【问题标题】:Java 2D Game: The game loopJava 2D 游戏:游戏循环
【发布时间】:2014-01-21 05:06:20
【问题描述】:

我有一个简单的 Java 2D 游戏。屏幕上的字符是使用键绑定控制的。 该游戏使用扩展 JPanel 的类来显示图形并包含大部分游戏逻辑。这个类的名字是Board

对于游戏每 40 毫秒我应该使用什么类型的游戏循环并 repaint() Board

选项 A:

Board 包含在程序启动时启动的线程。该线程包含一个循环,该循环每 40 毫秒更新一次游戏并 repaints() Board。

选项 B:

Board 创建了一个 Swing 计时器。此计时器的动作侦听器是 Board 本身。 actionPerformed() 方法每 40 毫秒运行一次并更新游戏 + 重绘 Board()。

换句话说,在带有键绑定的 2D 游戏中,游戏循环哪个更好,为什么 - Swing 计时器或内部带有循环的线程?

谢谢

【问题讨论】:

    标签: java multithreading swing key-bindings


    【解决方案1】:

    如果屏幕上唯一移动的东西是按键控制的角色(使用keyBindings),我相信只有在角色移动时才能成功重绘屏幕,所以移动方法可以在最后调用repaint。我自己尝试了一些简单的项目,效果很好。只是每个移动的对象在移动后都会调用 repaint。

    在其中一个项目(非常简单的一个)中,我为 keyBinding 在 actionPerformed 中调用了 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();
            }
        }
    } 
    

    【讨论】:

    • 这很便宜,但这里没有游戏循环。就像您正在重新绘制组件一样。他说 40 毫秒,每循环 25fps。
    【解决方案2】:

    使用两个线程,一个用于重新绘制,一个或多个用于对象的运动。不知道为什么需要在它们之间进行同步,它们可以独立工作。

    【讨论】:

      【解决方案3】:

      如果处理速度很快,并且您的更改涉及与 Swing 的更多交互而不仅仅是repaint(),那么SwingTimer 将是合适的,因为您已经在正确的线程上。

      原因:SwingTimer 很快,您不需要线程切换来更新 Swing - 但是在您处理时 UI 会冻结,因此如果您需要任何时间玩家会注意到。

      如果处理可能需要一些时间并且您需要 Swing 交互,请使用SwingWorker

      原因:Swing 工作线程被设置为为您处理 Swing 和工作线程之间来回传递的消息。

      否则,请使用 ScheduledExecutorServicescheduleAtFixedRate(这意味着您每 40 毫秒被调用一次,即使您的处理需要 0、5、10 或 20 毫秒)。从 EDT 之外调用 repaint() 方法是安全的。

      原因:ScheduledExecutorService 是在 Java 中调度要执行的任务的标准方式。它处理一次关闭和重复执行,即使您的执行时间不同(只要您不花费超过 40 毫秒),它也会使您的更新保持一致的节奏。您可以从任何线程调用repaint(),因此您无需担心额外的线程同步问题。

      附带说明一下,这种架构对于简单的游戏来说很好,但您应该考虑到在更复杂的游戏中更新可能需要超过 40 毫秒的时间,并想办法进行补偿。

      【讨论】:

      • +1 用于 Swing Timer,The repaint() method is safe to call from off the EDT. 在 Java7 中不可能为真,因为已删除所有对
      • 我没有意识到这一点。你有这个官方参考的链接吗?我刚刚尝试使用谷歌搜索并进行了一些讨论,但没有具体内容。
      • 是的,你可以比较(开始)JTextComponents.append/setText ...这里提到了几次
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      相关资源
      最近更新 更多