2
votes

I have a contact listener to detect collisions between a bullet and an asteroid. Inside the beginContact function i check for the sprite types and fire a block from within this function.

The block is set by the scene class when it is allocated, before the contact listener is assigned to the box2dworld. The bullets and asteroids both get box2d bodies as well as sprites.

The problem is that i can access the sprites and do whatever i want with them (run actions, stop actions etc.).

However, as soon as i call the removeChild function on the sprite, I get an EXC_BAD_ACCESS in the b2Contact::Update on listener->BeginContact(this).

Can anyone point me in the right direction?

My tick function:

//Physics simulation
_world->Step(dt, 10, 10);
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
    if (b->GetUserData() != NULL) {
        CCSprite *sprite = (CCSprite *)b->GetUserData();

        b2Vec2 b2Position = b2Vec2(sprite.position.x/PTM_RATIO,
                                   sprite.position.y/PTM_RATIO);
        float32 b2Angle = -1 * CC_DEGREES_TO_RADIANS(sprite.rotation);

        b->SetTransform(b2Position, b2Angle);
    }
}

for(CCSprite *sprite in spritesToDelete) {
    [self removeSprite:sprite];
    [spritesToDelete removeObject:sprite];
    sprite = nil;
}

My contact listener callback block:

 contactListener->contactBlock = ^(CCSprite *A, CCSprite *B) {

        NSLog(@"A: %@", [A class]);
        NSLog(@"B: %@", [B class]);
        CCSprite *bullet = nil , *asteroid = nil;
        if ([(NSString *)A.userData isEqualToString:@"asteroid"] && [(NSString *)B.userData isEqualToString:@"bullet"])
        {
            asteroid = A;
            bullet = B;
        } else if ([(NSString *)B.userData isEqualToString:@"asteroid"] && [(NSString *)A.userData isEqualToString:@"bullet"])
        {
            asteroid = B;
            bullet = A;
        }

        if (asteroid != nil && bullet != nil) {
            NSLog(@"Asteroid Hit!");
            [asteroid stopAllActions];
            [bullet stopAllActions];
            //If I keep the line below uncommented, I get the error. Adding actions and stuff does not make an issue, only removal of sprite is when I get the error.
            [spritesToDelete addObject:bullet];
        }

    };
1

1 Answers

0
votes

I guess you put a pointer to your sprite in b2UserData of b2Body or b2Fixure in order to retrieve when collision happens. When you delete the sprite, this pointer will point to a deleted instance and thus you receive EXC_BAD_ACCESS.

You should nullify the pointer to eliminate the problem