伙计们。
我正在为我的 Java 类编写一个简单的僵尸游戏,但我遇到了一个小问题:僵尸是我制作的一个类,我将它们放在 ArrayList 上,如下所示:
horda.add(new Zumbi( (int)(Math.random()* 750), 0));
其中参数表示僵尸在屏幕上生成的位置。要杀死它们,你必须单击它们,非常简单,用迭代器检查碰撞,在这里:
java.util.Iterator<Zumbi> itr = horda.iterator();
while (itr.hasNext()){
Zumbi z = itr.next();
if (tiroPos.x > z.zumbiPos.x &&
tiroPos.x < z.sprite.getWidth() + z.zumbiPos.x &&
tiroPos.y > z.zumbiPos.y &&
tiroPos.y < z.sprite.getHeight() + z.zumbiPos.y){
//things to do when it hits
}
tiroPos 是一个指针,保存玩家射击的坐标。事实是:有时当你击中僵尸时应该发生的事情并没有发生。我不知道是因为迭代器运行速度不够快还是其他什么原因。
也许为每个僵尸创建一个不同的线程是可行的,但这会改变代码,这是一些基本的方法,我不想冒着失去所有时间的风险,如果它没有帮助。
那么,有什么想法吗?
//编辑:忘了说:我正在检查重写的绘制方法中的冲突,因为我不知道如何在其他方法上绘制东西以及当我尝试访问 ArrayList 时(它是a Sync'd ArrayList)在另一个线程上它给我抛出了一个共同修改异常。
//编辑2: 问题解决了(从来没有解决过)。
MouseListener
传递的 MouseEvent
对象传递鼠标指针下端的坐标。所以这并不是一个真正的碰撞问题,更多的是一个数学问题。我必须比较 clickPoint.y
- 25 才能得到正确的结果。
感谢所有试图提供帮助的人!
最佳答案
需要记住两件事:
如果您需要在迭代 ArrayList 时从 ArrayList 中删除项目,则必须通过迭代器上的
remove()
方法来完成。如果修改列表本身,将会失败。如果两个线程正在访问该列表,您应该使用
Collections.synchronizedList
包装它,或者选择不同的数据结构。
编辑:听起来您正在修改一个线程上的列表,同时在另一个线程上迭代该列表。这将导致 ConcurrentModificationException。避免这种情况的最简单方法是在两个线程上使用同步块(synchronized block)包装列表的使用。示例:
synchronized(horda) {
iterator = horda.iterator();
while (iterator.hasNext()) {
z = iterator.next();
...
}
}
另一种选择是在迭代之前克隆列表或使用 java.util.concurrent 中的特殊列表实现之一,例如 CopyOnWriteArrayList .
关于Java游戏: ArrayList and Iterator vs.线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6500851/