我正在尝试制作简单的游戏,但遇到了小问题。所以我有 2 个指针向量。 一种用于子弹,一种用于敌方单位。 首先,我尝试遍历我所有的子弹,然后在第二个循环中遍历我的敌人,当我发现碰撞时,我会擦除敌方单位和子弹,但是擦除子弹会使我的游戏崩溃,所以我发现我不应该从向量中擦除它仍然在第一个循环中迭代。
我的第二个想法是这样的:
std::vector<Bullet*>::iterator remove = std::remove_if(bullets.begin(), bullets.end(),
[&](Bullet* x)
{
for (std::vector<EnemyUnit*>::iterator it = enemyUnits.begin(); it != enemyUnits.end(); ++it)
{
if (x->collision->CheckCollision((*it)->collision))
{
enemyUnits.erase(it);
return true;
}
else
{
return false;
}
}
});
bullets.erase(remove, bullets.end());
所以它似乎在某种程度上起作用,但我的子弹一次只能与一个敌人碰撞,而且似乎没有检查所有敌人。例如我射了 5 颗子弹,首先它们只能与一个敌人碰撞,一颗子弹杀死敌人后,其他子弹将能够与第二个敌人碰撞,依此类推。好像
for (std::vector<EnemyUnit*>::iterator it = enemyUnits.begin(); it != enemyUnits.end(); ++it)
没有发生,它只有一个敌人?这样做是错误的吗? 我需要使用指针和向量,因为它适用于我的项目。
答案 0 :(得分:3)
std::remove_if
的谓词在第一次检查后返回,无论如何。
为了解决这个问题,谓词可以在碰撞时返回,或者在没有碰撞时(循环之后)返回,例如
for (auto it = enemyUnits.begin(); it != enemyUnits.end(); ++it)
{
if (x->collision->CheckCollision((*it)->collision))
{
enemyUnits.erase(it);
return true;
}
}
return false;
这样,如果检测到碰撞,它会提前退出并返回true。 如果没有与任何敌人发生碰撞,它会在循环后停止并返回false。
答案 1 :(得分:1)
建议删除 return 语句的答案是正确的。 return 语句提前退出内部循环,但这不是唯一的问题。删除这些返回值将揭示下一个问题。您需要:
it = enemyUnits.erase(it);
在擦除后正确设置迭代器,为下一次循环做准备。