SDLのトラップマウス


12

ユーザーのマウスをゲーム内にトラップするにはどうすればよいですか?フルスクリーンのゲームではありませんが、ユーザーがマウスを画面外にドラッグできないようにしたいです。

マウスとSDL_WarpCursorの座標を確認してウィンドウ内で(手動で)確認する必要がありますか、それとも自動的な方法がありますか?

ありがとうございました。


カーソルを非表示にして、中央に戻すことを検討しましたか?次に、OSカーソルの代わりに画面の中央に十字線を描きます。
ヴォーンヒルツ

回答:


24

SDL_WarpCursor()を使用してこれを実装できますが、一部のプラットフォームではそのメソッドで問題が発生しました。一部のプラットフォームで、特にフレームごとに呼び出す場合に、WarpCursor()アクションを確実に実行できないという問題がありました。

また、多くのプラットフォームでは、カーソルはアプリよりも高い頻度で処理されることに注意してください。これは、60fps未満で実行している場合に特に当てはまります。プラットフォームがゲームのすべてのフレームでマウスを正常にワープしている場合でも、レンダリングされたフレームの間に更新を受信して​​いると、カーソルがウィンドウから離れることがあります。

SDLでマウスをトラップする正しい方法は次のとおりです。

SDL_WM_GrabInput( SDL_GRAB_ON );

これにより、SDLに、マウス+キーボードのフルコントロールを実際に取得することが意図されていることがわかります(ドキュメントを参照してください))であり、したがって、マウスが何であってもウィンドウ内に保持する。この時点から、フレームレートに関係なく、マウスはウィンドウの外に移動しません。カーソルを継続的にスパムするのではなく、どこかにテレポートするつもりでない限り、SDL_WarpCursorを呼び出さないでください。

この「グラビング」モードでは、マウスがウィンドウ内に拘束されていないかのように、マウスモーションイベントを受信し続けます。(したがって、カーソルが画面の右端にあり、ユーザーがマウスをさらに右に移動すると、カーソルの位置は変わりませんが、右への動きを示すマウスモーションイベントを受け取ります)。これは、(たとえば)FPSゲームのコントロールを回転させる場合に非常に便利です。FPSゲームでは、カーソルの絶対位置ではなく、相対的な動きのみに注目します。

SDL2の更新-2013年12月9日

このインターフェイスはSDL2で変更されました。SDL1.2を使用している場合、上記の答えは依然として正しいです。ただし、SDL2では、このSDL_WM_GrabInput(SDL_GrabMode)機能は使用できなくなりました。SDL2のマウスをキャプチャする新しい方法は次のとおりです。

SDL_SetRelativeMouseMode(SDL_TRUE);

それ以外の場合、これは以前の関数と同じです。このモードではSDL_MOUSEMOTION、マウスがウィンドウ内に拘束されていないかのようにイベントを受信し続けます。


1
警告:一部のプラットフォームでは、マウスグラブをオンにした直後に、非常に大きな動きを伴う偽のMouseMotionイベントをすぐに受け取ることに気付きました。これに対処するために、このモードをオンにした後に受け取った最初のマウスモーションイベントをコードで無視するようにします。
トレバーパウエル

それは完全に機能し、手動の方法よりもはるかに簡単です。ありがとうございました!
デビッドゴメス

3

Trevorの更新された回答にはSDL2の現在の状態が反映されていますSDL_Windowが、SDL_WINDOW_INPUT_GRABBEDセットでを作成してマウスをトラップすることもできます。SDL_QUITが呼び出されない限り(別のOSイベントがフォーカスを奪い取ったとしても)ウィンドウを終了できないという、Linuxでの奇妙な問題(おそらくXウィンドウの奇妙な問題)に遭遇したことに注意してください。


ありがとう、SDL_WINDOW_INPUT_GRABBEDは私のSDL2コードで完璧に機能します。
エイドリアンマイア


2

SDLモーションイベントを使用して、マウスが移動したことを検出できます。その後、relX値とrelY値をパイプするイベントを発生させた後でも、その内部でWarpCursorを呼び出すことができます。OSカーソルを非表示にして、画面の中央に十字線などを描画することもできます。これにより、ユーザーにとってマウスが常に中央にあるように見え、モーションなどの値を受け取ることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.