为什么我的跳跃算法不能独立于 FPS 工作



我正在尝试实现一个简单的跳跃算法,它应该是独立于FPS的。不幸的是,玩家以 1-5 FPS 的速度跳跃 1.6-1.9 个方块,但在 1.2 FPS 时跳跃 60 个方块。

首先,加速度降低GRAVITY * time for the last frame .如果 y 位置小于 0.15,则玩家开始新的跳跃(yAcceleration设置为 JUMP_POWER (。

private static final float GRAVITY = 9;
private static final float JUMP_POWER = 4.4f; 
private static final float TOLERANCE = 0.15f;

private float yAccleration;
private float positionY;
//delta is in seconds
private void update(float delta) {
    yAccleration -= GRAVITY * delta;

    if(positionY <= TOLERANCE) {
        yAccleration = JUMP_POWER;
    } 

    float newYPosition = positionY + yAccleration * delta;
    if(newYPosition > 0) positionY = newYPosition;
}

这是我在测试示例中用来调用update()的代码:

final float fps = 60;
final float deltaSeconds = 1f / fps;
while(true) {
    update(deltaSeconds);
    Thread.sleep((int) Math.round(deltaSeconds * 1000));
} 

为了使我的算法独立于 FPS,我必须更改什么?

final float fps = 60;
final float deltaSeconds = 1f / fps;

当我读到这篇文章时,它马上就是"WTF"。您不能假设增量将是 1/60 秒。而且,不会!

1/60 秒只是您的等待时间。计算呢?实际获取当前时间所需的时间如何?重绘时间呢?一切都很重要!

使用固定的虚幻增量,只需计算每次迭代的实际时间。

final float fps = 60;
final float deltaSeconds = 1f / fps;
float t0=System.currentMilisecond();
while(true) {
    float t=Sytem.currentMiliseconds();
    float delta=t-t0;
    t0=t;
    update(delta);
    Thread.sleep((int) Math.round(deltaSeconds * 1000));
} 

您可以尝试强制帧速率,但始终必须计算实际时差。

最新更新