Como posso prender o mouse do usuário dentro do meu jogo? Não é um jogo em tela cheia, mas quero que o usuário não possa arrastar o mouse para fora da tela.
Preciso verificar as coordenadas do mouse e do SDL_WarpCursor para dizer dentro da janela (manualmente) ou existe uma maneira automática?
Obrigado.
Respostas:
Embora você possa implementar isso usando SDL_WarpCursor (), eu tive problemas com esse método em algumas plataformas. Eu tive problemas reais com algumas plataformas que não executam com confiabilidade a ação WarpCursor (), principalmente quando a chamo de todos os quadros.
Além disso, lembre-se de que em muitas plataformas, o cursor é tratado com uma frequência mais alta que o seu aplicativo. Isto é particularmente verdade se você estiver executando abaixo de 60fps! Portanto, mesmo que a plataforma entorte com sucesso o mouse em todos os quadros do seu jogo, o cursor ainda poderá sair da sua janela se estiver recebendo atualizações entre os quadros renderizados.
O método correto para interceptar o mouse no SDL é:
Isso informa à SDL que sua intenção é realmente obter o controle total do mouse + teclado (consulte a documentação ) e, portanto, manter o mouse dentro da janela, não importa o quê. A partir deste momento, o mouse não se moverá para fora da janela, independentemente da sua taxa de quadros, e você não deve ligar para SDL_WarpCursor, exceto se realmente pretende teleportar o cursor para algum lugar, em vez de enviá-lo continuamente.
Enquanto estiver no modo "agarrar", você continuará recebendo eventos de movimento do mouse como se o mouse não estivesse sendo restringido dentro da janela. (Portanto, se o cursor estiver na borda direita da tela e o usuário mover o mouse mais para a direita, você receberá um evento de movimento do mouse mostrando o movimento para a direita, embora a posição do cursor não seja alterada). Isso é realmente útil para (por exemplo) girar controles para jogos de FPS, onde você se importa apenas com o movimento relativo do cursor, não com sua posição absoluta.
Atualização para SDL2 - 9 de dezembro de 2013
Essa interface foi alterada para SDL2. Se você estiver usando o SDL1.2, a resposta acima ainda está correta. No entanto, no SDL2, a
SDL_WM_GrabInput(SDL_GrabMode)
função não está mais disponível. A nova maneira de capturar o mouse do SDL2 é:Caso contrário, isso é idêntico à função anterior - nesse modo, você continuará recebendo
SDL_MOUSEMOTION
eventos como se o mouse não estivesse sendo restringido dentro da janela.fonte
Embora a resposta atualizada de Trevor reflita o estado atual do SDL2, você também pode prender o mouse criando o seu
SDL_Window
com oSDL_WINDOW_INPUT_GRABBED
conjunto. Esteja ciente de que encontrei alguns problemas estranhos no Linux (provavelmente devido a alguma peculiaridade da janela do X), onde você nunca pode sair da janela a menos que SDL_QUIT seja chamado (mesmo que outro evento do sistema operacional roube o foco).fonte
Para o SDL2, também parece haver a função SDL_SetWindowGrab, se você deseja habilitá-lo e desabilitá-lo.
fonte
Você pode usar o SDL Motion Event para detectar quando o mouse se move. Em seguida, você pode chamar WarpCursor dentro disso, mesmo depois de disparar um evento para canalizar os valores relX e relY. Você também pode ocultar o cursor do SO e desenhar uma mira ou algo semelhante no centro da tela. Isso garante que o mouse pareça estar sempre no meio para o usuário e você ainda poderá receber valores de movimento e similares.
fonte