2017-06-04 23 views
0

我正在處理一個小遊戲,並遇到了列表中的一個大問題。無法刪除C++中的列表元素

這裏是我的代碼:

void cCollisionManager::checkCollision(cPlayer * pPlayer, std::list<cAsteroid*> *asteroidList, std::list<cShot*> *ShotList) 
{  
    sf::FloatRect PlayerBox = pPlayer->getSprite()->getGlobalBounds(); 

    for (auto it : *asteroidList) { 
     for (auto es : *ShotList) { 
      sf::FloatRect asteroidboundingBox = it->getSprite()->getGlobalBounds(); 
      sf::FloatRect ShotBox = es->getSprite().getGlobalBounds(); 

      if (asteroidboundingBox.intersects(ShotBox)) {   

       it = asteroidList->erase(it); 

       *pPlayer->pPunkte += 1; 
       std::cout << *pPlayer->pPunkte << std::endl; 
      } 

      if (asteroidboundingBox.intersects(PlayerBox)) { 
       if (*pPlayer->phealth >= 0.f) 
        *pPlayer->phealth -= 0.5f; 
      } 
     } 
    } 
} 

我用SFML,基本上一切正常。但是,如果我想刪除碰撞的小行星和鏡頭,程序將退出並顯示錯誤。在if循環中,我試圖擦除對象,但是編譯器也給出了一個錯誤,說明參數類型與我給它的對象類型不一樣。

編輯 我又看了另一個問題,你向我推薦,但我還沒有找到如何解決這個問題。因此,如果我將代碼更改爲while循環,則遊戲無法處理它,因爲碰撞管理器實際上是在SFML主循環的每次調用中調用的。所以它會卡在我的碰撞循環中。所以我改了一下我的代碼,但是仍然沒有成功。

+7

(https://stackoverflow.com/questions/10360461/removing-item -from-vector-while-in-c11-range-for-loop)使用迭代器和'erase'的適當結果。 – WhozCraig

+1

如果您無法從列表中刪除某個元素,請嘗試編寫一個簡單的程序來完成此操作,而不是其他任何操作。當你發現你的錯誤並掌握了技巧後,*然後*你可以在複雜的程序中使用它。 – Beta

+1

即使在注意到@ WhozCraig的評論之後,當你返回一個'end()'迭代器時,你有可能使用'it' - 在你的內部循環中沿着sf :: FloatRect行asteroidboundingBox = it-> getSprite( )....' – WhiZTiM

回答

1

不要修改使用range-for枚舉的序列。使用 迭代器和相應的擦除結果。 - WhozCraig

這實際上是它的答案。我犯了這個錯誤 - 使用for循環,而不是一個while循環,所以我的代碼有一些大問題和糟糕的構建思路 - 幸運的是,現在一切正常。 這是我的最後的代碼:[不要修改正在與範圍換列舉序列]

auto it = asteroidList->begin(); 
auto es = ShotList->begin(); 

while (it != asteroidList->end()) { 

    sf::FloatRect PlayerBox = pPlayer->getSprite()->getGlobalBounds(); 
    sf::FloatRect asteroidboundingBox = (*it)->getSprite()->getGlobalBounds(); 

    while (es != ShotList->end()) 
    { 
     sf::FloatRect ShotBox = (*es)->getSprite().getGlobalBounds(); 

      if (asteroidboundingBox.intersects(ShotBox)) { 
       it = asteroidList->erase(it); 
       es = ShotList->erase(es); 

       std::cout << "Asteroid destroyed" << std::endl; 
       *pPlayer->pPunkte += 1; 
       std::cout << *pPlayer->pPunkte << std::endl; 
       } 


     if (es != ShotList->end()) 
      es++; 

    } 
     if (asteroidboundingBox.intersects(PlayerBox)) 
     { 
      if (*pPlayer->phealth > 3.f) { 
       *pPlayer->phealth -= 5.f; 
       it = asteroidList->erase(it); 
      } 
      else 
       *pPlayer->pBStateAlive = false; 
     } 


    if (it != asteroidList->end()) { 
     it++; 
     es = ShotList->begin();  

    } 


} 

}