首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当我尝试销毁b2Body时,游戏崩溃,我应该怎么做?

当我尝试销毁b2Body时,游戏崩溃,我应该怎么做?
EN

Stack Overflow用户
提问于 2011-06-23 01:14:15
回答 1查看 3.8K关注 0票数 2
代码语言:javascript
复制
"Assertion failed: (m_bodyCount < m_bodyCapacity), function Add, file libs/Box2D/Dynamics/b2Island.h, line 65." 

这就是崩溃在控制台中留下的东西。

代码语言:javascript
复制
[self removeChild:(CCSprite*)body->GetUserData() cleanup:YES];

body->SetTransform(b2Vec2(30, 30), 0); //moving the body out of the scene so it doesnt collide anymore!

 world->DestroyBody(body);

我想我在做正确的事情..

代码语言:javascript
复制
@property (nonatomic, assign) b2Body *body;

下面是我如何“使它”成为一个属性

我不明白为什么它不工作," body“是一个合适的指针,因为我可以从bodys的UserData中检索信息,就像在body的创建中设置的标签一样,所以这应该不是问题。有人知道我的代码出了什么问题吗?

谢谢。

编辑位置:

代码语言:javascript
复制
-(void) tick: (ccTime) dt //Main loop
{

if (ballFired) {
    Magnet *aMagnet = [magnetArray objectAtIndex:0];

    world->DestroyBody(aMagnet.body); //It crashes here!
}



int32 velocityIterations = 8;
int32 positionIterations = 1;

// Instruct the world to perform a single step of simulation. It is
// generally best to keep the time step and iterations fixed.
world->Step(dt, velocityIterations, positionIterations);


//Iterate over the bodies in the physics world
for (b = world->GetBodyList(); b; b = b->GetNext())
{
    if (b->GetUserData() != NULL) {
        //Synchronize the AtlasSprites position and rotation with the corresponding body
        CCSprite *myActor = (CCSprite*)b->GetUserData();
        myActor.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b>GetPosition().y * PTM_RATIO);
        myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
    }   
    }




}

这不是走出了世界的一步吗?

编辑2:

代码语言:javascript
复制
        ContactListener::ContactListener(){};

         void ContactListener::BeginContact(b2Contact* contact)
        {
        // Box2d objects that collided
       b2Fixture* fixtureA = contact->GetFixtureA();


       b2Fixture* fixtureB = contact->GetFixtureB();
       CCSprite* actorA = (CCSprite*) fixtureA->GetBody()->GetUserData();
       CCSprite* actorB = (CCSprite*)  fixtureB->GetBody()->GetUserData();



      if(actorA == nil || actorB == nil) return;

    b2WorldManifold* worldManifold = new b2WorldManifold();
    contact->GetWorldManifold(worldManifold);


      Kollisjon *kollisjon = [Kollisjon sharedKollisjon];

     if (actorA.tag == 1) {

    NSLog(@"OK1");

    kollisjon.kollidertBody = fixtureB->GetBody();

    kollisjon.world->DestroyBody(kollisjon.kollidertBody); //Isnt this ok?

    }

    else if (actorB.tag == 1) {

       NSLog(@"OK2");


       kollisjon.kollidertBody = fixtureA->GetBody();

       kollisjon.world->DestroyBody(kollisjon.kollidertBody); //Isnt this ok?

    } 


    }

它不是在时间步长之外吗?请帮帮我。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-23 18:06:25

您必须扫描联系人,将所有联系人存储在一个数组中,然后在检查完所有联系人后,移除您的身体。

检查联系人:

代码语言:javascript
复制
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++;
        }
    }
}

稍后在您的方法中,检查完所有联系人后:

代码语言:javascript
复制
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);
        }
    }
}

请注意,这些只是我复制和粘贴的随机代码块。例如,它们只是举例说明,如果您试图将它们作为确切的说明来阅读,则可能只会使您感到困惑。

这里的要点是:当一个实体正在被step或contact listener访问时,您不能将其移除。完成联系侦听器的使用,然后移除身体。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6443832

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档