与Util计时器相比,使用游戏循环有什么优势

  • 本文关键字:循环 游戏 计时器 Util java
  • 更新时间 :
  • 英文 :


我想每秒运行一个函数60次。我更喜欢使用Util计时器,我认为这是一种非常简单的方法

int second = 1000;
int fpsLimit = 60;
Timer timer = new Timer();
TimerTask task = new TimerTask(){
public void run(){
//
}
}


timer.scheduleAtFixedRate(task, 0, second / fpsLimit);`

但我看到很多人使用游戏循环,这种循环要长得多,也更复杂。

long lastime = System.nanoTime();
double AmountOfTicks = 30;
double ns = 1000000000 / AmountOfTicks;
double delta = 0;
int frames = 0;
double time = System.currentTimeMillis();

while(isRunning == true) {
long now = System.nanoTime();
delta += (now - lastime) / ns;
lastime = now;

if(delta >= 1) {
Update();
Render();
frames++;
delta--;
if(System.currentTimeMillis() - time >= 1000) {
System.out.println("fps:" + frames);
time += 1000;
frames = 0;
}
}
}

抱歉,既然我真的不了解游戏循环,那么除了跟踪fps之外,使用它们还有什么好处吗?

游戏循环可能会以最快的速度运行,也可能有速率限制。您的示例似乎有速率限制,但它是一个繁忙的等待循环。它以最快的速度重新计算delta,然后在delta达到某个值时调用UpdateRender。这是低效的。

Timer有点像你的游戏循环,但更复杂。查看源代码,特别是TimerThread类及其mainLoop方法。线程在任务队列上等待,直到下一个计划任务的时间。插入任务后,线程将唤醒,执行所有到期任务,然后再次等待,直到下一个任务到期。

游戏循环在许多书籍和教程中都是作为一个概念引入的,但很少或根本没有理由自己编写游戏循环。在实践中,主循环通常由您使用的任何UI或游戏引擎框架为您提供。如果没有,像Timer这样的东西可能会很好地工作,省去你自己写的麻烦。

答案可能可以用一个词来概括:准确性

计时器通常使用Thread.sleep或其他类似的方法,使一个线程进入睡眠状态,然后在时间流逝时将其唤醒。

它是有效的,但分辨率通常不会超过几十毫秒。同样,我们可以说延迟是向上取整的,或者线程的睡眠时间可能比指定的稍长,或者计时器在两次调用之间等待的时间可能不完全相同。这意味着基本相同的事情。

当然,对于运行游戏并正确渲染来说,这太不准确了。需要精确计算需要等待的时间,并指定以纳秒为单位的目标延迟。

最新更新