Box2d销毁集合中的所有对象
Box2d destroy all objects in a set
我使用的是cocos2d和box2d,我有多达5个b2body需要同时销毁。它们都被添加到一个集合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);
}
}
Obvlious船长在评论中的解决方案很明显,但并不正确。尸体应该被世界摧毁->DestroyBody()。它需要简单地遍历实体,并通过调用此方法销毁每个实体(never为b2Body、b2Fixture或b2Joint调用delete
)。没有办法一下子把它们全部摧毁。
您应该通过world->DestroyBody()销毁尸体,不要以任何其他方式处理它们。没有办法同时移除它们,但身体的移除必须在box2d世界步骤之外进行。这意味着,如果你在列表中迭代并销毁你想要的实体,那么下次box2d世界将更新时,这些实体看起来就像同时被处理了一样。
C++方面很少有可能导致未定义行为的问题。其中之一是在迭代容器时从容器中移除。一旦在任何容器上使用了擦除,该容器的迭代器就会失效。这是我建议的更少的代码:
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::集来存储b2Body指针。集合通常比任何无序容器(如向量)都慢。我还删除了if(rowBody->GetUserData()!=NULL)。当您将对象添加到toDestroy向量时,可以假设对象通过了删除条件。
当你在row4容器上迭代时,你也会从场景中移除精灵(我从代码中假设它是某种容器),但你永远不会清除它。在你删除了该容器中的所有元素后,这样做可能是明智的,从我所看到的情况来看,这是在这里发生的。您还尝试多次删除这些精灵,在for循环中使用"for(CCSprite*sprite4 in row4)"来迭代实体,因此,如果有多个实体通过了要删除的标准,您可以再次遍历row4以删除精灵。
我不知道你为什么要基于"if(rowBody->GetUserData()!=NULL)标准"删除实体,但这可能是你在游戏中需要的东西,这在提供的代码中并不明显。
- 保留计时器集合(对象与指针)的最佳方法
- 在具有自定义对象的集合中查找值
- 如何处理C 中对象的混合集合
- 如何创建异质对象的集合
- 如果对象尚未在集合中,则创建一个对象
- C++内存中的大型对象集合是否正常
- C++集合对象和 iStream 文件输入
- 只有Arduino的第一个对象在包含在另一个对象的集合/数组中时会丢失其数据属性值
- C 11按几个属性的自定义对象集合
- 位掩码:通过集合方法设置对象的不同状态
- 可以在C++中更改存储在集合中的对象的非关键部分.如何在java中进行类似操作
- 具有不同接口的对象的集合
- 集合中的不可变对象(C++ 和 Qt)
- C++维护子类对象的混合集合
- 无法将对象上的指针添加到集合
- 映射/集合迭代器不兼容-检查对象是否在映射中
- 在派生类中处理派生对象集合的最佳方法是什么?
- 设计模式-在C++中返回对象集合的函数
- 访问父类对象集合的成员的子类函数
- 在c++中,两个线程/对象在一个对象集合中可以安全地做什么?