Need help in understanding the positions of sprite in cocos2d? - iphone

I am new in cocos2d i have created a simple example
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCSprite *player = [CCSprite spriteWithFile:#"Player.jpg"
rect:CGRectMake(0, 0, 27, 40)];
player.position = ccp(player.contentSize.width/2, winSize.height/2);
[self addChild:player];
but I am not clear about the position of sprite how to manager it

Your code will create a sprite and position it within the parent node so that its lower-left corner is at ccp(player.contentSize.width/2, winSize.height/2).
If you wonder why your sprite is not centered respect to the coordinate you provide, the answer is that it is the lower-left corner which is positioned, not the sprite center.
You can tweak this behavior by defining the anchorPoint property of the sprite, like this:
player.anchorPoint = ccp(0.5,0.5);
player.position = ...
EDIT:
You can think of the anchor point as the "center of gravity" of the sprite: the texture is centered around it, any scaling or other kind of transformation will be relative to it.
If the anchor point is set at (0,0), then it coincides with the lower-left corner (default); if it is (0.5, 0.5) then it is exactly in the middle of the sprite (50% width, 50% height). Its coordinates are not point, but the relative displacement within the sprite; the coordinates can go from 0.0 to 1.0.

Related

bodyWithEdgeLoopFromRect doesn't match SKSpriteNode

I have in my scene playing board (for Tetris) - smaller then scene (750x510px). I need to frame it with bodyWithEdgeLoopFromRect. Here is a code :
SKSpriteNode *herniPlocha = [[SKSpriteNode alloc]initWithImageNamed:#"Plocha"];
herniPlocha.anchorPoint = CGPointMake(0, 0);
herniPlocha.position = CGPointMake(10, self.size.height-450);
herniPlocha.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:herniPlocha.frame];
[self addChild:herniPlocha];
but when I try to put block inside this board, the physicsBody doesn't match my board, it is about 40px moved to the right and up. Can you help me solve this problem, please?
Don't change the anchorPoint. The anchorPoint shifts the texture relative to the node's position and does nothing else. It certainly does not change where the physics shape is relative to the node.

Scale SKShapeNode from center?

I have a SKShapeNode, and a label under one generic SKNode. If I try to scale that node, its position changes for no reason!. If I try to scale only the nodes it contains under it, it scales properly but not from the center, so it grows out to the up and right.
What am I doing wrong?
First before scale
After scale
Notice its position moves up. Can't figure out why, does it even if I do it as an action or not. Also, the position is not changing based on log, but it appears the frame got bigger (though that is expected)
Steps to recreate issue:
set height and width
#h = 50
#w = 256
create rect with height and width
CGRectMake(0, 0, #w, #h)
get path for rect
UIBezierPath.bezierPathWithRect(rect).CGPath
create skshape node with path, set position
antialiased: false,
lineWidth: 1.0,
strokeColor: SKColor.blackColor,
fillColor: SKColor.whiteColor
Create sklabel, vertical center alignment, set position
create generic SKNode, no properties, add skshapenode and sklabel to it as children
Scale the generic SKNode.
I had a similar problem: I created an SKShapeNode.ellipseInRect which look perfectly fine when I didn't need to scale it. Yet as soon as I tried to scale it down to fit the text it was behind, it would randomly shrink towards the bottom left of the screen!
I did a little debugging, and the number that surprised me was that the position was set to (0, 0) even though the ellipse was in the top left corner of the screen! I then realized that by initializing with a rect the "anchor point" (even though SKShapeNodes don't technically have them) was at (0, 0) too. This behavior would explain my shrinking towards that point and your growing away from that point.
What solved this problem for me was instead of putting my position in the rect, set the position afterwards. Then it scaled around my node's center-point and not the screen origin. Hope that helps!
Try this
SKLabelNode *labNode = [SKLabelNode labelNodeWithFontNamed:#"Arial"];
labNode.fontSize = 12.0f;
labNode.fontColor = [SKColor blackColor];
labNode.text = #"SMASH";
SKSpriteNode *topWithText = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(100, 30)];
topWithText.position = CGPointMake(100, 110);
[topWithText addChild:labNode];
SKSpriteNode *bottom = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 10)];
bottom.position = CGPointMake(100, 100);
[self addChild:topWithText];
[self addChild:bottom];
[topWithText runAction:[SKAction sequence:#[
[SKAction waitForDuration:3.0],
[SKAction scaleBy:3.0 duration:3]
]]];
With the SKShapeNode, this is impossible.
I solved it by adding a move Action to center the node manually.
You need to apply this to the y and x coordinates

how to visible the portion sprite

I want to visible portion of sprite while on touching screen.
when i touch on the spriteModelHair touch location should be visibel and rest of the part of the sprite should be not visible.]
spriteModelHair = [CCSprite spriteWithFile:#"hair001.png" rect:CGRectMake(0, 0, 450, 612)];
spriteModelHair.position = ccp(winSize.width/2, winSize.height/2+25);
spriteModelHair.visibel = No;
[self addChild:spriteModelHair z:2];
Get the RGBA data of each pixel and each pixel's position on the screen. If the location of your touch is the same as one of the pixel's locations (or in a predefined area around the touch) change that pixel's alpha to 0 or something.

Cocos2d, Weird position offset when using CCParallaxNode

I'm using cocos2d for iOS. Not sure if I'm doing something wrong here or if CCParallaxNode does something strange that I just don't understand.
I'm trying to create a few layers of parallax scrolling in the background of my game, at the moment I just have one layer added to the parallax node till I can figure out what's going wrong. When the game loads the layer it's always offset down and left by about 30% of the image size. I've uploaded an image demonstrating the difference in position here http://oi42.tinypic.com/29dz1av.jpg.
Here is my code:
background = [CCParallaxNode node];
background.anchorPoint = ccp(0,0);
background.position = ccp(0,0);
[self addChild: background];
background_image = [CCSprite spriteWithFile: #"layer01.png"
rect: CGRectMake(0, 0, 100, 100)];
background_image.anchorPoint = ccp(0,0);
background_image.position = ccp(0,0);
[background addChild: background_image z:0 parallaxRatio: ccp(0,0) positionOffset:ccp(0,0)];
The cocos2d icon is attached to the same layer as the parallax node and it's position and anchor point are set to 0,0 so the bottom left of the icon should be in the same location as the bottom left of the blue background image.
I have tested this using a basic sprite in place of the parallax node and everything lines up as it should so it's not the image itself.
Any help with this would be appreciated.
First, I don't suggest you to set parallax node & its children's anchor point & position directly because it will cause some unexpected results. You should add the parallax node to a layer as its child, and set the layer's anchor point & position to place your parallax.
Second, CCParallaxNode also provides a positionOffset that you can place your picture in parallax at first. This can help if you want to align several layers of pictures' view center.
So I think you should do something like this(Since I'm using cocos2d-x, I'm not sure its right with obj-C):
layer = [[CCLayer alloc]init];
background = [CCParallaxNode node];
[layer addChild: background];
[self addChild: layer];
Then you just have to add the picture sprite in background, and set layer's position & anchor point.
Hope it can help.
Make sure the background image size is 480x320.
Why did you write CGRectMake(0, 0, 100, 100) ? Why 100 and 100 ? You're limiting your 'CGRect', that's probably wrong..

Cocos2D Rotation and Anchor point

The problem that I have is that when ever I change the anchor point sprite automatically rotates with respect to the current anchor point. And I don't want that to happen.
The steps that I followed
create a sprite with anchor point (0.5, 0.5)
Changed the anchor point to (0,1)
Rotated the sprite to 90 degree. (Using CCRotateBy. Sprite rotated correctly)
Changed the anchor point to (0.5, 0.5) (Every thing is fine till now. And this is the position that I need to keep). Now sprite.rotation is 90.
I changed the anchor point to (1,0) (Sprite automatically rotates to 90 degree with respect to the given anchor point - I need to stop this behavior)
Is there any way to reset the rotation of sprite to 0, without actually rotating the texture(ie., to keep the texture in its current form - actual texture rotated to 90 degrees) and changing anchor point or position along with step 4, so that I can continue from point 5.
As Lukman says, the anchor point will always affect rotation, since your goal is to be able to specify the sprite position with a different anchor point from the rotation I would suggest making an empty CCNode as a parent of your sprite.
This way, you can set the position on sprite to be relative to this parent node to compensate for your anchor point change and then keep the anchor point for rotation on the sprite but use the parent node for position.
anchorPoint affects both position and rotation. You cannot stop it from affecting either one of them.
But from reading your question, since you want to prevent anchorPoint from affecting the rotation, I'm assuming here that the reason you change the anchorPoint is for the position, for example you are setting it to be ccp(1, 0) because you want to the sprite bottom right corner, instead of the sprite center, to be where you set the position is.
My suggestion is: don't change the anchorPoint at all, but change the way you set the sprite position. You can use this small function to adjust the position:
CGPoint adjustedPosition(const CGPoint position, const CGPoint anchor, const CGSize size) {
return CGPointMake(position.x - (anchor.x - 0.5) * size.width, position.y - (anchor.y - 0.5) * size.height);
}
Now, assuming you wanted to use anchorPoint of (1,0) when doing the positioning, instead of sprite.position = ccp(200, 300), you just need to do:
sprite.position = adjustedPosition(ccp(200, 300), ccp(1.0, 0.0), sprite.contentSize);
If you want, I'll post the logic behind the math later. Otherwise, I hope this will help.
Maybe it will help you to install an anchor for the sprites in the correct coordinate.
void SetAnchorPosition(CCSprite * sprite, const CCPoint & point)
{
static CCSize winSize = CCDirector::sharedDirector()->getWinSize();
double x = ((double)1/(double)winSize.width)*(double)point.x;
double y = ((double)1/(double)winSize.height)*(double)point.y;
sprite->setAnchorPoint(ccp(x,y));
sprite->setPosition(point);
}
You can add a line in the touchEnded method as a forceful alternative:
-(void)touchEnded:(UITouch *)touch withEvent:(UIEvent *)event{
_yourSprite.rotation = 90;
}