Answers:
尽管您可以使用SDL_WarpCursor()实现此功能,但在某些平台上,该方法却遇到了问题。我遇到了某些平台无法可靠执行WarpCursor()动作的实际问题,尤其是当我在每一帧都调用它时。
另外,请记住,在许多平台上,处理光标的频率高于您的应用程序。如果您以低于60fps的速度运行,则尤其如此!因此,即使平台成功在游戏的每个帧上变形了鼠标,但如果光标正在渲染帧之间接收更新,则光标仍可能离开窗口。
在SDL下诱捕鼠标的正确方法是:
SDL_WM_GrabInput( SDL_GRAB_ON );
这告诉SDL您的意图是实际上要完全控制鼠标+键盘(请参阅文档),因此无论如何都将鼠标保持在窗口内。从那时起,无论帧速率如何,鼠标都不会移出窗口,并且您不应调用SDL_WarpCursor,除非您确实确实打算将光标传送到某个地方,而不是连续地向其发送垃圾邮件。
在这种“抓取”模式下,您将继续接收鼠标运动事件,就好像鼠标没有被约束在窗口内一样。(因此,如果光标位于屏幕的右边缘,并且用户将鼠标向右移动,您将收到一个鼠标移动事件,该事件向右显示运动,尽管光标位置不会改变)。这对于(例如)转动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
集合创建鼠标来捕获鼠标。请注意,我在Linux上遇到了一些奇怪的问题(可能是由于某些X窗口怪癖),除非调用SDL_QUIT(即使另一个OS事件夺走了焦点),否则您将永远无法退出该窗口。
对于SDL2,如果要启用和禁用它,则似乎也有SDL_SetWindowGrab函数。
SDL_SetWindowGrab(SDL_Window* window, SDL_bool grabbed)
您可以使用SDL Motion事件来检测鼠标何时移动。然后,即使在触发事件以传递relX和relY值之后,也可以在其中调用WarpCursor。您也可以隐藏OS光标并在屏幕中央绘制十字准线或类似图形。这样可以确保鼠标似乎始终位于用户的中间位置,并且您仍然可以接收运动值等。