DoCollision函数是一个回调函数,它通过迭代碰撞列表来检查每一帧的碰撞。
void Collision::DoCollisions(Game *game){
for (ColliderList::const_iterator colliderAIt = colliders_.begin();
colliderAIt != colliders_.end();
colliderAIt++)
{
ColliderList::const_iterator colliderBIt = colliderAIt;
for (++colliderBIt; colliderBIt != colliders_.end(); ++colliderBIt)
{
Collider *colliderA = *colliderAIt;
Collider *colliderB = *colliderBIt;
if (CollisionTest(colliderA, colliderB))
{
game->DoCollision(colliderA->entity, colliderB->entity);
}
}
}
如果碰撞测试通过任何两个游戏实体,游戏实体(所有游戏对象的基类)类析构函数调用函数DestroyCollider,它从列表中删除相应的碰撞元素。
void Collision::DestroyCollider(Collider *collider){
colliders_.remove_if(std::bind1st((std::equal_to<Collider *>()), collider));
delete collider }
答案 0 :(得分:0)
您正在删除迭代器指向的列表元素。这使迭代器无效,这意味着您不再允许使用它。
列表或向量的典型删除循环如下所示:
for (auto iterator = list.begin(); iterator != list.end(); ) {
if (should_remove(iterator)) {
iterator = list.erase(iterator);
} else {
++iterator;
}
}
请注意,如果要删除元素,迭代器不递增,而是替换为erase
调用的结果。
您必须找到一种方法来重构代码以匹配此模式。这很复杂,因为你的条件在碰撞函数的深处,但是你可以做到这一点(顺便说一句,它的优势在于通过摆脱线性搜索使你的代码更有效率),或者你可以而不是立即删除元素,将它们收集在一个单独的列表中,然后在迭代完主列表后删除它们。
或者您可以将colliders_
转换为侵入式列表(例如来自Boost.Intrusive或手写)。侵入性列表非常适合像你这样的情况。