3

我已经多次看过这段代码。

long lastTime = System.nanoTime();
final double ticks = 60D;
double ns = 1000000000 / ticks;    
double delta = 0;

上面的代码占用系统时间并将其存储到lastTime. 60 个滴答应等于每秒更新的次数。

while(running){
    long now = System.nanoTime();
    delta += (now - lastTime) / ns;
    lastTime = now;
    if(delta >= 1){
        tick();
        delta--;
    }

它需要now并减去lastTime,然后将其转换为纳秒/60。是否有一些保证,超过 60nowlastTime到 nano 之间的时间差会导致 delta 大于或等于每秒 1、60 次?我不明白为什么tick();每秒会运行大约 60 次。根据我的计算,每次循环运行 delta 都会增加 0.0025 左右。

4

3 回答 3

2

我已经对代码进行了一些注释,以便更清楚地向您展示正在发生的事情。

//Get the system time
long lastTime = System.nanoTime();
//Specify how many seconds there are in a minute as a double
//store as a double cause 60 sec in nanosec is big and store as final so it can't be changed
final double ticks = 60D;
//Set definition of how many ticks per 1000000000 ns or 1 sec
double ns = 1000000000 / ticks;    
double delta = 0;

while(running){
//Update the time
    long now = System.nanoTime();
//calculate change in time since last known time
    delta += (now - lastTime) / ns;
//update last known time    
    lastTime = now;
    //continue while delta is less than or equal to 1
    if(delta >= 1){
//Go through one tick        
        tick();
//decrement delta
        delta--;
    }

现在我很确定这就是它的作用,但我不能肯定地说没有看到 tick() 是什么

于 2014-11-10T07:07:26.437 回答
2

它确保 tick() 方法每秒只执行 60 次。它被称为增量计时,并在整个游戏社区中被引用。使用增量计时的原因是为了让游戏在所有平台上以相同的速率运行。无论系统的速度如何,游戏中的物理和动画之类的东西都需要以相同的速度运行。如果您的系统较慢且游戏不包含增量计时,则物理运行速度会比游戏在快速系统上运行时慢。

这个怎么运作

  • 弄清楚你每秒要更新多少次,在你的情况下是每秒 60 次。

  • 找到内置时间函数的语言的分辨率。您的代码使用 Java 内置的 System.nanotime() 函数,该函数返回系统运行的纳秒数的长值。

  • 一秒钟有 1000000000 纳秒,这意味着每次调用 tick() 的时间差等于 1000000000/60。大约是 16666666 纳秒。这意味着每当调用tick() 时,程序将在再次调用tick() 之前等待16666666 纳秒。

  • 您必须做的是找到当前帧和最后一帧之间的时间(以纳秒为单位)。该值除以时间步长 (16666666) 将为您提供已过去多少必要时间的小数百分比。如果将此十进制百分比添加到 delta 变量,当 delta 变量 >= 1 时,已经过了 1/60 秒,这意味着程序现在可以调用 tick()。

  • 最后你从 delta 变量中减去 1。您不将 delta 变量设置为 0 的原因是因为可能存在比 1 更大的时间步长,并且 delta 变量将高于 1,这意味着您需要在下次循环并调用时考虑到这一点打钩()

于 2015-01-10T18:45:01.597 回答
1

在不知道里面有什么的情况下tick(),我不能确定,但​​我猜它也用于60D尝试睡眠大约正确的时间?所以:不,没有保证,这就是这段代码要解决的问题。

它的意思是“如果tick()睡的时间少于一个滴答声,那么什么也不做;如果它睡了一个滴答声或更多,那么滴答一次”。

据推测,如果滴答声超过了足够的时间(例如 80ns 然后 80ns,这意味着第一个循环增加滴答声,第二个循环增加 2 个),那么最终将有另一个只有 40ns 增量的循环,导致一切都变平。

于 2014-11-10T07:09:13.527 回答