2016-08-02 104 views
0

我正在用C++和sfml構建太空射擊遊戲。 現在我有一個子彈類,它只是一個帶有一些運動邏輯的圓形。我需要一種方法來存儲子彈對象,繪製它們,並且在它們碰到某物或超出範圍時也可以將它們取消/刪除。我將它們添加到一個列表中,每個項目符號對象都有一個名爲alive的bool屬性,我根據距離或與其他對象的碰撞而不斷更新。每當它碰撞或超出範圍時,我都會將它設置爲假。然後遍歷列表來刪除活動屬性爲false的所有對象。這聽起來像是一種可怕的方法,並且在從列表中刪除它們之後,子彈對象甚至會被釋放?通過按鍵創建新對象並將其添加到列表

這是到目前爲止我的代碼:

if (Keyboard::isKeyPressed(sf::Keyboard::T)) { 
     Bullet newBullet(mySub.getSprite().getPosition().x + 64, mySub.getSprite().getPosition().y + 20); 
     bulletList.push_back(newBullet); 
} 
list<Bullet>::iterator it = bulletList.begin(); 
while (it != bulletList.end()) { 
     if (it->getNoDraw() == true) { 
      bulletList.erase(it++); 
     } 
     else { 
      it->update(); 
      if (it->getBulletSprite().getPosition().x > mySub.getSprite().getPosition().x + 1200) { 
        it->setNoDraw(); 
       } 
      } 
     } 

cout << "list size " << bulletList.size() << endl; 
for (list<Bullet>::iterator it = bulletList.begin(); it != bulletList.end(); ++it) { 
      window.draw(it->getBulletSprite()); 
} 

我創建一個新的子彈物體,它的每個我按時間T增加了bulletList,但它實際上沒有增加,因爲新的子彈名單bulletList.size()總是打印0.任何想法如何能有效地做到這一點?

+0

爲什麼使用for循環繪製。你不能在if(it-> getNoDraw()== true)的else部分中繪製該子彈嗎?這樣更有效,因爲你只需遍歷整個列表。 – Lucian

+0

你說得對。稍後我將更新我的代碼,以便使用一次迭代更新我的對象並繪製。這只是我習慣於更新我的所有對象,然後繪製所有對象。如果是這種情況,那麼我應該在for-loop之前清理我的窗口。 – Chrine

回答

1

代碼中有一些錯誤。 對於list,您應該重讀erase(),它會返回下一個迭代器。 當你不摧毀子彈時,你也會在列表中失蹤前進。

if (Keyboard::isKeyPressed(sf::Keyboard::T)) { 
     Bullet newBullet(mySub.getSprite().getPosition().x + 64, 
         mySub.getSprite().getPosition().y + 20); 
     bulletList.push_back(newBullet); 
} 
list<Bullet>::iterator it = bulletList.begin(); 
while (it != bulletList.end()) { 
    if (it->getNoDraw() == true) { 
     it = bulletList.erase(it); // erase already advance it to the next 
    } else { 
     it->update(); 
     if (it->getBulletSprite().getPosition().x > 
       mySub.getSprite().getPosition().x + 1200) { 
      it->setNoDraw(); 
     } 
     it++; // move on to the next position 
    } 
} 

cout << "list size " << bulletList.size() << endl; 
for (list<Bullet>::iterator it = bulletList.begin(); 
    it != bulletList.end(); ++it) { 
    window.draw(it->getBulletSprite()); 
} 
+0

'bulletList.erase(it);'使其無效'。不要忘記用返回的迭代器更新'it'。 – Hiura

+0

我改變了bulletList.erase(它)它= bulletList.erase(它),它似乎工作! – Chrine

+0

已更正的代碼,「it =」部分丟失。 – Surt

相關問題