删除实体,然后在其位置添加新实体

时间:2013-11-24 04:14:22

标签: java for-loop arraylist

所以我正在制作一个僵尸模拟游戏。我所拥有的是一群随机乱跑的玩家和僵尸。当幸存者与僵尸发生碰撞时,我希望它能够移除幸存者并用僵尸替换它,基本上将他变成僵尸。

碰撞检测工作正常(我只是使用带交叉方法的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)

我尝试过使用高级for循环,常规for循环和带有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);
            }
        }
    }

其他所有内容似乎都正常工作,只是当我尝试修改列表时,它会混淆并抛出索引超出范围的异常。有什么想法吗?

2 个答案:

答案 0 :(得分: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.

            }                 
        }
  }

答案 1 :(得分:0)

我已经成功地为自己解决了这个问题。从Masud向正确的方向发展。问题是我在迭代它时无法修改列表,但是我仍然需要来自迭代器的数据。

我所做的是创建两个新的列表,一个名为toRemove,以填充碰撞的幸存者。然后一个叫做添加,以填充碰撞的僵尸。

然后像往常一样迭代,但不是直接从主列表中添加和删除,而是将它们添加到这些新列表中。然后在迭代完成后,删除并相应地添加这些新列表。这是最终的代码。

    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);
    }