矢量迭代器在碰撞时不可递增

时间:2017-07-15 21:32:30

标签: c++

我正在尝试创建一个观看教程的pacman游戏。因此,当幽灵处于弱状态并且pacman与幽灵碰撞时,我得到错误Vector迭代器不可递增。有谁可以解决这个问题。提前致谢。

for (Ghost*ghost : m_ghosts)
{
    if (ghost->getCollisionBox().intersects(m_pcMan->getCollisionBox()))
    {
        if (ghost->isWeak())
        {
            m_ghosts.erase(std::find(m_ghosts.begin(), m_ghosts.end(),ghost));
            m_score += 100;
        }
        else                
            m_pcMan->die();
    }
}

2 个答案:

答案 0 :(得分:0)

注意:您使用了基于范围的for循环,但在 for循环中,您仍然使用std::find来查找迭代器当前元素,以便您删除,这是低效的。

您的问题源于这样一个事实:在删除迭代器指向的元素之后,所有迭代器和对该元素的引用变为无效。基于范围的for循环尝试最终递增调用未定义行为的无效迭代器。幸运的是,你的STL实现检查了迭代器,所以你得到了一些很好的错误信息。

有很多方法可以解决这个问题。虽然你可能想要考虑你的数据结构...游戏开发者有更高级的技巧来处理这类事情。尽管如此,这是一个技巧,将当前ghost与向量上的最后一个交换,然后弹出最后一个元素。

auto iter = m_ghosts.begin();
auto End = m_ghosts.end();
while(iter != End)
{
    if (iter->getCollisionBox().intersects(m_pcMan->getCollisionBox()))
    {
        if (iter->isWeak())
        {
            if(iter != std::prev(End)){ //We want to prevent `std::swap(x,x)`
                 std::iter_swap(iter, std::prev(End));
                 End = m_ghost.erase(std::prev(End));
            }
            else{
                 iter = End = m_ghost.erase(std::prev(End));
            }
            m_score += 100;
        }
        else{
            ++iter;
            m_pcMan->die();
        }
    }
}

答案 1 :(得分:0)

谢谢你的帮助。这对我有用:)

for (int i=0;i<m_ghosts.size();i++)
{
    Ghost* ghost = m_ghosts[i];

    if (ghost->getCollisionBox().intersects(m_pcMan->getCollisionBox()))
    {
        if (ghost->isWeak())
        {

            m_ghosts.erase(std::find(m_ghosts.begin(), m_ghosts.end(), ghost));

            m_score += 100;
        }
        else

            m_pcMan->die();
    }
}