java - 如何使时间独立于FPS?

原文 标签 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();
}

最佳答案

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

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

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


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

如果需要更高的准确性,则需要研究其他集成方法,例如Verlet或Runge-Kutta。

关于java - 如何使时间独立于FPS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26171586/

相关文章:

java - 字符串的Java类型类异常

java - 使用 Ant 进行 Jacoco 覆盖和报告任务

html5 - 如何解决提供极高FPS的webkitRequestAnimationFrame

android - Unity Render.TransparentGeometry性能问题

java - 使用输入列表获取实体对象列表:Spring Data JPA-Hibernate

java - strace: `dup2(A, B); close(B)` 有什么意义吗?

带有 OpenMP 的 C++ 在 N-Body Simulator 中给出 -not-a-numbers (nan)

Android 加速度计精度(惯性导航)

c++ - 用鼠标施加脉冲的问题

java - Java-在没有线程/计时器的情况下延迟事件