2016-11-21 3 views
1

私はゲーム開発者で私の冒険を始めています。私はLibGDXを使い始めました。 私は速度とフレームレートに関する1つの質問があります。異なるフレームレートのゲームバージョンでのLibGDXの相違

float position x=0f; 
float velosity v=200f; 
float force f=-15f; 
public void update(float deltaTime){ 
    v+=f; 
    v*=deltaTime; 
    x+=v; 
    v*=1/deltaTime; 
} 

私のコードでは、フレームごとにある程度の速度で速度を下げる力があります。同じ時間の後、30FPSでプレイしている1人のプレイヤーは、60FPSでプレイしているプレイヤーよりもさらに力を発揮します。私は正しいですか? もしそうなら、両方のプレイヤーが同じ距離を移動できるようにするにはどうすればいいですか?全く別のアプローチを使うべきですか?

答えて

1

あなたが正しいです。フレームレートが異なる場合、時間ステップが異なりますので、加速レートは予測できません。このため、多くのゲームでは、ゲームのフレームレートとは別に実行される固定タイムステップが使用されます。これは、すべてのデバイスでまったく同じようにゲームが確実に行われるようにする方法です。

これはシンプルで競争力の高いゲームでなければ、必ずしも正確であることを確認するだけで、必ずしも確定的である必要はありません。その場合、私の意見では、ちょっと騙されて、固定タイムステップの代わりに最大タイムステップを使用することができます。ゲームはいつも全く同じように再生されませんが、誰も気付かないほど正確です。これを行うには、最大デルタ時間を設定します。ゲームの各フレームで、すべてのデルタ時間が使い果たされるまで繰り返し更新を呼び出しますが、合計デルタ時間はまだ正確です。たとえば:

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を置き、滑らかなアニメーションを描画するのに適した値を取得します。とても難しい!

1

デルタタイム値(フレーム間の時間)で移動を掛けて、フレームレートを独立させることができます。あなたは以下の方法を使用することができlibgdx使用:

Gdx.graphics.getDeltaTime(); 

ことはここでは簡単な例です:

x += 500 * Gdx.graphics.getDeltaTime(); 
+0

私は自分の質問で何をしているのですか?速度にデルタ時間を掛けて現在の位置に追加しています。しかし、速度が一定でなく、フレームごとに減少している場合、低いfpsのプレーヤーは、高いfpsのプレーヤーよりもさらに移動します。 – androlama

+0

はい、彼は各フレームでさらに移動しますが、fpsの高いプレイヤーはfpsの低いプレイヤーより多く動きます。だから、それぞれが多かれ少なかれ同じ距離を移動する – Fefux

+0

1秒後の計算によれば、1fpsのプレーヤーは、両方とも順方向ボタンを1回押すと、30fpsのプレイヤーよりも約40単位多くなります。 40はかなり大きな違いです。私はユーザーがそれを利用して、より低いfpsでより高い得点を得ることを望んでいません – androlama

関連する問題