あなたが正しいです。フレームレートが異なる場合、時間ステップが異なりますので、加速レートは予測できません。このため、多くのゲームでは、ゲームのフレームレートとは別に実行される固定タイムステップが使用されます。これは、すべてのデバイスでまったく同じようにゲームが確実に行われるようにする方法です。
これはシンプルで競争力の高いゲームでなければ、必ずしも正確であることを確認するだけで、必ずしも確定的である必要はありません。その場合、私の意見では、ちょっと騙されて、固定タイムステップの代わりに最大タイムステップを使用することができます。ゲームはいつも全く同じように再生されませんが、誰も気付かないほど正確です。これを行うには、最大デルタ時間を設定します。ゲームの各フレームで、すべてのデルタ時間が使い果たされるまで繰り返し更新を呼び出しますが、合計デルタ時間はまだ正確です。たとえば:
public static final float MAX_DELTA = 1/50f;
public static final int MAX_UPDATES_PER_FRAME = 3;
private float elapsedTime;
public void render (float deltaTime){
elapsedTime += deltaTime;
int updates = 0;
while (elapsedTime > 0 && updates < MAX_UPDATES_PER_FRAME){
update(Math.min(MAX_DELTA, elapsedTime));
elapsedTime = Math.max(0, elapsedTime - MAX_DELTA);
updates++;
}
// drawing
}
だから何が起こっていることはMAX_DELTA
以下の時間ステップを使用して、現在の時間に追いついたまであなたが繰り返し物理学を更新し、whileループです。 MAX_DELTA
が物理的に正しく見えるように十分小さく、薄い壁をトンネルできないようにする必要があります。 MAX_UPDATES_PER_FRAME
変数は、デルタ時間が長すぎるCPUスパイクがある場合に、「死のスパイラル」を入力しないようにするためのものです。代わりに、あなたのゲームはそれが追いつくまで少し遅いモモに入ります。
固定時間ステップ(famously explained here)より簡単な理由は、レンダリングのために2つのシミュレーションを保存する必要がないからです。固定タイムステップでは、上記のコードは次のようになります。
醜い吃音になり、そして唯一のそれらの間のすべてのフレームを交互に、ゲームのためにあなたの位置データの全ての2つのコピーを維持し、補間することによって固定することができ
public static final float FIXED_TIMESTEP = 1/50f;
public static final int MAX_UPDATES_PER_FRAME = 3;
private float elapsedTime;
public void render (float deltaTime){
elapsedTime += deltaTime;
int updates = 0;
while (elapsedTime >= FIXED_TIMESTEP = && updates < MAX_UPDATES_PER_FRAME){
update(FIXED_TIMESTEP);
elapsedTime -= FIXED_TIMESTEP;
updates++;
}
// drawing
}
左の2つの間にelapsedTime
を置き、滑らかなアニメーションを描画するのに適した値を取得します。とても難しい!
私は自分の質問で何をしているのですか?速度にデルタ時間を掛けて現在の位置に追加しています。しかし、速度が一定でなく、フレームごとに減少している場合、低いfpsのプレーヤーは、高いfpsのプレーヤーよりもさらに移動します。 – androlama
はい、彼は各フレームでさらに移動しますが、fpsの高いプレイヤーはfpsの低いプレイヤーより多く動きます。だから、それぞれが多かれ少なかれ同じ距離を移動する – Fefux
1秒後の計算によれば、1fpsのプレーヤーは、両方とも順方向ボタンを1回押すと、30fpsのプレイヤーよりも約40単位多くなります。 40はかなり大きな違いです。私はユーザーがそれを利用して、より低いfpsでより高い得点を得ることを望んでいません – androlama