■
FlexのTimerクラスを使って、ストップウォッチっぽいものをつくっていたけど、このTimerクラスの精度が渋い。
http://www.bit-101.com/blog/?p=910でもガイジンさんが言及しているけど、自分の環境でも1分に3,4秒の狂いが平気で出る。
これは、TimerクラスがTIMERイベントのHandler実行中に、停止してしまう(次のカウントを開始しない)ために起こる。
ので、クラスリファレンスからして
たとえば、SWF ファイルを 10 fps (1 秒あたりのフレーム数)、つまり100 ミリ秒間隔で実行するように設定し、80 ミリ秒でイベントを発生するようにタイマーを設定すると、Flash Player ではおよそ 100 ミリ秒間隔でイベントが実行されます。
と書いてある。
Timerクラスは便利なのですが、実時間と連動するのが必要なタスクには向かないようです。
解決策としては2つが考えられそう。
- リファレンスに素直に従い、Timer(80)なり、適切なミリ秒を設定する。Timerの動作は、Handlerの動作の間“待ってしまう”ため狂いが大きくなる。そのため、Handlerの動作時間を見越してdelayを与えてやればいい。
- Timerクラスの使用は諦めて、Event.ENTER_FRAMEを拾う。
上のガイジンさんもお勧めの方法。具体的にはこんな感じ。
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
…
private function enterFrameHandler(event:Event):void
{
trace("hoge");
}
ただし、Event.ENTER_FRAMEは時間を一切考慮せず、「Flashのフレームの進捗にあわせて」発行されるため、
コンピュータの動作速度等に依存する部分が大きくなる。
また、FlexデフォルトのFPSは24であるため、場合によってはFPSを設定する作業も必要かもしれません。
FPSを変更するためには以下。
stage.frameRate = 60;で、fps=60になるはず。(ただし、表示オブジェクト追加後に呼び出さないとstageからnullが返る。
ので、例えば
今回くらいだと大して困らないけど、Flexでゲームを本格的に作ろうと思った場合、結構問題になってくると思ってメモ。