从Java中循环中的数组中删除

时间:2015-03-03 18:35:08

标签: java for-loop collision-detection

我正在尝试用Java创建一个空间入侵者克隆。

在太空入侵者中,当射击被击中并击中敌人时,两个物体都被摧毁。这就是我的代码:

while (prosessGame) {

    Drawable whatToRemove = null;
    Drawable whatToRemove2 = null;
    for (Drawable d : DrawableStuff) {

        if (!d.callTick()) {
            whatToRemove = d;
        }

        for (Drawable k : DrawableStuff) {
            if (k.rectIntersect(d.getRect()) && k != d) {
                whatToRemove = d;
                whatToRemove2 = k;
            }
        }
    }

    for (Drawable d : DrawableStuff) {
        d.callAfterTick();
    }
    DrawableStuff.remove(whatToRemove);
    DrawableStuff.remove(whatToRemove2);

Drawable是一个接口,DrawableStuff是我所有实例的数组,d.callTick()是我的对象的游戏代码,如果实例需要被销毁则返回false,d.callAfterTick就像callTick但它在它之后运行, getRect是获取实例的矩形碰撞框的getter。

显然,此代码最多只允许同时销毁两个实例。我想要这个代码来创建一个列表/队列/堆栈因为if(!d.callTick){DrawableStuff.remove(d);}并返回错误。

编辑:

错误是当我尝试使用if(!d.callTick)删除实例时{DrawableStuff.remove(d);}而不是if(!d.callTick()){whatToRemove = d;}我得到了错误:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at helloworld.java.Drawer.main(Drawer.java:84)

我认为这是因为我正在使用直接使用数组的for循环,而我正在改变它的一半,我认为。

我正在寻找的是一种说法(用伪代码):

queue removeQueue
    for (Drawable d :  DrawableStuff){
    if (!d.callTick()){
    removeQueue.add(d);
    }
    -- bla bla bla--
}
for(j : removeQueue){
    Drawablestuff.remove(j);
}

编辑2:

我已将代码更改为:

for (Iterator<Drawable> i = DrawableStuff.iterator(); i.hasNext(); ){
        Drawable d = i.next();

        if (!d.callTick()) {
            i.remove();
        }

        for (Iterator<Drawable> ii = DrawableStuff.iterator(); ii.hasNext();){
            Drawable dd = ii.next();
            if (dd.rectIntersect(d.getRect()) && d!=dd){
                ii.remove();
                i.remove();
            }
        }
    }

但它会返回此错误:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.remove(Unknown Source)
at helloworld.java.Drawer.main(Drawer.java:112)

当我删除第二个循环时,代码确实按预期工作,所以它看起来像这样:

for (Iterator<Drawable> i = DrawableStuff.iterator(); i.hasNext(); ){
  Drawable d = i.next();
  if (!d.callTick()) {
    i.remove();
  }
}

(当它们撞到屏幕顶部时,它只会移除射弹,这是唯一让它返回虚假的东西)

有人可以帮我解决这个问题吗? :)

1 个答案:

答案 0 :(得分:1)

可以从大多数类型的Collection s / Iterable(foreach使用的界面)中移除内容,同时使用其Iterator对其进行迭代直接做。

不幸的是,这意味着重写循环,因为foreach循环会隐藏Iterator

for (Iterator<Drawable> i = DrawableStuff.iterator(); i.hasNext(); ) {
    Drawable d = i.next();

    if (!d.callTick()) {
        i.remove();
    }
}

并非所有Iterator支持remove,但一般收集的支持{{1}}。