2011-11-30 94 views
0

我不知道我錯過了什麼...完整的代碼非常大,所以我只是把這個部分拋出異常在這裏。數組索引超出範圍

 for (int i = 0; i < player.getBullets().size(); i++) { //for every player bullet 
      for (int j = 0; j < aliens.getAliens().size(); j++) { //for every player bullet every alien 
       player.getBullets().get(i); 
       aliens.getAliens().get(j); 
       if (player.getBullets().get(i).getBounds().intersects(aliens.getAliens().get(j).getBounds())){ //player bullet vs alien collison 
        if (aliens.getAliens().get(j).getType() == 1) 
         score += 2 + level; 
        else if(aliens.getAliens().get(j).getType() == 2) 
         score += 4 + level; 
        else 
         score += 8 + level*2; 
        aliens.getAliens().remove(j); // alien dies 
        player.getBullets().remove(i); 
        System.out.println("player bullet removed"); 
       } 
      } 
     }  

它放在//玩家子彈VS外來碰撞線引發了異常。 我加入了player.getBullets().get(i)getAliens()來判斷哪一個拋出了異常,這是一個玩家。

錯誤似乎是隨機的,但我相信當外星人移動到子彈上時,它會超出界限。如果子彈直接擊中外星人,它可以正常工作。這可能是使用相交的錯誤嗎?

順便說一下,這是一個太空侵略者模仿。任何幫助,將不勝感激。

+3

請張貼異常或至少告訴在哪一行它發生 – mort

回答

2

當您遍歷它們時,您正在更改您的列表(通過在循環內調用.remove())。您在檢查與它碰撞的過程中刪除了子彈。

一個解決方案是給外星人/子彈頭/其他類似的物體一個isDead變量。然後,不要在循環中刪除它們,而要在循環後刪除所有人,並使用isDead == true刪除所有人。

0

在代碼中,你是從什麼我想刪除的項目是一個列表

aliens.getAliens().remove(j); // alien dies 
player.getBullets().remove(i) 

什麼可能發生的是,你仍然在內部循環的循環,而外環的條件是無效的。

1

問題是,您正在從您正在遍歷的數組中刪除項目。據的Javadoc:

int size() 
Returns the number of elements in this collection. 

這是屈服,當你從集合中刪除該項目,數字會比實際徵收尺寸更大,因此導致成出界。

您需要使用iterator遍歷集合,然後在遍歷集合時使用iterator.remove()刪除集合中的項目。

1

你應該創建迭代器遍歷玩家和外星人。然後,當一個應該被刪除在迭代器而不是原始列表。這使循環工作。

由於@託麥建議,不要刪除,將它們標記爲已死,稍後可能會將其刪除,也是一個不錯的解決方案。

0

在我看來那個player.getBullets()。remove(i);刪除一些東西,但你繼續循環。你必須在System.out.println之後跳出內部for循環...

3

使用Iterator它支持remove操作它的集合。爲了給你一個想法(從OP所有無關的代碼中刪除):

List<Bullet> bullets = new ArrayList<Bullet>(); 
    List<Alien> aliens = new ArrayList<Alien>(); 

    Iterator<Alien> alienIterator = aliens.iterator(); 
    Iterator<Bullet> bulletIterator = bullets.iterator(); 
    while (bulletIterator.hasNext()) { //for every player bullet 
     while (alienIterator.hasNext()) { //for every player bullet every alien 
      Bullet bullet = bulletIterator.next(); 
      Alien alien = alienIterator.next(); 
      if (bullet.getBounds().intersects(alien.getBounds())) { //player bullet vs alien collison 
       bulletIterator.remove(); 
       alienIterator.remove(); 
       System.out.println("player bullet removed"); 
      } 
     } 
    } 

請注意,如果您修改外星人它仍然容易受到IllegalStateException /子彈別的地方兼任。

1

假設玩家0被殺死。當你移除他的子彈時,所有其他子彈都會在索引中向下移動。因此,當指數遞增到1,你會看什麼最初子彈2,沒有子彈1

從索引列表中刪除時,總是經過相反的順序循環,讓你做不影響仍然需要查看的元素的順序。

但是,如果最後一顆子彈殺死任何你看到的問題(在KAPOW)發生。當你仍然在for(j)循環中時,刪除最後一個項目符號。下一次調用getBullet(i)將失敗,因爲不再有子彈我,現在只有i-1。當子彈殺死某物時,你應該跳出內部循環。 (假設子彈可以;噸立刻殺了2名外國人)

這就是說,您將得到更好的通過

  1. 服務使用新樣式的循環,for (Bullet bullet : player.getBullets() {}它會真的簡化代碼! !
  2. 考慮不刪除的飛行。將所有要刪除的內容收集到兩個臨時列表中,deadAliens和usedBullets。在你的循環調用

    aliens.getAliens()結束的removeAll(deadAliens)。 player.getBullets()。removeAll(deadBullets);