3

私のアプリケーションには、ウィンドウサイズに応じてCSSサイズ(htmlではなくCSS)が更新されるキャンバスがあります。

私はこのように見えるメインのgameplayLoopを持っています:

run = function(){

    console.log(timerDiff(frameTime));

    game.inputManage();
    game.logics();
    game.graphics.animate();
    game.graphics.render();

    frameTime = timerInit();

    requestAnimFrame(run);

}

私のrequestAnimFrame関数はPaulIrishのものです:

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

つまり、基本的に問題は、requestAnimFrame呼び出しと有効な関数呼び出しの間の時間を測定するログに記録するタイマーが完全に変更されることです。ブラウザがフルスクリーンの場合は50/60ミリ秒になり、ウィンドウが小さい場合は10ミリ秒になります。

requestAnimFrame呼び出しは、60 fpsのリズム(30 msのようなものだと思います)で関数を常に呼び出すことになっているので、タイマーの作成とチェックの間に基本的に何も起こらないので、このような結果は得られないはずです。 requestAnimFrame

また、2/3秒ごとのように発生するマイクロフリーズ(1秒未満)が繰り返し発生します。ただし、タイマーは時間の変化を検出しません(javascriptのタイムカウンターもブロックされているように)

私のタイマー機能はこんな感じですが、ここでは関係ありません

timerInit = function()
{
    return new Date();
}

timerDiff = function(datePrev)
{
    return new Date().getTime() - datePrev.getTime();
}
4

2 に答える 2

7

まあ、標準は基本的requestAnimationFrameに、「一貫した」フレームレートで実行するために「最善を尽くす」と言っています。これは 60 fps を保証するものではありません。できるだけ速くアニメーション化することを示しているだけです。

残念ながら、これまでの私の経験はあなたと同じくらい薄暗いものでした。に戻ってしまいましたsetTimeout。それはほぼ同じ速度で進み、グラフィカルな更新は正確であり、requestAnimationFrame. 確かに 60 fps ではありませんでしたが、少なくとも何が起こっているかはわかりました。

ブラウザー開発者が新しい機能を最適化するにつれて、パフォーマンスが向上するだけだと確信していますが、当面は に戻すことを検討してtimeoutsください。

編集:これは1年前に回答されたものであり、時代が変わったことを人々に思い出させたい:)

于 2012-03-25T13:29:16.077 に答える
4

「つまり、基本的に問題は、requestAnimFrame 呼び出しと有効な関数呼び出しの間の時間を測定する、ログに記録するタイマーが完全に変化することです...」

もちろんそうです。そのため、それを測定し、この時間差の値に基づいて次のフレームを計算する必要があります。

div の 'left' css プロパティを 60 fps で 1 秒間に 0px から 120px にアニメーション化するとします。

  • setTimeout を使用すると、フレーム数を設定するため、「左」プロパティをどれだけインクリメントする必要があるかがわかります: 120px/60frames = 2px/frame

  • requestAnimationFrame を使用すると、次のフレームが発生するまで、次のフレームがいつ発生するかわかりません。次に、これと前のフレームの時間差を測定し、css の「左の値」をインクリメントする必要がある値を計算します。フレームが 500 ミリ秒後に発生する場合、増分距離 = (120px * 500ms)/1000ms = 60px; アイデアは、アニメーションの開始時に、各フレームで増分する固定の所定の値を持つことができないということです。時間差に基づいて動的に計算する必要があります

したがって、アニメーションが宣伝されている 60 fps でなくても、フレームがスキップされた場合、スキップされていないすべてのフレームが正確に更新された状況を描画します。

アニメーションをいつ終了するかを決定するには、少し調整する必要があります。

于 2012-07-31T09:18:37.457 に答える