问题描述
"Assertion failed: (m_bodyCount < m_bodyCapacity), function Add, file libs/Box2D/Dynamics/b2Island.h, line 65."
这就是崩溃在控制台中留下的内容.
That is what it the crash leaves in the console.
[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);
我认为我在做正确的事情..
I think im doing the right stuff..
@property (nonatomic, assign) b2Body *body;
这就是我如何使它"成为一个属性
Here is how i "make it" a property
我不明白为什么它不起作用,body"是一个正确的指针,因为我可以从 body 的 UserData 中检索信息,比如在 body 的 creatin 中设置的标签,所以这不应该是一个问题.. 有人知道吗我的代码有什么问题?
I dont understand why it doesnt work, "body" is a proper pointer because I can retrieve infromation from the bodys UserData like tags that are set in the creatin of the body, so that shouldnt be a problem.. Do anyone know whats wrong with my code?
谢谢.
编辑于:
-(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());
}
}
}
这不是世界之外的一步吗?
Isnt this outside the world step?
编辑 2:
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?
}
}
不是在时间步之外吗?请在这里帮助我...
Is it not outside the timestep? Please help me here...
谢谢
推荐答案
您必须扫描联系人,将所有联系人存储在一个数组中,然后在检查完所有联系人后,您可以移除您的身体.
You must scan for contacts, store all contacts in an array, and then AFTER all contacts have been checked, you remove your bodies.
检查联系人:
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.
这篇关于当我尝试破坏 b2Body 时游戏崩溃,我该怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!