帧率独立引力

时间:2012-12-24 17:19:26

标签: java frame-rate gravity delta

我遇到的问题是重力随着帧速率的变化而严重变化。当我以160 fps运行时,我的播放器在空中跳了几米然后跌落,但是在大约10 fps时,我的播放器跳了半米然后跌落。我的引力代码如下:

public void fall(long delta) {
    float increase = acceleration * ((delta) / 1000000000); //changes delta time (nanoseconds) to seconds
    if(player.y + velocity + increase < -1.15f) {
        if(velocity + inc < terminal_velocity) {
            velocity += inc;
        }
        player.y += velocity;
    }else{
        player.y = -1.15f;
        velocity = 0;
    }
}

我称之为:

while(!close_request) {
        now = getTime();
        int delta = getDelta(now);

        player.fall(delta);

        ........other functions.........

    }

我认为实施三角洲会让玩家不要太快或太慢地改变速度,但它实际上让它变得更糟。我认为这是因为随着帧之间的时间增加,速度的增加也会导致玩家异常快速下降。这是因为随着FPS的增加,玩家跳得更高,更高。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

你的问题在这一行:

player.y += velocity;

没有考虑 velocity 是“距离除以时间”。

你正确地建模加速:

v = u + a * t   // v = current velocity, a = acceleration, t = time

但不是距离,足够小的delta是:

delta_s = v * delta_t

在将velocity添加到该位置之前,您需要将delta乘以{{1}}。

答案 1 :(得分:2)

您没有正确建模物理。假设dt足够小,这将提供“足够好”的近似值。

curV     // current velocity
accel    // global acceleration constant
terminal // terminal velocity for object
dt       // delta time in seconds

fall(dt):
    deltaV = accel * dt                  // Change in velocity in a vacuum
    newV = curV + deltaV                 // New velocity 
    if (newV < terminal) newV = terminal // Don't exceed downwards terminal velocity
    y = y + dt * (curV+newV)/2           // New position
    curV = newV                          // Save new velocity as current

当你接近终极速度时,它忽略了加速度降低等事情的复杂性。这个和你的之间的最大区别是dt 两次出现,一次计算deltaV,然后再计算新的垂直位置。