Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java GameLoop fps控制器_Java_Game Engine - Fatal编程技术网

Java GameLoop fps控制器

Java GameLoop fps控制器,java,game-engine,Java,Game Engine,我一直在关注youtube上关于如何使用java创建2d游戏的系列文章,我似乎无法理解这段代码是如何工作的,如果有人能详细说明这段代码是如何工作的,我将不胜感激 public void run() { long lastTime = System.nanoTime(); final double clock = 1000000000.0 / 60.0; double delta = 0; while (running) { long now =

我一直在关注youtube上关于如何使用java创建2d游戏的系列文章,我似乎无法理解这段代码是如何工作的,如果有人能详细说明这段代码是如何工作的,我将不胜感激

public void run() {
    long lastTime = System.nanoTime();
    final double clock = 1000000000.0 / 60.0;
    double delta = 0;

    while (running) {
        long now = System.nanoTime();
        delta +=(now - lastTime) / clock;
        System.out.println(now-lastTime);
        lastTime = now;

        while (delta >= 1){
            update();
            delta--;
        }
        render();
    }
}
我从这段代码中了解到的是,时钟变量包含了如果我们的游戏每秒运行60帧,那么一帧应该花费多少时间,但我似乎无法理解现在的lastTime变量,因为它们似乎一直在变化,但我们在循环的每一次执行中都获得了相同的时间,因此获得60 fps。 我理解循环的目的,但我实际上不理解的是它是如何在数学上归结为delta>=1每秒发生60次。

编辑。 基本上,该代码首先计算每1/60秒的纳秒数,然后使用它将增量转换为标准化值。不过,这是一种令人困惑的做法

这可能更容易考虑:

double nano = 1000000000.0;
double updateIntervalInSec =  1 / 60.0;
double delta = 0;

delta += (now-lastTime) / nano;//convert nano to seconds here

while(delta >= updateIntervalInSec)
{
  delta -= updateIntervalInSec;
}
更早的回答;可能对某人有用

这种类型的游戏循环旨在解决几个问题

  • 使更新速率独立于渲染速率
  • 使每次更新的时间增量为常量
  • 对于速度慢或可能速度慢的计算机来说,第一个考虑因素很重要;即使你不能足够快地显示更新,游戏也应该(通常)以正常速度更新

    第二个考虑因素对于物理游戏很重要;用可变的时间间隔/增量更新物理系统会使物理不愉快

    现在开始实施

    //run this loop as fast as possible
    while (running) { 
        long now = System.nanoTime();
    
        //delta is to collect up the amount of time since the last loop and put it
        //into our bucket of time
        delta +=(now - lastTime) / clock;
    
    
        System.out.println(now-lastTime);
        lastTime = now;
    
        //if we have accumulated enough time to meet the minimum requirements for an update, then run one update, and remove one increment of time from our bucket of available time.
        //but what if we have more time left in the delta bucket?   We need to keep doing updates until we've used up all the available time.
        while (delta >= 1){
        //update requires 1 time
            update();
            delta--;
        }
        //now that we've made sure all the updates are up to date, we can render
        //note that render happens no matter if 10 updates, or 0 updates were just run
        render();
    }
    
    考虑到这一点;它消除了在快速和慢速计算机上观察应用程序时可能出现的任何视觉速度差异


    逻辑是这样的:

    我们指定每一帧应该有多少纳秒。这是
    100000000/60
    :1b是纳秒,60是多少帧(你可能知道)

    以下是我的计算机在最后一次打印
    时的一些结果,即每帧之间经过的纳秒数:

    7270.0
    2566.0
    4704.0
    4276.0
    
    我们的想法是将所有结果相加,直到达到16m~nano秒。一旦你达到16m,是时候更新了。实际上,您可以这样做:

    double timePerFrame = 1000000000/60; //16m
    long last = System.nanoTime();
    while(true) {
        long now = System.nanoTime();
        double elapsedTime = now - last;
    
        delta += elapsedTime;
        last = now;
    
        if(delta >= timePerFrame) {
            update();
            delta = 0;
        }
    }
    

    相反,条件是
    delta>=1
    ,其中
    1
    表示“一帧”。将经过的时间除以更新前应该经过的时间,可以得到当前帧的进度百分比。不是每个循环都是一个帧,而是每次
    delta>=1
    都经过一个帧
    delta
    表示当前通过该帧的进度。

    时钟速度基本上就是每秒可以出现的纳秒数。
    最终双时钟=100000000.0/60.0
    只是在一秒钟内返回1/60纳秒数

    下一个有趣的部分是计算delta变量(当它大于或等于1时,意味着我们需要再次绘制,因为至少已经过了1/60秒)

    他们通过
    now-lastTime
    来获得现在和上次循环运行之间的纳秒差。然后我们将这个数字除以时钟速度(1/60秒)

    现在,delta只是显示自上次执行循环以来已过了多少1/60秒

    然后我们检查是否至少过了1/60秒,如果过了,我们会更新游戏并减少增量(因为我们做了1帧/我们做了1/60秒)

    循环会不断更新,因此每过1/60秒就会抽签,从而基本上迫使游戏以60帧/秒的速度运行(从技术上讲,这可能不是真的)

    希望这有点道理。我不太擅长解释事情

    编辑

    我只是想澄清一下。Delta只是已经过去的1/60秒数。所以delta可以是60(表示1秒过去了,或者360表示6秒过去了,或者其他数字)。
    while(delta>=1)
    将一直运行,直到delta返回到0。所以,如果增量足够大,更新可以连续运行300次


    如果
    update()
    以某种方式阻塞,则delta可能高于1(这意味着update()的执行时间超过了1/60秒)。

    感谢您的解释,我想我忘了提到我实际上理解了为什么使用这个游戏循环以及它的作用,我实际上不明白的是,用数学术语来说,它实际上是如何计算帧的,例如,它将一个循环的时间加到delta上,然后除以1/60秒,为什么当你检查delta>=1时,一帧的时间就足够了呢?谢谢你的解释,但我不明白的是,当你除以一帧的时间,除以一帧实际需要的时间,你就能得到这样的效果,为什么delta>=1在数学上每秒只发生60次。@FilipBog请查看我的编辑。如果您需要更深入地了解任何内容,请告诉我哦,谢谢您,现在我终于按照您解释的方式理解了,我是这样想的,但我没有想到%转换,现在我很清楚,我想我还有很长的路要走,谢谢您花时间向我解释。@FilipBog没问题!别忘了点击复选标记将此答案标记为“已接受答案:)谢谢你的解释,它非常有用。