I need to place a sprite at the bottom of the screen independently from resolution using cocos2d for iPhone, so that if a sprite is at the bottom on iPhone 5/5s, it will be at the bottom even on iPhone 4/4s.
The following code works on iPhone5/5s resolution, but not on the previous iPhone model:
ground1 = [CCSprite spriteWithImageNamed:#"ground1.png"];
ground1.position = ccp(self.contentSize.width/2,self.contentSize.height/2-259);
[self addChild:ground1];
What can I do?
CGSize size = [[CCDirector sharedDirector]viewSize];
ground1 = [CCSprite spriteWithImageNamed:#"ground1.png"];
ground1.position = ccp(size.width/2,[ground1 boundingBox].size.height/2);
[self addChild:ground1];
First of all you need the size of the view. In Cocos2D you get that value calling the CCDirector and getting its viewSize.
After that, you create the sprite as you did.
Now the important step is to position the sprite. Now you have your viewSize stored in 'size' so you get the X value by doing: size.width/2.
Now you have your sprite centered on X. Now let's position it over Y.
You want your sprite to be at the bottom. So you need to calculate the point as I show you in this picture:
So the Y value is exactly height/2 of the sprite's size. We can get this value by calling the method:[sprite boundingBox] that returns the size of the sprite.
In conclusion, we have our sprite centered on X (size.width/2) and at the bottom ([sprite boundingBox].size.height/2)
Related
I placed a circle image in the middle of the screen and had the image move to the left. But it eventually stops so half of it still shows on the screen. I don't want to remove the circle, just move it a little bit further to the left so less of the circle shows. I tried setting the moveTo value to negative but it had the same effect as the value being 0. Any ideas?
SKSpriteNode *circle = [self makeSprite:#"circle" x:.5 y:.5];
circle.position = CGPointMake(self.size.width*.5, self.size.height*.5);
[circle [SKAction moveToX:0.0 duration:3]];
I am creating a simple Sprite Kit game however when i am adding the PhysicsBody to one of my sprites it seems to be going in the wrong position. i know that it is in the wrong position as i have have set
skView.showsPhysics = YES;
and it is showing up in the wrong position.
The Square in the bottom corner is the physics body for the first semicircle. I am using a square at the moment just for testing purposes.
My app includes view following and follows my main sprite when it moves. I implemented this by following apples documentation and creating a 'myworld' node and creating all other nodes from that node.
myWorld = [SKNode node];
[self addChild:myWorld];
semicircle = [SKSpriteNode spriteNodeWithImageNamed:#"SEMICRICLE.png"];
semicircle.size = CGSizeMake(semicircle.frame.size.width/10, semicircle.frame.size.height/10);
semicircle.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:semicircle.frame.size];
semicircle.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
semicircle.physicsBody.dynamic = YES;
semicircle.physicsBody.collisionBitMask = 0;
semicircle.name = #"semicircle";
[myWorld addChild:semicircle];
To centre on the node I call these methods
- (void)didSimulatePhysics
{
[self centerOnNode: [self childNodeWithName: #"//mainball"]];
}
- (void) centerOnNode: (SKNode *) node
{
CGPoint cameraPositionInScene = [node.scene convertPoint:node.position fromNode:node.parent];
node.parent.position = CGPointMake(node.parent.position.x - cameraPositionInScene.x, node.parent.position.y - cameraPositionInScene.y);
}
I don't know if the my world thing makes any difference to the SkPhysics body...
SKPhysicsBody starts at coordinates 0,0 which is at the bottom left hand corner. If you make the area smaller, as you did by width/10 and height/10, you decrease the size but from the bottom left.
I think what you are looking for is bodyWithRectangleOfSize:center: which allows you to manually set the center from which you base your physics body area on.
Update:
Based on what I understand, your smallest semi circle pic size is the same as the screen size. I would suggest you modify the image size to something like the example I have. You can then set the sprite's position as required and set the physics body to the half of the image containing your semi circle.
Your centerOnNode call should be put in the didEvaluateActions function instead of the didSimulatePhysics function. This is because you need to move the world before the physics are drawn so that they stay in sync. Similar question found here: https://stackoverflow.com/a/24804793/5062806
I'm learning how to use SpriteKit.
Question:
As practice, I'm trying to make a mock of pong. I want the ball's initial position to be in the center, and for the life of me, I cannot set its position to be in the center. It always ends up in the bottom left hand corner of the screen and I have no clue why. I've set the scene's scale mode equal to SKSceneScaleModeAspectFill, and I've tried each of the following lines of code in separate trials in order to get set its position to the center, but it has always remained in that bottom left hand corner.
//Attempt #1
self.ball.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)); //find the middle of each axis and put them together in one coordinate
//Attempt #2
self.ball.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2); //find the width and height of the screen, divide each by 2 and assign them to an (x,y) coordinate together
//Attempt #3
self.ball.position = CGPointMake(160, 284) //Half the width and half the height
//Attempt #4
self.ball.position = CGPointMake(320, 568) //The width and the height (I'm desperately guessing at this point)
//Attempt #5
self.ball.position = CGPointMake(0,0) //I figured I'd give it a go
This ball is an SKSpriteNode by the way I didn't make a Ball subclass of SKSpriteNode or anything. The strange thing about this, is I've been able to bring up other sprites on the screen such as paddles and scores exactly where I want them. It's just this ball that isn't cooperating. What am I doing wrong? How can I prevent this issue in the future?
If you want to make ball's initial position to centre, then write below code:
[self.ball setPosition:CGPointMake(self.size.width/2, self.size.height/2)];
I'm using above code in my code and it is giving me perfect result.
Let me know it is working or not?
Happy Coding!
So here's the gist of what I'm trying to do here.
I have an array of foreground sprites that I scroll forever as the player moves along. What I would like to do, is when the player starts passing a certain point on the Y axis, scale down those foreground sprites while still moving them.
I'd like to be able to scale the sprites from their bottom left hand corners when the player is going up, and I've got this working without any problems.
The real problem is that I'd also like to scale the sprites from their bottom right hand corners when the player is coming down. Now I thought that I could do this by setting each sprite's anchor point to 1,0 before scaling it, but that doesn't seem to work. The sprites still scale from their bottom left hand corners.
What am I missing here?
// do logic to identify the scale factor we want
for (CCSprite *sprite in foreground_sprites)
{
CGPoint old_anchor = sprite.anchorPoint;
[sprite setAnchorPoint:ccp(1,0)];
[sprite setScale:scale_factor];
[sprite setAnchorPoint:old_anchor];
}
Have you tried messing with this property?
ignoreAnchorPointForPosition(false);
I'm using cocos2d-x, there should be something similar to that
If I understand correctly, you want to scale from the bottom left while the player's Y position increases but scale using the bottom right while they are descending?
Well you can't just change the anchor point alone. The anchor point and position go hand in hand to position the sprite on the screen. So if you positioned the sprite on to the screen using an anchor point of (0,0) then if you want to switch it's anchor point to (1,0) while keeping it in the same location on the screen, you'll need to update the position.
CCSprite* sprite = ...;
sprite.anchorPoint = CGPointZero;
sprite.position = CGPointZero;
...
sprite.anchorPoint = CGPointMake(1.0f, 0.0f);
sprite.position = CGPointMake(sprite.position.x + (sprite.contentSize.width * sprite.scaleX * sprite.anchorPoint.x),
sprite.position.y + (sprite.contentSize.height * sprite.scaleY * sprite.anchorPoint.y));
Hopefully I understood your problem correctly and was able to help.
I have a sprite :
ombreoeuf1 = [CCSprite spriteWithFile:#"mangeurcentremieu3_03.png" ];
ombreoeuf1.position = ccp(240,160);
[self addChild:ombreoeuf1];
And I would like to rotate it constantly around an anchor point. How can I do it?
You can first set anchor point by setting the property anchorPoint, for example:
[ombreoeuf1 setAnchorPoint:ccp(0,0)]
and then set rotation (in degrees) by setting another property rotation:
[ombreoeuf1 setRotation:90]
anchorPoint and rotation are both properties of CCNode class, which is the parent of CCSprite.
Update
According to your comments, it seems that what you want is a rotating sprite which never stops? Here is an example which let the sprite rotate 10 degrees per 0.1 seconds:
[sprite runAction:[CCRepeatForever actionWithAction:[CCRotateBy actionWithDuration:0.1 angle:10]]];
All transformations of CCNode subclasses are done relatively to the anchor point. During all of your transformations the anchorPoint will have the same position. For example, if you will place sprite with anchorPoint (0.f, 0.f) to the position (0.f, 0.f), the left-bottom corner of the screen, then set it's scale, for example, to 5.f, after transforming it will stay at the left-bottom corner, just wil become larger. So all rotations automatically will be done relatively to the anchor point.
Just one more thing. CCSprite has anchorPoint (0.5f, 0.5f) by default and some content size, so you just have to set it to another to see changes in transformations. If you want to do it with CCNode, you have to set it's relativeToAnchorPoint property to YES and set contentSize manually.
You can use CCRepeatForever action for this. For example,
id rotateAction = [CCRepeatForever actionWithAction:[CCRotateBy actionWithDuration: yourDuration
angle: anyAngleForGivenTime]];