Sup人。
我正在为我的Java类编写一个简单的僵尸游戏,我遇到了一个小问题:Zombies是我制作的一个类,我在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是一个指针,用于保存玩家射击的坐标。事情是:有时当你击中僵尸时应该发生的事情没有发生。我不知道是不是因为Iterator运行速度不够快或其他事情。
也许为每个僵尸制作一个不同的线程,但这会改变代码是一些基本方法,如果它没有帮助我不想冒失去所有时间。
那么,有什么想法吗?
//编辑:忘了说:我正在检查Overrided paint方法中的碰撞,因为我不知道如何在其他方法上绘制东西,当我尝试访问ArrayList时(它是另一个线程上的Sync'd ArrayList)它给我一个共同修改的异常。
// EDIT2: 问题解决了(从未有过)。
MouseEvent
传递的MouseListener
对象传递鼠标指针下端的坐标。所以它不是真正的碰撞问题,而是更多的数学问题。我必须比较clickPoint.y
- 25 以使其正确。
感谢所有试图提供帮助的人!
答案 0 :(得分:2)
要记住两件事:
如果需要在迭代过程中从ArrayList中删除项目,则必须通过迭代器上的remove()
方法执行此操作。如果您修改列表本身,它将失败。
如果两个线程正在访问列表,则应使用Collections.synchronizedList
包装它,或选择其他数据结构。
编辑:听起来你正在修改一个线程上的列表,而在另一个线程上迭代它。这将导致ConcurrentModificationException。避免它的最简单方法是在两个线程上使用synchronized块包装列表的用法。例如:
synchronized(horda) {
iterator = horda.iterator();
while (iterator.hasNext()) {
z = iterator.next();
...
}
}
另一种方法是在迭代之前克隆列表,或者使用java.util.concurrent中的一个特殊列表实现,例如CopyOnWriteArrayList。
答案 1 :(得分:0)
多线程只能对你有所帮助,而且它实际上取决于你拥有多少处理能力。
四叉树通常用于碰撞检测,因此可能值得研究,作为替代方案。
答案 2 :(得分:0)
在我看来,你最好使用for-each循环迭代僵尸。它是为执行这样的任务而引入的,所以你也可以使用它。
答案 3 :(得分:0)
我假设玩家通过点击窗口“射击”,因此tiroPos
是点击的x,y坐标。
如果是这种情况,并且你的问题是,当用户点击很多时,某些僵尸似乎没有被点击,那么可能只有最后一个“镜头”被保存在{ {1}}。
您可以通过在for循环周围添加适当的tiroPos
调用以及设置System.out.println()
的另一个调用来测试此问题。如果在for循环中间tiroPos
发生了变化,那就是为什么有些僵尸没有被射击。
如果是这种情况,您需要开始存储点击列表,而不仅仅是最新点击。
编辑:但这不会修复您的并发修改例外。