23

そこで、「SDL でのマルチスレッド プログラミングのヒントとアドバイス」を含むこの記事を読んでいました - https://vilimpoc.org/research/portmonitorg/sdl-tips-and-tricks.html

SDL_PollEvent は CPU を過度に使用する可能性があるため非効率的であり、代わりに SDL_WaitEvent を使用することをお勧めします。

両方のループの例を示していますが、これがゲーム ループでどのように機能するかわかりません。SDL_WaitEvent は、一定の更新を必要としないものにのみ使用する必要があります。つまり、ゲームを実行している場合、フレームごとにゲーム ロジックを実行します。

私がそれを使用できると考えることができる唯一のものは、ユーザー入力に対してのみアクションが必要なペイントプログラムのようなプログラムです.

一般的なゲーム プログラミングに SDL_PollEvent を使い続ける必要があるという考えは正しいですか?

4

5 に答える 5

13

ゲームがユーザーの入力によってのみ更新/再描画される場合は、SDL_WaitEvent を使用できます。ただし、ほとんどのゲームでは、ユーザー入力がない場合でもアニメーション/物理が進行しています。したがって、ほとんどのゲームには SDL_PollEvent が最適だと思います。

SDL_WaitEvent が役立つ可能性がある 1 つのケースは、あるスレッドにそれがあり、別のスレッドにアニメーション/ロジックがある場合です。そうすれば、SDL_WaitEvent が長時間待機しても、ゲームは描画/更新を続行します。(編集: これは実際には機能しない可能性があります。以下の Henrik のコメントを参照してください)

記事に示されているように 100% CPU を使用する SDL_PollEvent に関しては、ゲームが必要な 1 秒あたりのフレーム数を超えて実行されていることを検出したときに、ループにスリープを追加することでそれを軽減できます。

于 2013-09-18T03:17:38.250 に答える
10

入力にサブフレームの精度が必要なく、ゲームが常にアニメーション化されている場合は、SDL_PollEvent が適切です。

サブフレームの精度は、たとえば次の場合に重要になる可能性があります。プレーヤーが非常に小さな動きの増分を必要とする可能性のあるゲーム - キーをすばやくタップして離すと、「速度 = 1」を意味するキーダウンと「速度 = 0」を意味するキーアップの古典的な怠惰な方法を使用すると、予期しない動作が発生します。フレームごとに位置を更新します。タップがたまたまフレーム レンダリングとオーバーラップした場合、1 フレーム分の移動時間が得られます。そうでない場合は移動がありません。実際に必要なのは、タイムスタンプに基づくフレームの長さよりも小さい移動量です。イベントが発生した場所。

残念ながら、SDL のイベントにはオペレーティング システムからの実際のイベント タイムスタンプは含まれず、PumpEvents 呼び出しのタイムスタンプのみが含まれ、WaitEvent は 10 ミリ秒間隔で効果的にポーリングされるため、WaitEvent が別のスレッドで実行されている場合でも、得られる最高の精度は10 ミリ秒 (同じポーリング サイクルでキーダウンとキーアップを取得した場合、約 5 ミリ秒と言うと、より小さく概算できます)。

したがって、入力の正確なタイミングが本当に必要な場合は、実際には、SDL_Delay を小さくした独自のバージョンの SDL_WaitEventTimeout を作成し、それをメインのゲーム ループとは別のスレッドで実行する必要があります。

さらに残念なことに、SDL_PumpEvents は ( https://wiki.libsdl.org/SDL_PumpEventsごとに) ビデオ サブシステムを初期化したスレッドで実行する必要があるため、別のスレッドで入力ループを実行してサブフレームのタイミングを取得するという全体的なアイデアは破棄されます。 SDL フレームワークによって。

結論として、アニメーションを伴う SDL アプリケーションの場合、SDL_PollEvents 以外を使用する理由はありません。サブフレームレートの入力精度のためにできる最善の方法は、フレームで焼き付ける時間があれば、その間は正確にするオプションがありますが、入力が失われるフレームごとに奇妙なレンダリング期間ウィンドウが表示されます。精度なので、別の種類の不一致が発生します。

于 2016-01-17T21:49:15.017 に答える
5

一般に、SDL_PollEventではなくSDL_WaitEventを使用してCPUをオペレーティングシステムに解放し、ユーザー入力の処理などの他のタスクを処理する必要があります。これは、ユーザーがコマンドを入力してからアプリケーションがイベントを処理するまでに遅延が発生する可能性があるため、ユーザー入力に対する反応の鈍さとしてユーザーに現れます。代わりに SDL_WaitEvent を使用することで、OS はアプリケーションにイベントをより迅速に送信できるようになり、認識されるパフォーマンスが向上します。

副次的な利点として、ノート PC やポータブル デバイスなどのバッテリー駆動システムのユーザーは、ゲームが 100% の時間で CPU を使用するわけではないため、OS が全体的な CPU 使用率を削減する機会があるため、バッテリー使用量がわずかに少なくなるはずです。イベントが実際に発生したときに使用します。

于 2013-09-18T01:20:17.780 に答える
0

メイン スレッドで SDL とウィンドウを実際に初期化し、更新 (時間の経過に応じてゲームの状態と変数を更新するだけ) とレンダリング (それに応じてサーフェスをレンダリングする) 用にさらに 2 つのスレッドを作成できます。それが終わったら、メインスレッドで SDL_WaitEvent を使って SDL_Events を管理します。このようにして、sdl_init を呼び出したのと同じスレッドでイベントが管理されるようにすることができます。

私はこの方法を長い間使用して、ゲームを Windows と Linux で動作させ、上記のように同時に 3 つのスレッドを正常に実行できました。

レンダー スレッドを一時停止することで、更新スレッドでもテクスチャ/サーフェスを変換/変更できるようにするためにミューテックスを使用する必要がありました。ロックは 60 フレームごとに呼び出されるため、大きなパフォーマンスの問題は発生しません。

このモデルは、イベント ドリブン ゲーム、ランタイム ゲーム、またはその両方を作成するのに最適です。

于 2019-07-09T14:26:03.770 に答える