2

次のコードは、ボールがレンガと重なっているかどうかをチェックします。オーバーラップが発生すると、ブリックが強調表示され、リストから削除されます。

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);                
        }
    }
}
4

2 に答える 2

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;
    }
}

そうしないと、要素をスキップするだけでなく、最後を過ぎて最終的にクラッシュします。

于 2012-06-09T00:50:08.020 に答える
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());
于 2012-06-09T01:00:08.680 に答える