Java游戏: ArrayList and Iterator vs.线程

标签 java multithreading arraylist

伙计们。

我正在为我的 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 才能得到正确的结果。

感谢所有试图提供帮助的人!

最佳答案

需要记住两件事:

  1. 如果您需要在迭代 ArrayList 时从 ArrayList 中删除项目,则必须通过迭代器上的 remove() 方法来完成。如果修改列表本身,将会失败。

  2. 如果两个线程正在访问该列表,您应该使用 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/

相关文章:

java - 递归创建目录

java - 使用 python 调用并打印 Java 的输出

java - 如何使用 ThreadPoolTask​​Executor 获取线程状态?

java - 短项目 : Electronics Inventory

java - 使用 Java API 将文件上传到 GCS 时 CPU 使用率过高

java - 在循环内动态创建 ArrayList

java - 有什么方法可以区分主线程和它产生的任何线程吗?

multithreading - 计算机如何仅使用几个寄存器?

Java比较两个字符串似乎不起作用

arrays - 向 ArrayList 添加一组新值