嵌套循环,从向量中删除

时间:2021-03-21 20:25:22

标签: c++

我正在尝试制作简单的游戏,但遇到了小问题。所以我有 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)

没有发生,它只有一个敌人?这样做是错误的吗? 我需要使用指针和向量,因为它适用于我的项目。

2 个答案:

答案 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);

在擦除后正确设置迭代器,为下一次循环做准备。

相关问题