2

Libgdx フレームワークでプラットフォーム ゲームを作成しています。キャラクターにジャンプ能力を実装したいです。私は単純な式を使用します:

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

うまく機能しますが、1 秒あたりのフレーム数が一定の場合のみです。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

4

1 に答える 1

6

これは、使用する非常に単純で非常に不正確な積分器を考えると、完全に正常な動作です。計算してそれを示すのはとても簡単です。

1/30 秒の 1 つのタイム スパンを取りましょう。ゲームが 30 FPS で実行される場合、speed_yとへの更新は 1 回だけであるyため、1/30 秒後に新しい位置y'は次のようになります。

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

これは1/30dt秒のタイム デルタです。

ゲームが 60 FPS で実行される場合、同じ 1/30 秒で 2 倍の短い時間デルタで 2 つの更新が発生します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 の場合よりも高くなります。

これは垂直方向の動きにのみ影響します。水平速度は一定で、2 倍の短い時間デルタで 1 回または 2 回更新しても問題ありません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に更新する必要があることに注意してください。

于 2013-01-11T14:03:54.203 に答える