【问题标题】:Collision of two sprite lists - SFML 2.0两个精灵列表的冲突 - SFML 2.0
【发布时间】:2013-08-26 20:02:00
【问题描述】:

我正在用 SFML 2 制作一个简单的游戏,到目前为止一切顺利。我创建了两个 sf::Sprite 列表,一个用于敌人,一个用于激光。敌人在屏幕外随机生成,并且只要给出输入就会创建激光。我为两个列表创建了一个碰撞循环并执行了我的代码。没有编译时和运行时错误。激光与敌人的碰撞对前 3 到 4 个敌人效果很好,但之后就不会发生碰撞。什么可能导致这个问题?请帮助我。谢谢。这是我的代码。

std::list<sf::Sprite>::iterator enemyit = enemy.begin(), next;
std::list<sf::Sprite>::iterator greenlaserit = greenlaser.begin(), reload;
while(enemyit != enemy.end())
{
    next = enemyit;
    next++;
    while(greenlaserit != greenlaser.end())
    {
        reload = greenlaserit;
        reload++;
        if(enemyit->getGlobalBounds().intersects(greenlaserit->getGlobalBounds()))
        {
                enemy.erase(enemyit);
                greenlaser.erase(greenlaserit);
                ++erased;
        }
        greenlaserit = reload;
    }
    enemyit = next;
}

【问题讨论】:

    标签: c++ list sprite sfml


    【解决方案1】:

    您似乎在进行大量迭代器操作,这很可能是问题所在。

    如果您可以使用 c++11,我建议您查看 for each 循环 (http://www.cprogramming.com/c++11/c++11-ranged-for-loop.html),以使事情变得非常易于阅读和理解(因此更易于调试)。

    你可以这样做:

        std::list<sf::Sprite> enemies;
        std::list<sf::Sprite> lasers;
    
        for (sf::Sprite enemy: enemies) {
           for (sf::Sprite laser : lasers) {
              if (enemy.getGlobalBounds().intersects(laser.getGlobalBounds())) {
                enemies.remove(enemy);
                lasers.remove(laser);
              }
           }
        }
    

    编辑:否则,我发现的一种解决迭代器问题的方法是手动单步执行。我为每个位置绘制了两个带有单元格的矩形,并跟踪迭代器并逐步运行逻辑。在您的逻辑的每次迭代之前,写下您的预期结果。然后手动检查,看看你的结果是否符合你的期望。

    【讨论】:

    • 我没有使用 C++11。但是,我会尝试你的第二种方法。谢谢。
    • 是否有任何特殊原因通过创建第二个变量(下一个,重新加载)来循环列表,然后立即迭代它?在我看来,这总是会跳过列表中的第一个元素。
    • 那是为了确保迭代器没有到达 list::end()。当我不使用第二个变量时,它会崩溃。
    • 好的,我知道会发生什么。您正在立即增加您的迭代器。这本质上是一个“关闭一个”错误。如果你在循环的最后递增,你应该没问题。如果你在那里增加,那么评估的下一行是寻找列表末尾的条件,所以它会退出循环。
    猜你喜欢
    • 2013-05-31
    • 2014-02-16
    • 1970-01-01
    • 2019-03-10
    • 2013-02-25
    • 2017-05-19
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多