PixelArtsという個人的なプロジェクトでcanvasをガンガン使っているんですが、canvasとその周辺技術についてTipsをまとめたいと思います。まず最初のTipsはループ処理。ゲームなどでキー入力待ちを行う場合などは、ループ処理で入力を待つなんて事をしますが、JavaScriptでループを回しっぱなしにするとフリーズします。フリーズせずにループをする方法に加えて、擬似的にフレームレートを設定する方法をまとめます。
ページに留まり続ける限りループさせ続けるのが前提なので、forやwhileだとフリーズしたようになります(forefoxやchromeではスクリプトが長く動いていると警告が出ます)。
JavaScriptにはsleepがないので、setTimeout()でインターバルを設ける事で、擬似的にsleep処理を行っている雰囲気です。
上記のソースは、PixelArtsで作品を作る際の雛形からループ処理に関する部分だけを抜粋したものです。
変数fpsで、1秒間にループさせる回数を設定して、変数intervalで1ループ辺りのミリ秒を取得します。
play()の先頭で実行開始時間をsTimeに格納し、終了時間をeTimeに格納します。
後はeTime-sTimeとintervalを比較して次のplay()を実行するタイミングを取得しています。
HTMLにbuttonが配置されていて、それを押すとrunFlgがtrue/falseが切り替わるようになっています。
これで一時停止を実現しています。
play()の中でforやwhileを利用することはありますが、arrayを走査するなど、短時間で終わる事が分かっているものなので、ブラウザの操作に支障が出るレベルではありません。
今回紹介したコードはPixelArtsのどのコードにも登場する定番コードです。
PixelArtsはMath.random()を使ってプログラマーが芸術に挑戦するというものです。
PixelArtsの方もよろしくお願いします。
PixelArts
ループ処理
私はループして図形を動かし続けるために、forやwhileを使わずsetTimeout()を使った割り込み可能なループをよく使います。ページに留まり続ける限りループさせ続けるのが前提なので、forやwhileだとフリーズしたようになります(forefoxやchromeではスクリプトが長く動いていると警告が出ます)。
JavaScriptにはsleepがないので、setTimeout()でインターバルを設ける事で、擬似的にsleep処理を行っている雰囲気です。
var fps = 20, interval = 1000 / fps; function play(){ var sTime = new Date().getTime(); /* なんらかの処理 */ var eTime = new Date().getTime(); var intervalTime = interval - (eTime - sTime); if (intervalTime < 0) intervalTime = 0; if (runFlg){ time = setTimeout(arguments.callee, intervalTime); } };
上記のソースは、PixelArtsで作品を作る際の雛形からループ処理に関する部分だけを抜粋したものです。
変数fpsで、1秒間にループさせる回数を設定して、変数intervalで1ループ辺りのミリ秒を取得します。
play()の先頭で実行開始時間をsTimeに格納し、終了時間をeTimeに格納します。
後はeTime-sTimeとintervalを比較して次のplay()を実行するタイミングを取得しています。
HTMLにbuttonが配置されていて、それを押すとrunFlgがtrue/falseが切り替わるようになっています。
これで一時停止を実現しています。
play()の中でforやwhileを利用することはありますが、arrayを走査するなど、短時間で終わる事が分かっているものなので、ブラウザの操作に支障が出るレベルではありません。
フレームレートの設定
先のソースコードにもまんまfpsと書いていますが、これが設定値ですね。intervalは1フレーム当たりに割り当てられた時間になる訳ですが、ループ内のコードを実行するのにかかった時間を加味して次回実行するまでの時間をintervalTimeに計算しています。今回紹介したコードはPixelArtsのどのコードにも登場する定番コードです。
PixelArtsはMath.random()を使ってプログラマーが芸術に挑戦するというものです。
PixelArtsの方もよろしくお願いします。
PixelArts
コメント
コメントを投稿