我们应该如何在Java中制作固定的时间步?我认为有两种方式:
while
同步游戏循环。Thread
异步游戏循环。最重要的是性能和准确性。那么最好的方法是什么?
这是同步游戏循环:
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的画布用于渲染。
您更喜欢哪种方式?为什么?还有更好的办法吗?
答案 0 :(得分:4)
Java API中有一些类可以定期执行任务。最好不要尝试重新发明轮子并使用Java API。 ScheduledExecutorService似乎就是您所需要的。
此示例定期执行Runnable
:
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(myRunnable, initialDelay, period, TimeUnit.MILLISECONDS);
在第一个示例中,如果elapsedTime >= timeStep
为真,则您的线程会检查很多次。它一直在做检查,直到它成立为止,而不是一次又一次地检查,直到它最终为真,线程可能正在等待,处理器可以用于其他东西。
第二个选项比第一个选项更好,因为线程等待下一个执行的时间段。