2017-04-20 11 views
1

私は、クラスのためにスペースインベーダーをプログラミングするのは非常に困難です。私は「ミサイル」と私の「エイリアン」を保管するためのリストを保管するためにリストを使用することになっています。スペースバーを押して新しいエイリアンにロードし、2人の接触があったときに両方を削除しようとしていて、過去に "エイリアン"を削除することもできません。複数のミサイルが発射されたときにさまざまなバグがあり、この機能がコメントアウトされていればミサイルは正常に機能します。私はすでに宇宙人のリストを含む別のクラスにミサイルのリストを渡し、両方を削除することを余儀なくされている。ここで2つのリストから要素を削除するにはどうすればいいですか?

は、問題のあるコードです:

bool AlienMgr::checkHit(PlayerMgr& playerMgr) 
{ 

    bool hit = false; // If the player hits an alien, switches to true and is returned. 
    list<Missile*>::iterator missileIter; 
    list<Missile*> missileList = playerMgr.getMissiles(); 
    int missileCount; 

    FloatRect missileBounds; 
    FloatRect alienBounds; 

    iter = myAliens.begin(); 

    while (!myAliens.empty() && iter != myAliens.end()) 
    { 
     alienBounds = (*iter)->getGlobalBounds(); 

     if (!missileList.empty() && !hit) 
     { 

      for (missileIter = missileList.begin(); missileIter != missileList.end() && !hit; missileIter++) 
      { 
       missileBounds = (*missileIter)->getMissileBounds(); 

       if (alienBounds.intersects(missileBounds)) 
       { 
        delete (*iter); 
        iter = myAliens.erase(iter); 
        cout << "HIT" << endl; 

       } 
       else 
       { 
        iter++; 
       } 
      } 
     } 
     else 
     { 
      iter++; 
     } 
    } 
    return hit; 
} 
+2

*プレーヤーがエイリアンに当たった場合は、trueに切り替えて返されます。* - いいえ、trueに切り替わりません。それはコメントが言っていることですが、それはコード内で起こることではありません:)。また、修正を加える前に、変数の宣言をどこに初期化するかを移してください。関数の初めにそれらをすべて宣言することは悪い、時代遅れの習慣です。同様に、オブジェクトのライフタイムを手動で管理するべきではありません。値を格納すると、それらを '削除 'する必要がなくなります。ノイズを除去すると、実際の問題に集中するのに役立ちます。 –

+0

エイリアンとそれが衝突するすべてのミサイルを取り除きたい場合は、エイリアンを取り外す前にミサイルを取り除く必要があります。 – molbdnilo

答えて

0

あなたはあなたのコード内のいくつかの問題を持っています。私はそれらをきれいにしようとしました。また、私はあなたがC++ 11を使用できることを願っています。

bool AlienMgr::checkHit(PlayerMgr& playerMgr) 
{ 

    bool hit = false; // If the player hits an alien, switches to true and is returned. 
    list<Missile*> missileList = playerMgr.getMissiles(); 
    int missileCount; 

    FloatRect missileBounds; 
    FloatRect alienBounds; 

    // iter == myAliens.end() if it's empty 
    for (auto iter = myAliens.begin(); iter != myAliens.end();) 
    { 
     bool hitDetected = false; 
     alienBounds = (*iter)->getGlobalBounds(); 

     // remove all missiles intersecting current alien and set flag 
     missileList.remove_if([&](Missile* missile) 
      { 
       if (!alienBounds.intersects(missile->getMissileBounds())) 
        return false; 

       hitDetected = true; 
       delete missile; 

       return true; 
      }); 

     if (hitDetected) 
     { 
      hit = true; 

      delete (*iter); 
      iter = myAliens.erase(iter); 
      cout << "HIT" << endl; 
     else 
     { 
      iter++; 
     } 
    } 
    return hit; 
} 

しかし、もっと重大な問題があります。あなたのコードはあまりにもC + + 98'ishです。 私はいくつかの改善を助言する:

  • 利用std::vector代わりのstd::list代わりに、手動でのメモリ管理の
  • 使用スマートポインタを(コードは単純くらいだろう(それはリストが速くなりますときが本当にハードケースを見つけることです)理解しやすい)
関連する問題