I've looked around quite a bit and haven't been able to find a concise answer to this question. For my Cocos2D game I have integrated the Chipmunk physics engine. On initialization, I setup the boundaries of the 'playing field' by establishing a series of bodies and static shapes as follows:
- (void)initPlayingField {
// Physics parameters
CGSize fieldSize = _model.fieldSize;
CGFloat radius = 2.0;
CGFloat elasticity = 0.3;
CGFloat friction = 1.0;
// Bottom
CGPoint lowerLeft = ccp(0, 0);
CGPoint lowerRight = ccp(fieldSize.width, 0);
[self addStaticBodyToSpace:lowerLeft finish:lowerRight radius:radius elasticity:elasticity friction:friction];
// Left
CGPoint topLeft = ccp(0, fieldSize.height);
[self addStaticBodyToSpace:lowerLeft finish:topLeft radius:radius elasticity:elasticity friction:friction];
// Right
CGPoint topRight = ccp(fieldSize.width, fieldSize.height);
[self addStaticBodyToSpace:lowerRight finish:topRight radius:radius elasticity:elasticity friction:friction];
// Top
[self addStaticBodyToSpace:topLeft finish:topRight radius:radius elasticity:elasticity friction:friction];
}
This setup works, except for one thing-- the positions of the boundaries appear to be off by a significant amount of pixels to the right. After initializing a player, and sending him towards the boundary walls, it does not bounce off the edges of the screen (as I would expect by setting up the bounding box at 0,0), but rather some number of pixels (maybe 30-50) inwards from the edges of the screen. What gives?
I initially thought the issue came from where I was rendering the player sprite, but after running it through the debugger, everything looks good. Are there special protocols to follow when using chipmunk's positions to render sprites? Do I need to multiply everything by some sort of PIXELS_PER_METER? Would it matter if they are in a sprite sheet? A sprite batch node? Here is how I set the sprite position in my view:
Player *player = [[RootModel sharedModel] player];
self.playerSprite.position = player.position;
self.playerSprite.rotation = player.rotation;
And here is how I set the position in my Model:
- (void)update:(CGFloat)dt {
self.position = self.body->p;
self.rotation = self.body->a;
}
(Yes, I know it's redundant to store the position because chipmunk does that inherently.)
Also, bonus question for for those who finished reading the post. How might you move a body at a constant velocity in whatever direction it is facing, only allowing it to turn left or right at any given time, but never slow down?