以下代码检查球是否与砖重叠。如果发生重叠,则会从列表中突出显示并删除砖块。
当我只删除vector brickWall 中的最后一项时,我遇到了核心转储。 在评论 erase()行时,代码似乎运行良好 在论坛上查看类似问题之后,我相信我正在迭代并正确地删除向量中的项目,但我怀疑情况可能并非如此。
对此代码的任何建议都将非常感谢!
void Game::updateEntities()
{
ballMother.update();
for (std::vector<gdf::Entity>::iterator it = brickWall.begin(); it != brickWall.end(); ++it)
{
if (it->getRect().intersects(ballMother.getRect())) {
it->rect.setFillColor(sf::Color::Red);
it = brickWall.erase(it);
}
else {
it->rect.setFillColor(it->colour);
}
}
}
答案 0 :(得分:11)
通常的习语是
for (std::vector<gdf::Entity>::iterator it = brickWall.begin(); it != brickWall.end(); /*note nothing here*/)
{
if (it->getRect().intersects(ballMother.getRect())) {
it->rect.setFillColor(sf::Color::Red);
it = brickWall.erase(it);
}
else {
it->rect.setFillColor(it->colour);
++it;
}
}
否则你将跳过元素,并最终通过结束崩溃。
答案 1 :(得分:4)
K-ballo发现了这个错误,并提出了一个很好的习惯用法,但你可能会发现使用标准算法和删除删除习惯用法更容易。
struct Pred {
Pred(const BallMother& ballMother) {
//save refs to whatever you need for the compare
}
bool operator()(const gdf::Entity& item) {
//collision logic here, return true if you want it erased
}
};
现在你的功能:
std::vector<gdf::Entity>::iterator end_iter =
std::remove_if(brickWall.begin(), brickWall.end(), Pred(ballMother));
brickWall.erase(end_iter, brickWall.end());
或者更简洁:
brickWall.erase(std::remove_if(brickWall.begin(), brickWall.end(), Pred(ballMother)),
brickWall.end());