Libgdx,物理,加速和FPS

我在Libgdx框架中制作平台游戏。 我想实现跳到我的角色的能力。 我使用简单的公式:

speed += acceleration * delta_time r += speed * delta_time 

它运行良好,但仅适用于每秒恒定的帧数。 FPS越低,我的角色越低。 我不知道这种行为的原因是什么,跳跃的高度应该是相同的:/我的代码片段:

 delta_time=Gdx.graphics.getDeltaTime(); if(input.getUpArrow()){ if(is_in_air==false){ is_in_air=true; speed_y=speed_y_0; } } if(is_in_air==true){ speed_y-=acceleration*delta_time; } else{ speed_y=0; } x+=speed_x*delta_time; y+=speed_y*delta_time; 

这里有一个插图(黑点是字符位置): http : //i.imgur.com/tfSTM.jpg

鉴于您使用的非常简单且高度不准确的积分器,这是完全正常的行为。 这很容易做数学并显示出来。

让我们花费1/30秒的单个时间跨度。 当游戏以30 FPS运行时, speed_yy只会有一次更新,所以在1/30秒后,新位置y'将是:

 speed_y' = speed_y - a*dt y' = y + speed_y'*dt = y + speed_y*dt - a*dt^2 

这里dt是1/30秒的时间差。

当游戏以60 FPS运行时,在相同的1/30秒内将发生两次更新,其中时间增量为两倍, dt/2

 // First update speed_y' = speed_y - a*(dt/2) y' = y + speed_y'*(dt/2) = y + speed_y*(dt/2) - a*(dt/2)^2 // Second update speed_y'' = speed_y' - a*(dt/2) = speed_y - a*dt y'' = y' + speed_y''*(dt/2) = y + speed_y*dt - 3*a*(dt/2)^2 

现在比较两个更新的y位置:

  • 在30 FPS时,它是: y + speed_y*dt - a*dt^2
  • 在60 FPS时,它是: y + speed_y*dt - a*(3/4)*dt^2

显然,在60 FPS时, y的新位置将高于30 FPS,因为减去的值较低。

这仅影响垂直运动。 水平速度是恒定的,如果你用两倍于短时间的三角形更新x一次或两次并不重要,因此当你的角色跳跃它总是沿着相同的水平距离行进到它撞击地面的地方,无论是什么FPS。

要解决这个问题,你必须仔细研究恒定加速度下的运动方程:

 y(t) = y(t=0) + v(t=0)*t - (1/2)*a*t^2 

t=0的选择是任意的,因为物理定律在时移下是不变的,因此可以将t=0作为更新间隔的开始,然后t=delta_time将给出当前更新之后的位置。 正确的更新算法如下:

 x += speed_x*delta_time; if (is_in_air) { y += (speed_y - 0.5*acceleration*delta_time)*delta_time; speed_y -= acceleration*delta_time; } 

请注意,应根据运动方程中的值在垂直位置之后更新speed_y