SDL의 트랩 마우스 전체 화면 게임은 아니지만

게임 내에서 사용자의 마우스를 어떻게 잡을 수 있습니까? 전체 화면 게임은 아니지만 사용자가 마우스를 화면 밖으로 드래그 할 수 없도록하고 싶습니다.

마우스와 SDL_WarpCursor의 좌표를 확인하여 창 내부에서 수동으로 말해야합니까, 아니면 자동 방법이 있습니까?

감사합니다.



답변

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에서는 마우스가 창 안에서 제한되지 않은 것처럼 계속 이벤트 를 수신 합니다.


답변

트레버의 업데이트 대답은 SDL2의 현재 상태를 반영 않지만, 당신은 함정 당신을 생성하여 마우스 수도 있습니다 SDL_WindowSDL_WINDOW_INPUT_GRABBED설정합니다. Linux에서 SDL_QUIT가 호출되지 않는 한 (다른 OS 이벤트가 포커스를 훔치더라도) 창을 종료 할 수없는 Linux에서 이상한 문제 (아마도 X 윈도우 문제로 인해)를 겪었습니다.


답변

SDL2의 경우 SDL_SetWindowGrab 함수 를 사용하거나 사용하지 않도록 설정하는 것 같습니다.

SDL_SetWindowGrab(SDL_Window* window, SDL_bool grabbed)


답변

SDL 모션 이벤트 를 사용 하여 마우스의 움직임을 감지 할 수 있습니다 . 그런 다음 이벤트를 발생시킨 후에도 relX 및 relY 값을 파이프하기 위해 WarpCursor를 호출 할 수 있습니다. OS 커서를 숨기고 화면 중앙에 십자선 또는 이와 유사한 것을 그릴 수도 있습니다. 이렇게하면 마우스가 항상 사용자의 중간에있는 것처럼 보이고 모션 등의 값을 계속받을 수 있습니다.


답변