这里有一些代码检查2个单位在相互攻击后是否被杀死,我传入向量中的位置但是当我删除一个时,向量的大小发生变化,因此第二个单位超出范围。如何同时删除这两个?
if ((MyHealth <= 0) && (EnemyHealth <= 0))
{
PlayerUnits.erase(PlayerUnits.begin() + MyUnit, PlayerUnits.begin() + EnemyUnit);
}
else if (MyHealth <= 0)
{
PlayerUnits.erase(PlayerUnits.begin() + MyUnit);
}
else if (EnemyHealth <= 0)
{
PlayerUnits.erase(PlayerUnits.begin() + EnemyUnit);
}
答案 0 :(得分:4)
不是自己编写删除逻辑,而是使用std::remove_if
中的algorithm
进行更好的管理。根据您是否具有支持C ++ 11的编译器,Predicate可以是lambda或命名函数。
答案 1 :(得分:0)
第一点:在第一个块中,调用erase(x, y)
执行的操作与您预期的不同 - 它会删除从索引x开始直到索引y之前的整个范围元素。例如,如果我们有向量[a,b,c,d,e,f,g],那么erase(2,5)将擦除索引2,3,4,所以我们最终得到[a,b, F,G]。我猜你想要删除两个元素,而不是整个范围。
第二点:正如DieterLücking指出的那样,首先简单地删除较高的索引元素,如下所示:
if (MyUnit > EnemyUnit) {
PlayerUnits.erase(PlayerUnits.begin() + MyUnit);
PlayerUnits.erase(PlayerUnits.begin() + EnemyUnit);
} else {
PlayerUnits.erase(PlayerUnits.begin() + EnemyUnit);
PlayerUnits.erase(PlayerUnits.begin() + MyUnit);
}
答案 2 :(得分:0)
我认为更好的方法是添加一个&#34; isDead&#34;条件到你的&#34;单位&#34;类:
void Unit::Update()
{
//other stuff
if(this->m_health <= 0) this->m_isDead = true;
}
然后在主循环中:
void Game::Update()
{
size_t size = PlayerUnits.size();
//iterate backwards, so there is no skipping
for(int i = size-1; i>= 0; i--)
{
PlayerUnits[i]->Update();
if(PlayerUnits[i]->isDead()) PlayerUnits.erase(PlayerUnits.begin() + i);
}
}
这至少是我个人的做法。