【问题标题】:Java Swing 'game loop' best practicesJava Swing“游戏循环”最佳实践
【发布时间】:2015-04-15 17:53:19
【问题描述】:

为了清楚起见,我正在寻找在 Java 中实现“游戏循环”的最佳替代方案(使用 Swing)。

目前,我正在使用以下设置,并在 JPanel 类中覆盖 paintComponent() 来绘制类似这样的内容:

public void run() {
    while (running) {
        panel.update();
        panel.repaint();
        try {
            sleep(SLEEP_TIME);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

此设置似乎运行良好,但移动的形状和图像有时似乎会卡顿一两个像素。换句话说,运动并不像我希望的那样流畅。

我想知道是否有一种方法可以更有效地进行游戏循环,即避免在运动中出现卡顿?

【问题讨论】:

  • 固定循环率。
  • 我该怎么做?
  • SLEEP_TIME 的值是多少? Swing 通常可以实现非常高的帧速率。口吃可能是由于您的程序的某种编写方式而您提供的小样本不足以确定问题。见stackoverflow.com/help/mcve
  • SLEEP_TIME 的值为 16。
  • 绘制图形时,是否使用了某种并发锁,以便在更新形状时无法进行绘制?否则,如果您绘制一些新外观仅更新一半的形状,它们很容易出现卡顿。

标签: java swing loops


【解决方案1】:

一个固定循环率的简单方法是使用ScheduledExecutorService。

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(() -> {
    panel.update();
    panel.repaint();
}, 0, 16, TimeUnit.MILLISECONDS);

另一种方法是通过根据进程使用的时间计算睡眠时间来自己完成。

public void run() {
    long time = System.currentTimeMillis();
    while (running) {
        panel.update();
        panel.repaint();
        long sleep = 16 - (System.currentTimeMillis() - time);
        time += 16;
        try {
            sleep(sleep);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    相关资源
    最近更新 更多