回答:
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
、マウスがウィンドウ内に拘束されていないかのようにイベントを受信し続けます。
Trevorの更新された回答にはSDL2の現在の状態が反映されていますSDL_Window
が、SDL_WINDOW_INPUT_GRABBED
セットでを作成してマウスをトラップすることもできます。SDL_QUITが呼び出されない限り(別のOSイベントがフォーカスを奪い取ったとしても)ウィンドウを終了できないという、Linuxでの奇妙な問題(おそらくXウィンドウの奇妙な問題)に遭遇したことに注意してください。
SDL2では、有効化および無効化する場合、SDL_SetWindowGrab関数もあるようです。
SDL_SetWindowGrab(SDL_Window* window, SDL_bool grabbed)
SDLモーションイベントを使用して、マウスが移動したことを検出できます。その後、relX値とrelY値をパイプするイベントを発生させた後でも、その内部でWarpCursorを呼び出すことができます。OSカーソルを非表示にして、画面の中央に十字線などを描画することもできます。これにより、ユーザーにとってマウスが常に中央にあるように見え、モーションなどの値を受け取ることができます。