我用Java编写了一个简单的2D游戏。使用Key Bindings控制屏幕上的chararcters。
游戏使用扩展JPanel的类来显示图形并包含大部分游戏逻辑。这个班级的名字是Board
。
我应该在每40毫秒游戏中使用什么类型的游戏循环并重新编辑()Board
?
选项A:
Board
包含一个在程序启动时启动的线程。该线程包含一个循环,在40毫秒内更新游戏并重新绘制()Board。
选项B:
Board创建一个Swing计时器。此计时器的动作监听器是Board本身。 actionPerformed()方法每40毫秒运行一次并更新游戏+重绘Board()。
换句话说,在带有键绑定的2D游戏中,游戏循环和为什么更好 - Swing计时器或其中有循环的线程?
由于
答案 0 :(得分:2)
如果处理速度很快且您的更改涉及与Swing的更多互动,而不仅仅是repaint()
,那么SwingTimer
将是合适的,因为您已经在正确的帖子上。
理由:SwingTimer很快,你不需要线程切换来更新Swing - 但你在处理时会冻结UI,所以如果你需要任何时间玩家会注意到。
如果处理可能需要一些时间而您需要Swing交互,请使用SwingWorker
。
理由:设置Swing worker来处理在Swing和工作线程之间来回传递消息。
否则使用ScheduledExecutorService
和scheduleAtFixedRate
(这意味着即使你的处理需要0,5,10或20ms,你也会每40ms调用一次)。可以安全地从美国东部时间拨打repaint()
方法。
原因:ScheduledExecutorService
是调度要在Java中执行的任务的标准方法。它处理一次性和重复执行,即使您的执行时间不同(只要您不超过40毫秒),它也会保持您的更新始终如一。您可以从任何线程调用repaint()
,因此您无需担心额外的线程同步。
作为旁注,这种架构适用于简单的游戏,但你应该考虑在更复杂的游戏中,更新可能需要超过40毫秒,并想办法补偿。
答案 1 :(得分:0)
使用两个线程进行重新绘制,使用一个或多个线程进行对象的运动。不确定为什么你需要在它们之间进行同步,它们可以独立工作。
答案 2 :(得分:0)
如果屏幕上唯一的移动内容是由键控制的字符(使用keyBindings),我相信只有在移动一个字符时才能成功重绘屏幕,因此移动方法可以在最后调用重绘。我自己尝试了一些简单的项目,并且工作正常。只有每一个移动物体在移动后都会重新调用它。
在其中一个项目中(非常简单)我在actionPerformed中为keyBinding调用了repaint,它看起来像这样:
class Right extends AbstractAction{
@Override
public void actionPerformed(ActionEvent e){
if (board.character.x < 465){ //check if not trying to move off the screen.
board.character.x += 7;
board.repaint();
}
}
}