0

これはばかげた/以前に回答された質問かもしれませんが、それは私と私の友人を少しの間困惑させてきたものであり、私は良い答えを見つけることができませんでした.

現在、すべての JS Canvas ゲームをティックで実行しています。例えば:

function tick(){
//calculate character position
//clear canvas
//draw sprites to canvas
if(gameOn == true)
    t = setTimeout(tick(), timeout)
}

これは、ハイエンド システムの CPU 負荷の低いゲームでは問題なく動作しますが、ティックごとにもう少し描画しようとすると、スロー モーションで実行され始めます。私の質問は、可変フレームレートを許可しながら、x、y 位置とヒット検出の計算をフルスピードで実行するにはどうすればよいですか?

補足: requestAnimationFrame API を使用しようとしましたが、正直なところ、少しわかりにくかったです (これに関する優れたチュートリアルはそれほど多くありません)。また、処理が高速化される可能性はありますが、問題が完全に解決されるわけではありません。

みんなありがとう - どんな助けでも大歓迎です。

4

3 に答える 3

0

あなたは実際にダニを使用していません。何が起こっているのかというと、あなたは何度も何度も何度も何度も電話tick()をかけているということです。を削除し、個人的には、関数がそれ自体を呼び出すことを明示的に示すために使用するのが好きな()ままにする必要があります(これにより、関数名を知るという依存関係が削除されます)。setTimeout(tick,timeout);arguments.callee

そうは言っても、可変フレームレートを実装するときに私がやりたいのは、基盤となるエンジンを可能な限り単純化することです。たとえば、ボールを壁に当たって跳ね返らせるには、ボールの前の位置から次の位置までの線が壁に当たるかどうかを確認し、当たる場合はいつ当たるかを確認します。

ただし、一部のブラウザでは、contaxtメニュー(またはその他のメニュー)を開いたときにすべてのJavaScriptの実行が停止するため、2つの「フレーム」の間に数秒または数分のギャップが生じる可能性があるため注意が必要です。個人的には、フレームベースのタイミングがほとんどの場合の方法だと思います。

于 2013-03-07T01:30:34.167 に答える
0

コリンクが述べたように。バグのsetTimeoutように見えます。これが単なるタイプミスであり、実際にはバグではないと仮定すると、アニメーション自体 (つまり、DOM の更新) がコードの速度を本当に低下させている可能性は低いと言えます。

もう少しでいくらですか?画面上の何百もの要素を一度にアニメーション化して、1.2 GHz Atom ネットブック上の VMWare の IE7 で良好な結果を得ました (私が持っている最も遅いマシンで使用している最も遅いブラウザー、VMWare は Linux を使用しているためです)。

私の経験では、ヒット検出が適切に行われていない場合、アニメーション化する要素の数が増えると、最も速度が低下します。n^nこれは、単純な実装が本質的に指数関数的であるためです (比較を実行しようとします)。これを回避する方法は、不要な比較を避けるために比較を除外することです。

(言語に関係なく) ゲーム エンジンでこれを行う最も一般的な方法の 1 つは、世界地図をより大きな一連のグリッドに分割することです。次に、同じグリッド (およびより正確にしたい場合は隣接するグリッド) 内のアイテムのヒット検出のみを行います。これにより、特に文字数が多い場合に必要な比較の数が大幅に削減されます。

于 2013-03-07T02:57:11.973 に答える
0

RequestAnimationFrame は大きな違いを生みます。それはおそらくあなたの問題の解決策です。できることはあと 2 つあります。たとえば、ヒット検出など、モデル側を処理する 2 つ目のティック システムをセットアップします。これの良い例は、PhysiJS のやり方です。さらに一歩進んで、Web ワーカーと呼ばれるいくつかの新しいブラウザーの機能を使用します。これにより、2 番目の CPU コアを利用できます。John Resig には優れたチュートリアルがあります。ただし、これは複雑であり、十分にサポートされていないことに注意してください (そのため、バグが多く、頻繁にクラッシュする傾向があります)。

実際、リクエスト アニメーション フレームは非常にシンプルです。設定が完了すると、あとは忘れてしまう数行しかありません。既存のコードを変更するべきではありません。コードが何をするかを理解するのは少し難しいですが、setTimeout コードをカットアンド置換して、そこにある例を使用することができます。私に言わせれば、setTimeout も同様に複雑です。setTimeout には遅延時間があることを除いて、実質的に同じことを行いますが、 requestAnimationFrame にはありません。設定された時間の後ではなく、準備ができたときに関数を呼び出すだけです。

于 2013-03-07T01:22:37.933 に答える