(增量时间)在java中每秒获得60次更新

(增量时间)在java中每秒获得60次更新,java,time,delta,nanotime,Java,Time,Delta,Nanotime,这个代码我已经看过好几次了 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

这个代码我已经看过好几次了

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--;
    }

它现在使用
并减去
最后一次
,然后将其转换为纳秒/60。是否可以保证
now
lastTime
之间的时间差超过60秒会导致delta大于或等于每秒160次?我不明白为什么
tick()将每秒运行约60次。根据我每次循环运行时的计算,增量增加了0.0025左右。

我对代码进行了一些注释,以便更清楚地向您展示发生了什么

//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()

如果不知道什么在
tick()
,我不能肯定,但我猜它也使用
60D
来尝试睡眠大约正确的时间?所以:不,没有保证,这就是这段代码要修复的

它的意思是“如果
tick()
睡眠时间少于一个滴答声,那么什么都不要做;如果它睡了一个滴答声或多个滴答声,就只打一次”

假设,如果滴答声持续时间足够长(例如,80ns然后80ns,这意味着第一个循环增加滴答声,第二个循环增加2),那么最终将出现另一个循环,该循环只有40ns的增量,导致所有内容都趋于平衡。

它确保滴答()方法每秒只执行60次。它被称为delta计时,在整个游戏社区都有引用。之所以使用增量计时,是为了让游戏在所有平台上以相同的速度运行。游戏中的物理和动画等东西需要以相同的速度运行,而不管系统的速度如何。如果你有一个缓慢的系统,而游戏不包括增量计时,那么物理运行速度会比游戏在快速系统上运行时慢

它的工作原理

  • 计算出每秒要更新多少次,在您的情况下是每秒60次

  • while(running){
        long now = System.nanoTime();
        delta += (now - lastTime) / ns;
        lastTime = now;
        if(delta >= 1){
            tick();
            delta--;
        }
    
  • 查找内置时间函数的语言分辨率。您的代码使用Java内置的System.nanotime()函数,该函数返回系统已运行纳秒数的长值

  • 每秒有100000000纳秒,这意味着每次调用tick()的时间差等于100000000/60。大约是166666纳秒。这意味着每当调用tick()时,程序将等待16666666纳秒,然后再次调用tick()

  • 您必须做的是以纳秒为单位查找当前帧和最后一帧之间的时间。这个值除以timestep(16666666)将得到所需时间的小数百分比。如果将此小数百分比添加到增量变量,当增量变量>=1时,1/60秒已经过去,这意味着程序现在可以调用tick()

  • 最后从delta变量中减去1。您不将delta变量设置为0的原因是,时间步长可能大于1,而delta变量将大于1,这意味着您需要在下次循环并调用tick()时对此进行说明