2011-07-21 157 views
0

我有兩個ArrayList,我使用的是一個用於敵方精靈,另一個用於子彈。當我運行應用程序時,它偶爾會在模擬器上崩潰,並在幾個級別內碰撞時在設備上崩潰。日誌不斷告訴我我有一個簡單的ListIterator錯誤。我想知道我將如何實現ListIterator。我沒有使用ListIterator,我四處搜尋以查找信息和示例,但我對如何真正做到這一點感到困惑。 add()函數在我的視圖類的onTouch方法中被調用,碰撞發生在我的線程類內部的碰撞方法中。Android遊戲中的Listiterator

登錄:

07-20 19:57:46.604: ERROR/AndroidRuntime(234): Uncaught handler: thread Thread-9 exiting due to uncaught exception 
07-20 19:57:46.613: ERROR/AndroidRuntime(234): java.util.ConcurrentModificationException 
07-20 19:57:46.613: ERROR/AndroidRuntime(234):  at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:64) 
07-20 19:57:46.613: ERROR/AndroidRuntime(234):  at com.android.hitmanassault.HitmanView$HitmanThread.startGame(HitmanView.java:333) 
07-20 19:57:46.613: ERROR/AndroidRuntime(234):  at com.android.hitmanassault.HitmanView$HitmanThread.gameStart(HitmanView.java:290) 
07-20 19:57:46.613: ERROR/AndroidRuntime(234):  at com.android.hitmanassault.HitmanView$HitmanThread.updateGame(HitmanView.java:393) 
07-20 19:57:46.613: ERROR/AndroidRuntime(234):  at com.android.hitmanassault.HitmanView$HitmanThread.run(HitmanView.java:237) 

檢查碰撞:

private void startGame(){ 
      synchronized(mSurfaceHolder){ 
       for(Beam bullet: beam){ 
        for(Sprite sprite: sprites){ 
         if(checkCollision(sprite, bullet)){ 
          sprites.remove(sprite); 
          beam.remove(bullet); 
          mScore = mScore + 1; 
          break; 
         }    
        } 
       } 
      }  
     } 

碰撞方法:

public boolean checkCollision(Sprite sprite, Beam bullet){ 

      boolean retValue = false; 
      int SpriteX = sprite.getX(); 
      int SpriteY = sprite.getY(); 
      int SpriteXS = sprite.getX() + sprite.getWidth(); 
      int SpriteYS = sprite.getY() + sprite.getHeight(); 
      int BeamX = bullet.getX(); 
      int BeamY = bullet.getY(); 
      int BeamXS = bullet.getX() + bullet.getBitmap().getWidth(); 
      int BeamYS = bullet.getY() + bullet.getBitmap().getHeight(); 


      if ((BeamX >= SpriteX && BeamX <= SpriteXS) || (BeamXS >= SpriteX && BeamXS <= SpriteXS)) { 
       if ((BeamY >= SpriteY && BeamY <= SpriteYS) || (BeamYS >= SpriteY && BeamYS <= SpriteYS)) { 
        retValue = true; 
       } 
      } 
      return retValue; 
     } 
+0

你能發表日誌嗎?它是'ConcurrentModificationException'嗎? – user802421

+0

將代碼粘貼到你正在迭代列表的地方,請問? –

回答

2

如果在另一個線程遍歷列表,您將一個元素添加到列表得到ConcurrentModificationException

您可以嘗試ConcurrentLinkedQueue,但根據您對遊戲一致性模型的要求,您應該重新考慮架構。

這是問題所在。

for(Sprite sprite: sprites) { <------- Iterate 
    if(checkCollision(sprite, bullet)) { 
     sprites.remove(sprite); <-------- Modify 
... 

快速修復是你可以收集你想要刪除的所有元素,然後在for循環後刪除它們。

ArrayList<Beam> toBeRemoveBeams = new ArrayList<Beam>(); 
ArrayList<Sprite> toBeRemoveSprites = new ArrayList<Sprite>(); 
for(Beam bullet: beam){ 
    for(Sprite sprite: sprites){ 
     if(checkCollision(sprite, bullet)){ 
      toBeRemoveBeams.add(beam); 
      toBeRemoveSprites.add(sprite); 
      mScore = mScore + 1; 
      break; 
     }    
    } 
} 
beam.removeAll(toBeRemoveBeams); 
sprites.removeAll(toBeRemoveSprites); 
+0

所以當他們被槍殺時,他們會顯示直到被移除或碰撞發生。 – Manji

+0

它再次崩潰給出相同的錯誤,除了使用線程13而不是線程9 – Manji