如何让时间独立于FPS?

时间:2014-10-03 00:19:41

标签: java physics frame-rate

我有一个程序,每帧运行tick()方法。我希望一个物体根据设定的重力常数下降,所以我创建了一个Ball物体,它将其位置更新为前一帧的位置减去y速度。 y速度将通过每个滴答的重力常数减小。但是下跌太快了,因为蜱不会直接转化为秒。我想我错过了一些基本的数学,但我正在处理这么多变量,我看不出它是什么。

编辑:添加了代码

@Override
public void run(){
    init();

    long lastTime=System.nanoTime(), timer=System.currentTimeMillis();
    final double ticks=60.0;
    double ns=1000000000/ticks, delta=0;
    int updates=0, frames=0;

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

        if(delta>=1){
            tick();
            updates++;
            delta--;
        }

        render();
        frames++;

        if((System.currentTimeMillis()-timer)>1000){
             timer+=1000;
             System.out.println(updates+" ticks, FPS "+frames);
             frame.setTitle("Ball -- "+SCALEWIDTH+"x"+SCALEHEIGHT+" at "+frames+" FPS");
             updates=0;
             frames=0;
        }
    }
    stop();
}

1 个答案:

答案 0 :(得分:2)

对于每个更新框架,您需要计算从现在到上一次更新之间的时间(以秒为单位)。这将需要是浮点数或双倍,因为它可能只是一小部分。为此,您将获得当前时间(以毫秒或纳秒为单位),减去上一次,然后转换为秒。

然后,您可以使用名为数字积分的过程来计算新的位置和速度。这意味着通过基于来自前一帧的计算和它们之间的时间计算当前帧中的位置和速度来找到运动方程的近似。这看起来像:

position += velocity * dt;
velocity += acceleration * dt;

其中dt是以秒为单位的帧之间的时间。这种用于积分位置和速度的特殊方法称为 Euler方法。这种方法很简单,它可能适用于您的应用程序,但是当速度或加速度不恒定时,它会开始变得不准确。这是因为计算的值是曲线的近似值。

如果您需要更高的准确度,您需要查看其他集成方法,例如 Verlet Runge-Kutta