1
votes

I just recently started messing with cocos2d's Box2D integration, while most of the process has been simple and straight forward, I keep running into a EXC_BAD_ACCESS error when using a CCPhysicsSprite (CCSprite subclass that integrates a b2body with the sprite). The code I'm using is:

- (void)spawnBallAtPoint:(CGPoint)point
{
    count++;

    CCPhysicsSprite *sprite = [CCPhysicsSprite spriteWithFile:@"ball.png" rect:CGRectMake(0, 0, 52, 52)];
    sprite.position = point;
    [self addChild:sprite];

    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(point.x / PTM_RATIO, point.y / PTM_RATIO);
    bodyDef.userData = sprite;
    b2Body *body = world->CreateBody(&bodyDef);

    b2CircleShape circleShape;
    circleShape.m_radius = (26.0 / PTM_RATIO);

    b2FixtureDef fixtureDef;
    fixtureDef.shape = &circleShape;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.2f;
    fixtureDef.restitution = 0.8f;
    body->CreateFixture(&fixtureDef);

    sprite.b2Body = body;
}

This code triggers an EXC_BAD_ACCESS, I know it's the CCPhysicsSprite because changing CCPhysicsSprite to CCSprite throws zero errors:

- (void)spawnBallAtPoint:(CGPoint)point
{
    count++;

    CCSprite *sprite = [CCSprite spriteWithFile:@"ball.png" rect:CGRectMake(0, 0, 52, 52)];
    sprite.position = point;
    [self addChild:sprite];

    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(point.x / PTM_RATIO, point.y / PTM_RATIO);
    bodyDef.userData = sprite;
    b2Body *body = world->CreateBody(&bodyDef);

    b2CircleShape circleShape;
    circleShape.m_radius = (26.0 / PTM_RATIO);

    b2FixtureDef fixtureDef;
    fixtureDef.shape = &circleShape;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.2f;
    fixtureDef.restitution = 0.8f;
    body->CreateFixture(&fixtureDef);
}

I've been looking around and can't find a real answer (as all the sample code uses CCPhysicsSprite in this way without error). I'm sure I'm making a stupid mistake but I guess that's to be expected when learning something new :P

Thanks in advanced!

1
which line exactly gives bad access?Kreiri
The method inline float32 b2Body::GetAngle() const in b2body, specifically return m_sweep.a;user1241570
But it's only when b2body is used on a CCPhysicsSprite, otherwise b2body throws no errorsuser1241570
there are no calls of b2Body::GetAngle() in the code you posted.Kreiri
Look, code you posted doesn't show where the crash happens.Kreiri

1 Answers

2
votes

With CCPhysicsSprite you must set the body BEFORE you set the position of the sprite. I assume that this line is where the crash occurs:

sprite.position = point;

If you look at CCPhysicsSprite it overrides the position/setPosition to always use the values from the contained b2body object. So it really accesses its b2body property, which is nil at that point → Crash. Generally after creating a CCPhysicsSprite you want to set its .b2body as soon as possible - there might be more occasions where similar problems might occur just because you need to set the .b2body property first.

So, move sprite.position = point; below sprite.b2Body = body;.