0

HTML5/JSで簡単なゲームを作ろうとしています。ステートマシンとゲームループ用に基本的なスケルトンを準備することができましたが、単純な長方形を動かしても、「具体的な」途切れが発生します。

さらに、しばらくアイドル状態のままにした後(タブアウト)、非常に速くカチカチ音をたてるように見え、単純なキーを押すだけで長方形が必要以上に移動します。

setTimeoutゲームのアップデートに使用しています。各「ティック」の間に、現在の状態の更新関数を呼び出します。

State.prototype.update = function(ms) {
    this.ticks += ms;

    var updates = 0;
    while(this.ticks >= State.DELTA_TIME && updates < State.MAX_UPDATES) {
          this.updateState();

          this.updateFrameTicks += State.DELTA_TIME;
          this.updateFrames++;

          if(this.updateFrameTicks >= 1000) {
              this.ups = this.updateFrames;
              this.updateFrames = 0;
              this.updateFrameTicks -= 1000;
          }

        this.ticks -= State.DELTA_TIME;
        updates++;
    }   

    if(updates > 0) {
          this.renderFrameTicks += updates*State.DELTA_TIME;
          this.renderFrames++;

          if(this.renderFrameTicks >= 1000) {
              this.rps = this.renderFrames;
              this.renderFrames = 0;
              this.renderFrameTicks -= 1000;
          }

          this.renderState(updates*State.DELTA_TIME);
    }

};

アイデアは、Game.updateを使用してできるだけ頻繁に呼び出してsetTimeoutから、経過時間をに渡すことState.updateです。State.update状態によって累積された時間が固定更新タイムステップ以上である場合にのみ、状態を更新します。状態が実際に更新されるState.updateと、現在の状態もレンダリング/再描画され、状態の表示が状態のシミュレーションと一致するようになります。

今、私はそれrequestAnimationFrameがよりうまく機能することを知っていますが、根本的な間違いをしない限りsetTimeout、理論的には現在のバージョンが機能するはずです。

これは私がこれまでに持っているものです:http://jsbin.com/ogicec/1編集

途切れ途切れになっていることがはっきりとわかります。長時間タブアウトして戻ってくると、通常よりも「速く」動作しているように見えます。

問題が何であるかを正確に特定することはできませんので、助けていただければ幸いです。

編集:setTimeout更新とレンダリングに使用し て、状態の更新とレンダリングの部分を分離しましたrequestAnimationFrame。それはタブアウトの問題を処理し、全体がより一貫しているように感じます。ただし、同時に、パフォーマンスはまだ不安定であり、ゲーム関連のコードを追加する前に、十分にスムーズであることを確認したいと思います。

更新されたJSBinは次のとおりです。http://jsbin.com/eyarod/1編集

4

2 に答える 2

1

私のシステムでは、JSBinテストは実際にはUPS:60およびFPS:60でほぼ常に実行されます(i7-2600kのchrome 25.0.1349.2 devで実行しており、VSyncがオンになっていることに注意してください。フレームレートが制限される理由)。別のタブに切り替えて戻ると、FPSが少し混乱します。これは、タブがアクティブでないときにブラウザがsetTimeout呼び出しを調整する方法に関連していると思われます。

より一般的には、メッセージポーリングのビジーウェイトループをイベント駆動型言語であるJavaScriptに押し込もうとしているようです。共有オブジェクトを現在のxとyで更新するイベントハンドラーを追加し、モニターのリフレッシュレートに固定されたレートで画面を更新するための別のループを追加すると、多くのパフォーマンスが得られると思います(ただし、確かではありません)。より良い。

于 2012-12-10T17:59:08.943 に答える
0

これで、requestAnimationFrameがsetTimeoutよりもうまく機能することがわかりましたが、根本的な間違いをしない限り、理論的には現在のバージョンが機能するはずです。

ユーザーエージェントは、提供されたミリ秒の引数を超えて、必要に応じて追加の時間を待つことができますsetTimeout(通常、遅延実行を実行する非リアルタイムAPIは、指定された遅延の前にコードが実行されないことを保証しますが、実行される場合があります指定した遅延後の任意の時間)。this.ticksさらに、更新の1つの呼び出しがフレームに非常に近いがフレーム未満であり、次の呼び出しが2つの更新をトリガーする時間に来て、フレームをスキップすると、動きが途切れる場合があります。

間違いは、そうsetTimeoutする保証を決して提供できないということrequestAnimationFrameです。

requestAnimationFrameを使用して問題が発生し続ける場合は、Chrome開発ツールを使用して問題を掘り下げることができます。これがアニメーションチョップの回避に関するスライドです

于 2012-12-10T19:27:30.017 に答える