我正在使用cocos2d和box2d,我有多达5个需要同时销毁的b2bbody。它们全部添加到集合std::set<b2Body*>row1RedArray;
并由row1RedArray.insert(spriteBody);
添加,我已经通过迭代删除了数组中的所有项目,但是当我删除它后触摸屏幕时我的程序崩溃了。我是否正确地摧毁了b2Bodies?
//if that array is empty, then remove all objects from this array (row4)
if ((row4BlueArray.count == 0) && (row4.count >> 0) && (row4Removed == NO)) {
std::set<b2Body *>::iterator pos04;
for(pos04 = row4RedArray.begin(); pos04 != row4RedArray.end(); ++pos04) {
b2Body *rowBody = *pos04;
if (rowBody->GetUserData() != NULL)
{
for (CCSprite* sprite4 in row4) {
[self removeChild:sprite4 cleanup:YES];
}
//Adding the b2Body to the toDelete Set and then removing it from the set of b2Bodies
toDestroy.insert(rowBody);
row4RedArray.erase(rowBody);
row4Removed = YES;
}
}
}
std::set<b2Body *>::iterator pos2;
for(pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2) {
b2Body *body = *pos2;
if (body->GetUserData() != NULL)
{
//Then removing the b2Body completely (this is all at the end of the tick method)
_world->DestroyBody(body);
}
}
答案 0 :(得分:1)
评论中的Obvlious队长很明显,但是不正确。身体应该被world-&gt; DestroyBody()破坏。它需要通过实体进行简单的迭代,并通过调用此方法来销毁每个(并且从不调用delete
用于b2Body,b2Fixture或b2Joint)。没有办法一下子将它们全部销毁。
答案 1 :(得分:0)
你应该通过world-&gt; DestroyBody()销毁尸体,不要以任何其他方式处置它们。没有办法同时删除它们,但是必须在box2d世界步骤之外完成对身体的移除。这意味着如果您遍历列表并销毁下一次更新box2d世界时所需的实体,那么它们看起来就像是同时处理了这些实体。
C ++方面几乎没有可能导致未定义行为的问题。其中之一是在迭代时从容器中移除。在任何容器上使用erase后,该容器的迭代器将变为无效。这更像是我建议的代码:
std::vector<b2Body *> toDestroy;
if ((row4BlueArray.count == 0) && (row4.count >> 0) && (row4Removed == NO))
{
for(std::set<b2Body *>::iterator pos04 = row4RedArray.begin(); pos04 != row4RedArray.end(); ++pos04)
{
b2Body *rowBody = *pos04;
if (rowBody->GetUserData() != NULL)
{
toDestroy.push_back(rowBody);
row4Removed = YES;
}
}
for (CCSprite* sprite4 in row4)
{
[self removeChild:sprite4 cleanup:YES];
}
}
for( std::set<b2Body *>::iterator pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2)
{
row4RedArray.erase( (*body) );
_world->DestroyBody( (*body) );
}
//I have put the toDestroy vector in as a local variable so this is not needed, but if you
//are having it as a member variable etc. you need to clear it before you are going to use
//it in next loop, otherwise it will try to delete the same elements a second time.
toDestroy.clear();
我不确定你为什么用std :: set来存储b2Body指针。集合通常比任何无序容器慢,例如我们的向量。我还从第二个for循环中删除了if(rowBody-&gt; GetUserData()!= NULL),当您将对象添加到toDestroy向量时进行检查,可以假设对象通过了删除标准
当迭代row4容器时,你也会从场景中删除精灵(我假设从代码中它是某种容器),但你永远不会清除它。删除该容器中的所有元素后,这样做可能是明智的,这可以从我所看到的情况发生。您还尝试多次删除这些精灵,在for循环内部使用“for(CCSprite * sprite4 in row4)”迭代主体,因此如果多于一个主体已通过要删除的条件,则再次遍历row4删除精灵。
我不确定你为什么要根据“if(rowBody-&gt; GetUserData()!= NULL)条件”移除尸体,但这可能是你在游戏中需要的东西,这一点并不明显从提供的代码。