0

我已经查看了关于同一消息的 10 个左右的答案,但还没有找到我的问题。

在 Level 类的 level.h 中:

std::vector<Bomb> m_bombs;

在 level.cpp 中:

添加炸弹:

Bomb bomb;
bomb.owner = player;
bomb.power = power;
bomb.x = pos.x;
bomb.y = pos.y;
bomb.timer = 3.0f;
m_bombs.push_back(bomb);

检查炸弹(每帧):

void Level::updateBombs(float dt)
{
    for(int i = 0; i < m_bombs.size(); i++)
    {
        m_bombs[i].timer -= dt;
        if(m_bombs[i].timer <= 0)
            m_bombs.erase(m_bombs.begin() + i);
    }
}

我 100% 确定程序在调用擦除函数的那一行崩溃。我能够从向量中输出信息,这使得这种方式更加混乱。炸弹在向量中是正确的。如果我执行 m_bombs.remove_last() 它会删除向量中的最后一个元素。似乎只是有擦除和开始()的问题。

4

4 回答 4

1

您可以使用erase-remove-idiom来修复您的代码。

m_bombs.erase(std::remove_if(m_bombs.begin(), m_bombs.end(), 
                             [](const Bomb& b){ return b.timer < 0.0f;}), 
                             m_bombs.end());

更好的将updateBombs函数拆分为两个函数:

updateBombs() does bomb timer update only
removeBombs() removes bombs which expired
于 2013-11-02T23:47:06.447 回答
1

也许您可以尝试向后擦除向量,例如,如果要擦除炸弹索引 3 和 5,则删除索引为 5 和 3 的向量,因为如果您从0到顺序N-1擦除,则在擦除索引 3 时,索引5 将变为索引 4,这可能导致在到达循环的最后一步时越界。

尝试这个:

int pivot = 0
void Level::updateBombs(float dt)
{
    for(int i = 0; i < m_bombs.size(); i++)
    {
        m_bombs[i].timer -= dt;
        if(m_bombs[i].timer <= 0)
        {
            m_bombs.erase(m_bombs.begin() + i - pivot);
            pivot++;
        }

    }
}
于 2013-11-02T23:37:35.433 回答
0

我将替换为您自己m_bombs.size()int变量,您在移除炸弹后会减少该变量。我个人遇到过问题.size()。它应该返回向量中的元素数,但我有一个空向量并.size()返回大于零的数字。也许尝试这将有助于缩小您的问题。

于 2014-10-10T16:24:26.050 回答
0

我在清除或创建向量时遇到了类似的问题。出现问题是因为在运行时使用了 2 个不同版本的 dll。调用 Open CV 函数时发生了清除和创建,这些函数似乎使用与我的 Visual Studio 不同的运行时库。更改视觉工作室终于解决了这个问题(我在更改视觉工作室之前尝试了很多旧的 OpenCV 构建,但无济于事)。VS 2008 和 2013 不起作用,VS2010 起作用。

于 2014-07-06T13:25:34.393 回答