我想创建一个基于速​​度的运动的二维游戏。正如当前的代码一样,我正在使用增量时间来使帧率之间的速度变化保持一致。但是,在144hz显示器上运行时,在跳跃时,每次跳跃的跳跃高度会略有不同(最大相差约3个像素,最大高度约为104像素),但是当我切换到60hz时,跳跃高度会立即增加平均约5像素,最大高度约109像素。

我曾尝试过用增量时间归一化哪些值的许多不同变体,但我总是回到最接近我想要的输出的那个值。

static bool grounded = false;

if (!grounded) {
    velocity.y += (5000.0f * deltaTime);   //gravity
}

if (keys[SPACE_INPUT]) {       //jump command
    if (grounded) {
        position.y = 750;
        velocity.y = -1000.0f;
        grounded = false;
    }
}

//Used to measure the max height of the jump
static float maxheight = position.y;

if (position.y < maxheight) {
    maxheight = position.y;
    std::cout << maxheight << std::endl;
}

//if at the top of the screen
if (position.y + (velocity.y * deltaTime) < 0) {
    position.y = 0;
    velocity.y = 0;
    grounded = false;

//if at the bottom of the screen minus sprite height
} else if (position.y + (velocity.y * deltaTime) >= 800.0f - size.y) {
    position.y = 800 - size.y;
    velocity.y = 0;
    grounded = true;

//if inside the screen
} else {
    grounded = false;
    position.y += (velocity.y * deltaTime);
}

我希望结果是,无论刷新速率如何,每次每次精灵都会向上移动相同的高度,但是即使在相同的刷新速率下,尤其是在不同速率之间,它也会向上移动不同的量。

最佳答案

公认的技术如下:

// this is in your mainloop, somewhere
const int smallStep = 10;

// deltaTime is a member or global, or anything that retains its value.
deltaTime += (time elapsed since last frame); // the += is important

while(deltaTime > smallStep)
{
    RunPhysicsForTenMillis();
    deltaTime -= smallStep;
}

基本上,您要做的是:每次运行物理学时,都要处理给定数量的步长(例如10毫秒),这些步长总计等于帧之间的时间。
runPhysicsForTenMillis()函数的作用与您上面的相似,但是要保持恒定的增量时间(我的建议是10毫秒)。

这给您:
  • 确定性。不管您的FPS是多少,物理过程始终会以相同的精确步骤运行。
  • 鲁棒性。如果您有较长的磁盘访问权限,某些流传输延迟或使帧更长的事件,则该事件将使您的对象不会跳入外层空间。
  • 在线播放准备就绪。一旦您进入在线多人游戏,就必须选择一种方法。对于诸如输入传递之类的许多技术,这些小步骤将很容易实现在线。
  • 10-08 12:41