当我逐步运行调试器运行程序时,我没有收到此错误。但是,当我实际运行该程序时,我每次都会得到它。它在这个循环中打破了:
auto ships = sprites.begin();
auto misscnt = sprites.begin(); misscnt++; misscnt++; //missiles start at the 3rd item on list every time.
while (misscnt != sprites.end()) //Missile Collision
{
ships = sprites.begin();
ships++;
if (dynamic_cast<Missile*>(*misscnt)->Collides((*ships)->GetLeft(), (*ships)->GetTop(), (*ships)->GetWidth(), (*ships)->GetHeight()) && dynamic_cast<Missile*>(*misscnt)->GetID() == "PlayerMiss")
{
ships--;
(*ships)->AddToScore(10);
sys->playSound(FMOD_CHANNEL_FREE, eHit, false, 0);
while (true)
{
ships = sprites.begin();
ships++;
int x, y;
x = rand() % Console::WindowWidth;
y = rand() & Console::WindowHeight;
if ((*ships)->GoodSpot(x, y, *(*--ships)))
{
ships++;
(*ships)->SetLeft(x);
(*ships)->SetTop(y);
break;
}
}
delete (*misscnt);
sprites.erase(misscnt);
ships = sprites.begin();
}
else if (dynamic_cast<Missile*>((*misscnt))->Collides((*ships)->GetLeft(), (*ships)->GetTop(), (*ships)->GetWidth(), (*ships)->GetHeight()) && dynamic_cast<Missile*>((*misscnt))->GetID() == "EnemyMiss")
{
(*ships)->SetLives((*ships)->GetLives() - 1);
if ((*ships)->GetLives() > 1)
sys->playSound(FMOD_CHANNEL_FREE, pHit, false, 0);
if ((*ships)->GetLives() == 1)
sys->playSound(FMOD_CHANNEL_FREE, LastLife, false, 0);
if ((*ships)->GetLives() == 0)
{
bgmusic->setPaused(true);
sys->playSound(FMOD_CHANNEL_FREE, pDie, false, 0);
Sleep(4000);
play = false;
break;
}
while (true)
{
int x, y;
x = rand() % Console::WindowWidth;
y = rand() & Console::WindowHeight;
if ((*ships)->GoodSpot(x, y, *(*++ships)))
{
ships--;
(*ships)->SetLeft(x);
(*ships)->SetTop(y);
break;
}
}
delete (*misscnt);
sprites.erase(misscnt);
ships = sprites.begin();
}
else
misscnt++;
}
程序永远不会进入if或else if物体,所以每当发射导弹时它都被添加到列表中。在环路中,如果导弹在任何情况下不发生碰撞,它应该增加误差并检查下一枚导弹(如果有的话)。
编辑:错误说
列出不兼容的迭代器 File :: F:\ VS2013 \ VC \ include \ list 行:289
我认为该行正在讨论文件“list”。
当它破坏时,VS指向while循环条件,表示它是下一行要执行的。
答案 0 :(得分:2)
while()循环中有很多事情发生。它应该被重构,以便它无法通过无效迭代器获得这些问题。下面的代码尚未编译,但它将用于试图说明我的观点:
#include <algorithm>
bool IsAlive(ships& s)
{ return s.IsActive(); }
void DeleteMe(ship& s)
{ delete &s; }
//...
auto ships = sprites.begin();
auto misscnt = sprites.begin();
std::advance(misscnt, 2);
while (misscnt != sprites.end()) //Missile Collision
{
// do the collision handling
bool hasCollided = DoCollisionHandling( misscnt );
if ( hasCollided )
misscnt->setActive(false);
++misscnt;
}
// remove the inactive ones
list<sprites>::iterator pt = std::partition(sprites.begin(), sprites.end(), IsAlive);
std::for_each(pt, sprites.end(), DeleteMe);
std::erase(pt, sprites.end());
根据您发布的内容,上面的代码应该是您尝试实现的内容的概要。请注意,唯一要做的就是调用DoCollisionHandling(它应该是一个虚函数,为每种类型重写),并返回是否发生了碰撞。 DoCollisionHandling()应该不删除项目。
然后在while循环之外,我们将死的那些分区到分区的右边,这样我们就可以删除它们(或者稍后我们想做什么)。 &#34; pt&#34;是迭代器,它是活着的那些与死亡之间的分界线。
可能有更好的方法可以做到这一点,但我不推荐的一种方法是尝试在这样的循环中过于可爱,在这种情况下,你要删除被迭代的项目。除非是玩具或简单的循环,否则这样的事情似乎总是会引起麻烦。最好只标记项目,然后再处理它们。