3

このコードは何度か見ました。

long lastTime = System.nanoTime();
final double ticks = 60D;
double ns = 1000000000 / ticks;    
double delta = 0;

上記のコードは、システム時間を取得して に保存しlastTimeます。60 ティックは、1 秒あたりの更新回数に相当するはずです。

while(running){
    long now = System.nanoTime();
    delta += (now - lastTime) / ns;
    lastTime = now;
    if(delta >= 1){
        tick();
        delta--;
    }

を取りnow、減算lastTimeしてから、ナノ秒/60 に変換します。nowとナノの間の時間差がlastTime60 を超えると、デルタが 1 秒あたり 60 回以上になるという保証はありますか? tick();1秒間に約60回実行される理由がわかりません。私の計算では、ループが実行されるたびにデルタが 0.0025 程度増加します。

4

3 に答える 3

2

何が起こっているのかをより明確に示すために、コードに少しコメントを付けました。

//Get the system time
long lastTime = System.nanoTime();
//Specify how many seconds there are in a minute as a double
//store as a double cause 60 sec in nanosec is big and store as final so it can't be changed
final double ticks = 60D;
//Set definition of how many ticks per 1000000000 ns or 1 sec
double ns = 1000000000 / ticks;    
double delta = 0;

while(running){
//Update the time
    long now = System.nanoTime();
//calculate change in time since last known time
    delta += (now - lastTime) / ns;
//update last known time    
    lastTime = now;
    //continue while delta is less than or equal to 1
    if(delta >= 1){
//Go through one tick        
        tick();
//decrement delta
        delta--;
    }

今、私はこれが何をしているのかかなり確信していますが、 tick() が何であるかを見ずに確実に言うことはできません

于 2014-11-10T07:07:26.437 に答える
2

tick() メソッドが 1 秒間に 60 回しか実行されないようにしています。これはデルタ タイミングと呼ばれ、ゲーム コミュニティ全体で参照されています。デルタ タイミングが使用される理由は、ゲームをすべてのプラットフォームで同じレートで実行するためです。ゲーム内の物理やアニメーションなどは、システムの速度に関係なく、同じ速度で実行する必要があります。遅いシステムを使用していて、ゲームにデルタ タイミングが含まれていない場合、ゲームが高速システムで実行されている場合よりも物理演算の実行が遅くなります。

使い方

  • 1 秒あたりの更新回数を計算します。この場合、1 秒あたり 60 回です。

  • 時間関数に組み込まれている言語の解像度を見つけます。コードは、Java の組み込み System.nanotime() 関数を使用します。この関数は、システムが実行されているナノ秒数の long 値を返します。

  • 1 秒は 1000000000 ナノ秒です。これは、tick() の呼び出しごとの時間差が 1000000000/60 に等しいことを意味します。これは約 16666666 ナノ秒です。これは、 tick() が呼び出されるたびに、プログラムが tick() を再度呼び出す前に 16666666 ナノ秒待機することを意味します。

  • あなたがしなければならないことは、現在のフレームと最後のフレームの間の時間をナノ秒単位で見つけることです。この値をタイムステップ (16666666) で割ると、必要な時間が経過した割合が 10 分の 1 になります。この 10 進数のパーセンテージをデルタ変数に追加すると、デルタ変数が >= 1 のときに 1/60 秒が経過したことになります。これは、プログラムが tick() を呼び出すことができることを意味します。

  • 最後に、デルタ変数から 1 を引きます。デルタ変数を 0 に設定しない理由は、タイムステップが 1 よりも大きく、デルタ変数が 1 を超える可能性があるためです。つまり、次にループして呼び出すときに、それを考慮する必要があります。ティック()

于 2015-01-10T18:45:01.597 に答える
1

何が入っているのかtick()わからないので、確信が持てませんが、60Dほぼ正しい時間スリープしようとするためにも使用されていると思いますか? つまり、いいえ、保証はありません。これは、このコードが修正するものです。

tick()1 ティック未満の睡眠なら何もしないでください。1 ティック以上の睡眠なら 1 回だけ」と言っています。

おそらく、ティックが十分にオーバーした場合 (たとえば、80ns の次に 80ns の場合、最初のループがティックをインクリメントし、2 番目のループがティックを 2 ずつ増加させることを意味します)、最終的には 40ns のデルタしか持たない別のループが発生し、すべてが均等になります。

于 2014-11-10T07:09:13.527 に答える