2016-07-19 21 views
1

Ich mache gerade ein einfaches 2D-Spiel in Java. Ich habe eine Controller-Klasse erstellt und verknüpfte Listen für Zombies (Feinde) und Kugeln erstellt. Dann versuche ich in meiner gameState Klasse für jede Schleife die verknüpften Listen zu durchlaufen und festzustellen, ob es eine Kollision mit der Kugel und dem Zombie gibt. Wie auch immer es in meinem Codebeispiel dargestellt ist, nur der Gegner kann aus dem Spiel entfernt werden, wenn ich versuche, die Kugel ebenfalls zu entfernen, stürzt das Spiel ab. Ich habe mich gefragt, ob ich ein paar Ideen bekommen könnte, wie ich beide Entitäten nach einer Kollision entfernen kann.Entfernen von Feind und Kugel in Kollision Java

das ist der Fehler, den ich bekommen, wenn die Kugel mit dem Feind kollidiert

Exception in thread "Thread-1" java.util.ConcurrentModificationException 
at java.util.LinkedList$ListItr.checkForComodification(Unknown Source) 
at java.util.LinkedList$ListItr.next(Unknown Source) 
at android.game.GameState.update(GameState.java:71) 
at android.game.Game.update(Game.java:121) 
at android.game.Game.run(Game.java:101) 
at java.lang.Thread.run(Unknown Source) 

In GameState Klasse:

for(Zombie zombie : c.z) 
    { 
     if(player.getX() > zombie.getX()){ 
      zombie.setX(zombie.getX() + 1); 
     } 

     if(player.getX() < zombie.getX()){ 
      zombie.setX(zombie.getX() - 1); 
     } 

     if(player.getY() > zombie.getY()){ 
      zombie.setY(zombie.getY() + 1); 
     } 

     if(player.getY() < zombie.getY()){ 
      zombie.setY(zombie.getY() - 1); 
     } 

     if(player.getBounds().intersects(zombie.getBounds())){ 

      kills ++; 
      c.removeZombie(zombie); 
      System.out.println("kills" + kills); 

     } 

     for(Bullet bullet : c.b){ 
      if(zombie.getBounds().intersects(bullet.getBounds())){ 
       //c.removeBullet(bullet); 
       c.removeZombie(zombie); 
       kills++; 

       System.out.println("kills" + kills);   
      } 

     } 

    } 

Controller-Klasse:

public class Controller { 

LinkedList<Bullet> b = new LinkedList<Bullet>(); 
LinkedList<Zombie> z = new LinkedList<Zombie>(); 

Bullet TempBullet; 
Zombie TempZombie; 

public Controller(){ 
    addZombie(new Zombie (200,600)); 
    addZombie(new Zombie (400,650)); 
} 

public void tick(){ 
    for(int i = 0; i<b.size(); i++){ 
     TempBullet = b.get(i); 

     TempBullet.tick(); 
    } 

    for(int i = 0; i<z.size(); i++){ 
     TempZombie = z.get(i); 

     TempZombie.update(); 
    } 


} 

public void draw(Graphics g){ 
    for(int i = 0; i < b.size(); i++){ 
     TempBullet = b.get(i); 

     TempBullet.draw(g); 
    } 

    for(int i = 0; i < z.size(); i++){ 
     TempZombie = z.get(i); 

     TempZombie.render(g); 
    } 

} 

public void addBullet(Bullet block){ 
    b.add(block); 
} 

public void removeBullet(Bullet block){ 
    b.remove(block); 
} 

public void addZombie(Zombie block){ 
    z.add(block); 
} 

public void removeZombie(Zombie block){ 
    z.remove(block); 
} 
} 
+0

ist nicht eine sehr genaue Beschreibung. Ich nehme an, Sie erhalten eine Ausnahmebotschaft. – khelwood

+0

Ich habe die Frage bearbeitet – Phill

+0

Nehmen Sie Update-Logik von GameState, und legen Sie es in entsprechenden 'update' Methode in zomby/bullet/was auch immer Klassen. Erstellen Sie "isDestroyed" -Flags, und setzen Sie sie auf "true", wenn Sie eine Kollision erkennen und dadurch Dinge zerstören möchten. Schließlich iterieren Sie in Ihrem GameState über Ihre Zombies/Aufzählungszeichen, rufen deren Update-Methode auf, überprüfen ihr 'isDestroyed'-Flag und wenn es wahr ist, entfernen Sie sie aus der Sammlung. –

Antwort

3

Verwenden Sie ein Iterator durch die Liste zu gehen, und verwenden Sie die remove() Methode das aktuelle Element aus Ihrer Sammlung zu entfernen:

„stürzt das Spiel“
for(Iterator<Zombie> it = c.z.iterator(); it.hasNext();) { 
    Zombie zombie = it.next(); 
    if (collisionWithBullet) 
     it.remove(); 
} 
1

Sie können eine nicht verwenden für jede Schleife, um die Kollision mit dem Geschoss zu überprüfen und dann dasselbe Geschoss gleichzeitig zu entfernen. Stattdessen können Sie versuchen, die zu löschenden Kugeln zu markieren und sie nach der Kollisionserkennung für jede Schleife zu entfernen.

1

ConcurrentModificationException tritt auf, wenn Sie das Element entfernen, während Sie for-each loop ausführen. Eine Möglichkeit, dies zu umgehen, ist die Schleife zu einem indizierte eine ändern:

for (int i = c.z.size() - 1; i >= 0; i--) { 
    Zombie zombie = c.z.get(I); 

einen Zombie Löschen sollte dann sicher sein, ohne Zombies speichern in einer getrennten Sammlung zu entfernen.