简体   繁体   English

如何使时间独立于FPS?

[英]How do I make time independent of the FPS?

I have a program which runs the tick() method every frame. 我有一个程序,每帧运行tick()方法。 I want an object to fall according to a set gravity constant, so I created a Ball object which will update its position to the position on the previous frame minus the y velocity. 我希望对象根据设置的重力常数落下,因此创建了一个Ball对象,该对象将其位置更新为前一帧的位置减去y速度。 The y velocity will decrease by the gravity constant each tick. y速度将在每个刻度时减小重力常数。 But the fall is far too rapid because the ticks do not directly translate to seconds. 但是下降太快了,因为刻度不会直接转换为秒。 I think I'm missing some basic math but I'm juggling so many variables I can't see what it is. 我想我缺少一些基本的数学运算,但是我在处理这么多变量,所以看不到它是什么。

EDIT: Added code 编辑:添加代码

@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();
}

For each update frame, you will need to compute the time in seconds between now and the previous update. 对于每个更新帧,您将需要计算从现在到上一次更新之间的时间(以秒为单位)。 This will need to be a float or double since it will likely be a fraction of a second. 这将需要是浮点数或两倍,因为可能只需要几分之一秒。 To do this, you get the current time in milliseconds or nanoseconds, subtract the previous time, and convert to seconds. 为此,您可以获取当前时间(以毫秒或纳秒为单位),减去前一个时间,然后转换为秒。

You can then use a process called numerical integration to compute the new position and velocity. 然后,您可以使用称为数值积分的过程来计算新的位置和速度。 This means finding an approximation to the equations of motion by computing the position and velocity in the current frame based on computations from the previous frame and the time between them. 这意味着根据前一帧的计算结果和它们之间的时间,通过计算当前帧中的位置和速度来找到运动方程的近似值。 This looks something like: 看起来像这样:

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

where dt is the time between frames in seconds. 其中dt是帧之间的时间(以秒为单位)。 This particular method for integrating position and velocity is called the Euler Method . 这种将位置和速度积分的特殊方法称为Euler方法 This method is easy and it might work just fine for your application, but it starts to become inaccurate over time when velocity or acceleration is not constant. 这种方法很简单,对您的应用程序可能效果很好,但是当速度或加速度不恒定时,随着时间的流逝,它就会变得不准确。 This is because the values being calculated are an approximation to a curve. 这是因为正在计算的值是曲线的近似值。

If you need more accuracy, you will want to look into other integration methods like Verlet or Runge-Kutta . 如果需要更高的准确性,则需要研究其他集成方法,例如VerletRunge-Kutta

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM