如何在Java中制作固定的时间步长

时间:2016-09-28 13:33:13

标签: java game-loop

我们应该如何在Java中制作固定的时间步?我认为有两种方式:

  1. 使用while同步游戏循环。
  2. 使用Thread异步游戏循环。
  3. 最重要的是性能准确性。那么最好的方法是什么?

    这是同步游戏循环:

        double timeStep = world.getSettings().getStepFrequency();
        long lastTime = System.nanoTime();
    
        while (true) {
            long currentTime = System.nanoTime();
            double elapsedTime = (currentTime - lastTime) / 1000000000.0;
    
            if (elapsedTime >= timeStep) {
                lastTime = currentTime;
                world.update(elapsedTime);
            }
        }
    

    这是异步游戏循环:

        double timeStep = world.getSettings().getStepFrequency();
        long lastTime = System.nanoTime();
    
        Thread loop = new Thread() {
            public void run() {
                while (true) {
                    long currentTime = System.nanoTime();
                    double elapsedTime = (currentTime - lastTime) / 1000000000.0;
                    lastTime = currentTime;
    
                    world.update(elapsedTime);
    
                    try {
                        Thread.sleep((long) Math.floor(timeStep * 1000));
                    } catch (InterruptedException e) {}
                }
            }
        };
        loop.start();
    

    同步游戏循环使用大量CPU(我认为1核心?对我来说是25%左右)。

    异步游戏循环的CPU使用率几乎为0%。

    注意:我想要做的游戏是基于WebSocket的游戏。服务器用于物理,HTML5的画布用于渲染。

    您更喜欢哪种方式?为什么?还有更好的办法吗?

1 个答案:

答案 0 :(得分:4)

Java API中有一些类可以定期执行任务。最好不要尝试重新发明轮子并使用Java API。 ScheduledExecutorService似乎就是您所需要的。

此示例定期执行Runnable

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(myRunnable, initialDelay, period, TimeUnit.MILLISECONDS);

在第一个示例中,如果elapsedTime >= timeStep为真,则您的线程会检查很多次。它一直在做检查,直到它成立为止,而不是一次又一次地检查,直到它最终为真,线程可能正在等待,处理器可以用于其他东西。

第二个选项比第一个选项更好,因为线程等待下一个执行的时间段。