2017-08-08 10 views
1

ギターヒーローに似たブラウザゲームを構築しています。それが動作する方法は、テンポ(通常は100〜150ミリ秒)に応じて16分音符ごとに実行するようにsetIntervalが設定されています。実行する関数は、ユーザーのキー押下に対してチェックする必要のあるノートがあるかどうかをチェックするだけです。時間の経過とともに非常に正確な間隔が必要な場合は、setIntervalより優れた解決策がありますか?

しかし、私はsetIntervalがどのようにドリフトに悩まされているのか、あまり正確でないかもしれないことについて読んできました。 3〜4分持続し、100msの精度を必要とするソングの場合(タイミングメカニックがわずかにオフになっていると、ユーザーにとって非常に不満かもしれません)、それは最大の解決策ではないようです。

もっと正確な選択肢がありますか? T

+0

'私はこの声明を前に読んで、この主張をテストすることに決めました。少なくとも、Firefoxでは、そのようなドリフトがないことがわかりました。ジッタがあります。 –

+0

ユーザーインタラクション、setIntervalではありません。 – PHPglue

+0

@PHPglueユーザーがボタンを押して正しいかどうかを確認します。しかし、私はまた、ユーザーがメモを逃したかどうかをチェックする方法が必要です。たとえば、ユーザーがゲーム全体で何もしない場合、ゲームは正しいタイミングで各ノートをチェックして、ポイントを減らす必要があります。 –

答えて

1

それはおそらく良いアイデアだろう絶対時間ですべてを計算する。だからvar starttime = Date.now();を持って、そしてすべてのノートがvar expected_note_time = starttime+beat_interval*beat_numberであるべき場所を計算してください。 keypressにリスナーを追加して、キーを押された正確な時刻を記録することができます。 abs(time_pressed-expected_note_time) < ALLOWED_MISTAKE_VARIANCEの場合は、そのポイントをユーザーのスコアに追加します。がんばろう。

+0

私は実際にユーザー入力をチェックするためにその正確な解決策を設定しました。しかし、ゲームが動作する別の方法は、たとえユーザーがゲーム全体に対して何もしない場合であっても、ユーザーが何も押さなかった場合でもポイントをデクリメントする適切なタイミングで各メモをチェックする必要があります。 –

+0

@AndrewHarrisは、このQA(https://stackoverflow.com/questions/29971898/how-to-create-an-accurate-timer-in-javascript)を参照しています。これにより、setIntervalと "make up"を使ってジッタやドリフトを調整することができます。 – PressingOnAlways

+0

まさに私が必要とするもののように見えます。ありがとう! –

0

ソングの先頭にティックをキャッシュし、それ以降のティック数を取得し、その時点でノートが存在するかどうかを確認することができます。

戻る1970年1月1日からのミリ秒数:

var d = new Date(); 
var n = d.getTime(); 

n個の結果は次のようになります。 1502156888172

から:https://www.w3schools.com/jsref/jsref_gettime.asp

0

これは、コールバックがまだ実行されているかどうかに関わらず、柔軟性がないかどうかに関係なく、setIntervalにはいくつかの問題があります。あなたはあなたにこのような独自の方法で何かを実装することができます

:この関数はsetTimeoutを介して、自動的に呼び出されますintervと呼ばれる内部機能を持っている、interv内の繰り返し回数をチェックするクロージャである

function interval(func, wait, times){ 
var interv = function(w, t){ 
    return function(){ 
     if(typeof t === "undefined" || t-- > 0){ 
      setTimeout(interv, w); 
      try{ 
       func.call(null); 
      } 
      catch(e){ 
       t = 0; 
       throw e.toString(); 
      } 
     } 
    }; 
}(wait, times); 

setTimeout(interv, wait); 
}; 

を呼び出し、 setTimeoutを介して再度intervを呼び出します。例外がコールバック呼び出しからバブルアップした場合、インターバル呼び出しは停止し、例外がスローされます。 5回の間隔または10秒でコードの一部を実行

interval(function(){ 
    // Code block goes here 
}, 1000, 10); 

を、あなたが間に何かを行うことができます:

あなたはこのようにそれを使用することができます。

0

と100msの精度

のsetInterval()関数が原因ではJavaScriptが構築されている方法(イベントループ)のドリフトになると、あなたが重いCPU集約型タスクとそれをブロックする場合、それは遅れるだろうが必要です。しかし、それを正しく行うとドリフトは非常に小さくなります(ms未満)。

これを回避するには、複数のスレッドを使用するのが良い方法ですが、JavaScriptでは簡単には実現できません。

関連する問題