2013-11-24 5 views
1

Так что я делаю игру-симулятор зомби. На данный момент у меня есть группа игроков и зомби. Когда выживший сталкивается с зомби, я хочу, чтобы он удалил оставшегося в живых и заменил его зомби, по сути превратив его в зомби.Удаление объекта, а затем добавление нового на его место

Обнаружение столкновений работает нормально (я просто использую прямоугольники awt с методом пересечения). Однако у меня есть список групп зомби и список оставшихся в живых. Когда происходит столкновение, я добавляю зомби в список зомби. Затем я удаляю оставшегося в живых из этого списка. Он работает пару раз, а затем случайным образом выдает исключение индекса за пределы.

java.lang.IndexOutOfBoundsException: Index: 13, Size: 13 
    at java.util.ArrayList.rangeCheck(Unknown Source) 
    at java.util.ArrayList.remove(Unknown Source) 
    at com.caveragestudios.zombiesim.World.update(World.java:53) 
    at com.caveragestudios.zombiesim.Main.update(Main.java:93) 
    at com.caveragestudios.zombiesim.Main.run(Main.java:69) 
    at java.lang.Thread.run(Unknown Source) 

Я пробовал использовать расширенные для циклов, регулярные для циклов и итераторы с петлей while. Кажется, что ничего не работает. Это мой код на данный момент.

for (int i = 0; i < survivors.size(); i++) { 
     Survivor s = survivors.get(i); 
     for (int ii = 0; ii < zombies.size(); ii++) { 
      Zombie z = zombies.get(ii); 
      if (z.bounds.intersects(s.bounds)) { 
       zombies.add(new Zombie(s.position, this)); 
       survivors.remove(i); 
      } 
     } 
    } 

Все остальное, кажется, работает нормально, это просто, когда я пытаюсь изменить списки он вроде путает и выдает индекс из исключения границ. Есть идеи?

ответ

0

Ну, мне это удалось выяснить для себя. С толчком в правильном направлении от Масуда. Проблема заключалась в том, что я не мог изменять списки во время итерации по ним, однако мне все еще нужны данные из итераторов.

То, что я сделал, это создать два новых списка, один из которых называется toRemove, чтобы быть заполненными сталкивающимися оставшимися в живых. Затем один вызвал toAdd, чтобы его заполнили встречные зомби.

Затем повторяется как обычный, но вместо добавления и удаления из основных списков напрямую добавляется их в эти новые списки. Затем, после завершения итерации, удалены и соответственно добавлены эти новые списки. Это окончательный код.

List<Survivor> toRemove = new ArrayList<Survivor>(); 
    List<Zombie> toAdd = new ArrayList<Zombie>(); 

    Iterator<Survivor> survIt = survivors.iterator(); 
    Iterator<Zombie> zombIt = zombies.iterator(); 
    while (survIt.hasNext()) { 
     Survivor s = survIt.next(); 
     while (zombIt.hasNext()) { 
      Zombie z = zombIt.next(); 
      if (z.bounds.intersects(s.bounds)){ 
       toAdd.add(new Zombie(s.position, this)); 
       toRemove.add(s); 
       System.out.println("collided"); 
      } 
     } 
    } 

    for (Survivor s : toRemove) { 
     survivors.remove(s); 
    } 

    for (Zombie z : toAdd) { 
     zombies.add(z); 
    } 
2

Вы использовали внешний список survivors индекс i внутренний список zombies. Ваша индексная переменная неверна в zombies.get(i).

for (int i = 0; i < survivors.size(); i++) { 
    Survivor s = survivors.get(i); 
    for (int ii = 0; ii < zombies.size(); ii++) { 
     Zombie z = zombies.get(ii);// Here use ii instead of i 
     //.............. 
    } 
} 

Чтобы удалить элемент из коллекции использования Iterator.remove. Измените свой код, как показано ниже, для безопасного удаления из коллекции.

Iterator<Survivor > survIt=survivors.iterator();  
Iterator<Zombie> zombIt=zombies.iterator(); 
while(survIt.hasNext()){ 
     Survivor s=survIt.next();  

     while(zombIt.hasNext()){ 
      Zombie z=zombIt.next(); 

      if (z.bounds.intersects(s.bounds)) { 
      zombies.add(new Zombie(s.position, this)); 

      survIt.remove(); //Use Iterator.remove. 

      }     
     } 
    } 
+0

Вау, я не могу поверить, что пропустил это, lol. Однако я изменил его, и теперь вместо того, чтобы работать несколько раз, а затем ломаюсь, он ломается при первом столкновении. Поэтому я думаю, что это была не единственная проблема. – Darren

+0

Darren, Используйте Iterator.remove, чтобы удалить элемент из коллекции. – Masudul

+0

Я не верю, что вы можете удалить из него определенный объект из списка. Я должен был использовать что-то вроде while (survivors.iterator(). HasNext()). Тогда он просто застрял там и не продолжит остальную часть программы. Я пробовал это, и я не верю, что это сработает. – Darren

Смежные вопросы