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

最佳答案

对于每个更新帧,您需要计算现在与上一次更新之间的时间(以秒为单位)。这需要是 float 或 double ,因为它可能只是一秒的一小部分。为此,您需要获取当前时间(以毫秒或纳秒为单位),减去之前的时间,然后转换为秒。

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

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

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

如果您需要更高的准确性,您将需要研究其他集成方法,例如 VerletRunge-Kutta

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

相关文章:

xml - 计算 Final Cut Pro X xml 序列持续时间

java - 计算 xsl :result-document in a given stylesheet 的所有出现次数

java - 二进制搜索树节点删除不删除替换 Java

f# - 在 F# 中展开嵌套循环

python - 在 pygame 物理模拟中添加 wxPython GUI 元素

image-processing - ffmpeg 忽略每个帧率选项,将结果锁定为 25 fps

iphone - UIScrollView滚动时帧率慢,为什么?

java - DDD结构示例

java - 无法使用 ksoap2 序列化日期

python-3.x - 在 Python 中加速 MSD 计算