在Java Swing游戏循环中正确使用SwingWorker

时间:2015-02-18 23:50:17

标签: java multithreading swing

我目前正在开发一个模拟,涉及在JPanel周围移动的数千个1x1像素2D矩形。矩形移动并可以碰撞并连接在一起。

我创建了一个Event Dispatch Thread,然后创建了我的GUI。然后,我创建了一个模拟实例,并使用游戏循环通过move()detectCollision()repaint()方法控制系统,所有矩形都存储在全局{{ 1}}。 ArrayList将每个矩形移动1个像素,而move()检查两个矩形是否彼此相邻,并将它们连接在一起(如果适用)。

系统目前正常运行,但运行速度极慢。在每个方法周围放置一个计时器表明我的detectCollision()方法最多可能需要1000毫秒才能完成。我的问题是,我可以在detectCollision()方法中使用工作线程来提高程序的效率吗?

2 个答案:

答案 0 :(得分:2)

广域算法

  • 任何算法都可以限制在模拟系统中检查碰撞的对数。

  • 如果您正在执行n ^ 2次碰撞检查,则需要一个广泛的算法。

  • 由于您的对象已经是矩形,我认为一些空间分区技术可以帮助您。

资源: Broad-phase collision detection methods?

在大多数应用中,我看到有效的宽相算法减少了数量级所需的时间。但当然这取决于具体情况。

祝你好运。

答案 1 :(得分:2)

为了处理计算密集型模拟,应用程序通常将工作划分为两个域:图形引擎,包括JPanel的子类的#repaint();模拟引擎包含#move()和#detectCollision()方法。

模拟将在其自己的Thread中运行,使用SwingUtilities#invokeLater方法通过图形引擎更新可显示状态。模拟通常试图每秒实现一定数量的模拟滴答,在两者之间休眠。

通常,在本机AWT内部创建事件调度程序线程(EDT)以消化从底层窗口系统到达的事件。如果您以某种方式手动创建它,则表明您可能错误地使用了Swing或AWT。