I am trying to adjust the position and rotation of a sprite based on that of a b2body in box2d.
After I have created the body im setting the userData property to that of my body object that holds the sprite and position etc. The problem is that in the tick method b->GetUserData never retrieves the object I put in there. Can you see anything wrong with the following?
Here is my add player method:
-(void) addPlayerShip
{
CCSpriteSheet *sheet = [CCSpriteSheet spriteSheetWithFile:@"PlayerShip.png" capacity:1];
//Get sprite sheet
CCSprite *sprite = [CCSprite spriteWithSpriteSheet:sheet rect:CGRectMake(0,0,64,64)];
[sheet addChild:sprite];
CGSize screenSize = [CCDirector sharedDirector].winSize;
sprite.position = ccp( screenSize.width/2, screenSize.height/2);
[self addChild:sheet];
// Define the dynamic body.
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(sprite.position.x/PTM_RATIO, sprite.position.y /PTM_RATIO);
bodyDef.angularVelocity=0;
b2Body *body = world->CreateBody(&bodyDef);
b2PolygonShape dynamicTriangle;
dynamicTriangle.m_vertexCount=3;
dynamicTriangle.m_vertices[0].Set(0,-1);
dynamicTriangle.m_vertices[1].Set(1,1);
dynamicTriangle.m_vertices[2].Set(-1,1);
// Define the dynamic body fixture.
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicTriangle;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.0f;
fixtureDef.restitution=0.0f;
b2Fixture *fixture = body->CreateFixture(&fixtureDef);
b2Vec2 *vector = new b2Vec2;
BodyObject *bodyObject = [[BodyObject alloc] initWithBody:body
andFixture:fixture
andVelocity:vector
andSprite:sprite];
bodyDef.userData = bodyObject;
}
and the tick method that is always returning null on b->GetUserData
-(void) tick: (ccTime) dt
{
int32 velocityIterations = 8;
int32 positionIterations = 1;
world->Step(dt, velocityIterations, positionIterations);
//Iterate over the bodies in the physics world
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL) {
//Synchronize the Sprites position and rotation with the corresponding body
GameObject *myObject = (GameObject*)b->GetUserData();
myObject.Sprite.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
myObject.Sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
and finally the bodyObject
#import "BodyObject.h"
@implementation BodyObject
@synthesize Body;
@synthesize Fixture;
-(id) initWithBody:(b2Body*) body
andFixture:(b2Fixture*) fixture
andVelocity:(b2Vec2*) velocity
andSprite:(CCSprite*) sprite
{
self = [super initWithSprite:(CCSprite*)sprite
andVelocity:(b2Vec2*)velocity];
self.Body=body;
self.Fixture=fixture;
return self;
}
@end
im new to objective c so if im doing anything majorly wrong please let me know!
EDIT: I have tried another bit of code here and i seem to be able to get a bit further.
if I set bodyDef.UserData = sprite;
just after the line
bodyDef.position.Set(sprite.position.x/PTM_RATIO, sprite.position.y /PTM_RATIO);
then GetUserData returns the sprite. if however I set the user data to the sprite at the end of the addPlayerShip method then it returnns null again. Is the sprite / body object being disposed of somewhere?