2009-04-09 24 views
2

非常に正確なタイミングでゲームループを実行する必要があります。私はこれを行うためにNSTimerを使用しようとしていますが、私はOKの結果を得ていますが、少しのドリフトがあります。 NSTimerが起動すると、次回イベントがハンドラの終了時にカウントを開始するか、すぐにカウントが開始されます。 前者がsetFireDateを使って次のタイマーの発火を相殺しようとするのが妥当なのであれば - これを試してみると悪いようです。NSTimerを使用して正確なタイミングを得る

私のタイマーは44msごとに発火するように設定されています。私は20ms以上ドリフトを止めたいと思います。それが漂うなら、私は次の火のためにそれを修正したいと思います。 これはNSTimerで試してみると妥当なことですか?

+0

44msで20msがドリフトしていない、それは不正確です。 NSTImerはそれよりはるかに信頼性が高くなければなりません。 –

+0

私は、私のループがドリフトしないようにする時間が欲しいということでした。私は、タイマーが実際にタイマー値+ゲームアップタイムと思われるので、ハンドラーが終了する時点でタイマーが次のタイミングを開始することが分かります。 – Ian1971

+0

ドキュメントによれば、そのように漂ってはならないことは確かではありません(そしてこれまで私が単純なマウストラッカーを書いた時にこれが真実であることがわかった)。漂流している場合は、Appleにバグレポートを提出する必要があります。 –

答えて

4

スレッドを作成し、そのスレッドの実行ループでタイマーをスケジューリングしてみてください。その実行ループの唯一のものとしてそのタイマーを持つことは、それを妨害する可能性のあるものの数を制限するはずです。

これでうまくいかない場合は、すでにスレッドで作業しているので、usleep()ループに切り替えることもできます。

+0

私はこれを試してみるつもりです。 – Ian1971

+1

私は[NSThread sleepForTimeInterval]とmach_absolute_timeを使用してしまいました。タイミングが今すぐ上にあります。 – Ian1971

5

NSTimerが「非常に正確な」タイミングを与えるとは思わない。実行ループで起動します。メインスレッドにある場合は、UI更新からイベント処理までのすべてが遅れます。

+0

私が非常に正確に言うとき、私はそれが20ms以上言い過ぎることを望まないということです。私のタイマーは44ミリ秒ごとに発砲し、ドリフトすると次の発砲を修正したい。実際には私はこの情報で質問を更新すると思います。 – Ian1971

+1

NSTimerの文書では、タイミングは常に開始時の元の間隔に基づいています。つまり、「ドリフト」してはならないが、「ジッタ」がある可能性があります。また、この文書では50〜100ミリ秒の実効分解能が要求されています。 –

+0

うん、それはおそらく私にとって十分に正確な解像度ではありません。私は、最後の火災からの時間に基づいてfireDateを調整することでかなりの差を取ることができました。たぶん、私はPeter Hoseyが述べたusleep()のタイミングを調べる必要があります。 – Ian1971

1

またNSTimerドキュメントが述べていることに注意してください:

ための各種入力の

が 上に制限され、 典型的な実行ループが管理するタイマーの時間 間隔の 実効解像度をソース50-100ミリ秒のオーダ。 実行ループは、タイマーを監視したり、長い コールアウト時に ないモードである間 タイマーの焼成時間が発生した場合、タイマーは まで実行ループが タイマーをチェックする次の時間を発生しません。したがって、 の実際の時間は、 の可能性があります。

関連する問題