Game crashes when I try to destroy a b2Body, what should I do?

╄→гoц情女王★ 提交于 2019-12-06 07:50:00

You must scan for contacts, store all contacts in an array, and then AFTER all contacts have been checked, you remove your bodies.

Checking for contacts:

std::vector<MyContact>::iterator pos;
for(pos = _contactListener->_contacts.begin(); 
    pos != _contactListener->_contacts.end(); ++pos) 
{
    MyContact contact = *pos;

    b2Body *bodyA = contact.fixtureA->GetBody();
    b2Body *bodyB = contact.fixtureB->GetBody();

    // Rocket explosion rect
    if(bodyA->GetUserData() == NULL)
    {
        NSLog(@"NULL collision detected. (BODY A)");

        hasDoneRocketCollisions = YES;

        CCSprite *sprite = (CCSprite*) bodyB->GetUserData();

        if(sprite.visible == NO) continue;

        if(sprite.tag >= 200 && sprite.tag < 300)
        {
            index = sprite.tag - 200;
            if([spriteTracker containsObject:sprite]) continue;
            [spriteTracker addObject:sprite];
            bodiesToKill[counter] = bodyB;
            [enemyChargerIsAlive replaceObjectAtIndex:(int)(sprite.tag-200) withObject:[NSNumber numberWithInt:0]];
            [ParticleController spawnExplosion:sprite.position inParent:currentDefaultNode];
        }
        else if(sprite.tag >= 300 && sprite.tag < 400)
        {
            index = sprite.tag - 300;
            if([spriteTracker containsObject:sprite]) continue;
            [spriteTracker addObject:sprite];
            bodiesToKill[counter] = bodyB;
            [enemyShooterIsAlive replaceObjectAtIndex:(int)(sprite.tag-300) withObject:[NSNumber numberWithInt:0]];
            [ParticleController spawnExplosion:sprite.position inParent:currentDefaultNode];
            counter++;
        }
    }
}

Later in your method after all contacts have been checked:

b2Body *dyingBody;

for(int i = 0; i < counter; i++)
{
    CCSprite *dyingSprite;
    dyingSprite = [spriteTracker objectAtIndex:i];
    dyingSprite.visible = NO;

    // Is player projectile
    if(dyingSprite.tag >= 100 && dyingSprite.tag < 200)
    {
        CCParticleSystemQuad *dyingParticle;
        dyingParticle  = [particlesToKill objectAtIndex:particleIndex];
        particleIndex++;
        [dyingParticle stopSystem];

        dyingBody = bodiesToKill[i];
        dyingBody->SetActive(false);

        [ParticleController spawnExplosion:dyingSprite.position inParent:currentDefaultNode];
        [AudioController playExplosion];

        dyingSprite.visible = NO;

        if([_player currentShotType] == 1)
        {
            rocketHitBody->SetTransform(b2Vec2(dyingSprite.position.x/PTM_RATIO, dyingSprite.position.y/PTM_RATIO), 0.0);
            rocketHitBody->SetActive(true);
        }
    }
}

Take note that these are just random chunks of code I have copy and pasted in. They are for example only and may only confuse you if you try to read them as exact instructions.

The point here is: You can not remove a body while it is being accessed by the step or contact listener. Finish using the contact listener and then remove your bodies.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!