2

現在、SFMLでトップダウンシューティングゲームをプログラムしようとしていますが、問題が発生しました。私はC++とプログラミング全般にまったく慣れていないので、厄介なコードや過度に複雑なソリューションを許してください。

私には2つstd::listのがあります。1つはランダムにスポーンする敵を含み、もう1つは私が発射した弾丸を含みます。弾丸が敵に当たると、両方とも消去されるはずですが、機能しません。

これが問題です-私のコードの一部:

for(MonsterIt = MonsterList.begin(); MonsterIt != MonsterList.end(); MonsterIt++)
{

    //Here would be Monster-Movement

    //Collision Monster-Player (MonsterIt = iterator of MonsterList)
    if ((MonsterIt -> getPosition().x + 25) >= PlayerX - 25 && 
        (MonsterIt -> getPosition().x - 25) <= PlayerX + 25 &&
        (MonsterIt -> getPosition().y + 25) >= PlayerY - 25 && 
        (MonsterIt -> getPosition().y - 25) <= PlayerY + 25   )
    {
        MonsterList.erase(MonsterIt);
        break;              
    }


        window.draw(*MonsterIt);
}

それが私がモンスターとプレイヤーの間で衝突をした方法です。それはうまくいったので、私はモンスターとレーザーで同じことを試しました:

for(LaserIt = LaserList.begin(); LaserIt != LaserList.end(); LaserIt++)
{

    //Here would be "Laser-Movement"

    //Collision-Laser                               // Doesn't work
    if ((MonsterIt -> getPosition().x + 25) >=      //
        (LaserIt   -> getPosition().x - 7) &&       //
        (MonsterIt -> getPosition().x - 25) <=      //
        (LaserIt   -> getPosition().x + 7) &&       //
        (MonsterIt -> getPosition().y + 25) >=      //
        (LaserIt   -> getPosition().y - 7) &&       //
        (MonsterIt -> getPosition().y - 25) <=      //
        (LaserIt   -> getPosition().x + 7))         //
    {                                               //
        MonsterList.erase(MonsterIt);               //
                                                    //
        LaserList.erase(LaserIt);                   //
                                                    //
        break;                                      //
    }                                               //  

    window.draw(*LaserIt);
}

マークしたコードの一部(右側に//を付けて)を挿入すると、「リストイテレータは参照解除できません」というエラーが発生します。デバッグ中に、撮影するとすぐにエラーが発生します。上記のコードを切り取ると、正常に実行されます(撃ったり、モンスターに足を踏み入れたりすると、モンスターが消えるなど)。そのため、残りのコードは機能していると思います。

それで、異なるリストのイテレータ間の衝突さえ可能ですか?もしそうなら、どうすればいいですか?

さらに詳しい情報やコードが必要な場合は、お問い合わせください。よろしくお願いします...

4

1 に答える 1

0

使用するイテレータは無効です。

あなたの問題にはいくつかの解決策があります。最初の1つ:

for(MonsterIt = MonsterList.begin(); MonsterIt != MonsterList.end(); MonsterIt++)
{
    //Here would be Monster-Movement

    //Collision Monster-Player (MonsterIt = iterator of MonsterList)

    // Collision with laser, inside the loop for monsters
    for(LaserIt = LaserList.begin(); LaserIt != LaserList.end(); LaserIt++)
    {
    }

    window.draw(*MonsterIt);
}

このソリューションは実際にはC++っぽいものではありません。OOPを使用すると、はるかに明確なコードを作成できます。

class Player
{
    public:
        int X, Y; // for code simplicity on SO.
};
// ...

Player player;
for(MonsterIt = MonsterList.begin(); MonsterIt != MonsterList.end(); MonsterIt++)
{
    MonsterIt->update(player,LaserList);
    if(!MonsterIt->isAlive())
    {
        // Remove monster from list *without* break
    }
}

次に、Monster次のようなクラスです。class Monster {bool alive; public:bool isAlive()const {return alive; }

        bool collideWithPlayer(Player p) const
        {
            // Returns whether it collide with player
            // ...
        }

        bool collideWithLaser(Laser l) const
        {
            // Returns whether it collide with one laser
            // ...
        }

        bool collideWithLasers(LaserList l) const
        {
            for(LaserIt = LaserList.begin(); LaserIt != LaserList.end(); LaserIt++)
                if(collideWithLaser(*LaserIt))
                    return true;
            return false;
        }


        void update(Player p, LaserList l)
        {
            if(collideWithPlayer(p) || collideWithLasers(l))
                alive = false;
            else
                window.draw(this);
        }
};
于 2012-12-20T14:14:57.943 に答える