Wie kann ich die Maus des Benutzers in meinem Spiel fangen? Es ist kein Vollbild-Spiel, aber ich möchte, dass der Benutzer die Maus nicht außerhalb des Bildschirms ziehen kann.
Muss ich die Koordinaten der Maus und von SDL_WarpCursor überprüfen, damit sie (manuell) im Fenster angezeigt werden, oder gibt es eine automatische Möglichkeit?
Vielen Dank.
Antworten:
Während Sie dies mit SDL_WarpCursor () implementieren können, sind auf einigen Plattformen Probleme mit dieser Methode aufgetreten. Ich hatte echte Probleme mit einigen Plattformen, die die WarpCursor () - Aktion nicht zuverlässig ausführten, insbesondere, wenn ich sie für jeden Frame aufgerufen habe.
Denken Sie auch daran, dass der Cursor auf vielen Plattformen mit einer höheren Häufigkeit als Ihre App behandelt wird. Dies gilt insbesondere, wenn Sie unter 60 fps laufen! Selbst wenn die Plattform die Maus in jedem Frame Ihres Spiels erfolgreich verzieht, kann der Cursor dennoch von Ihrem Fenster entfernt werden, wenn Aktualisierungen zwischen Ihren gerenderten Frames empfangen werden.
Die korrekte Methode zum Einfangen der Maus unter SDL lautet:
Dies teilt SDL mit, dass Sie beabsichtigen, die vollständige Kontrolle über Maus und Tastatur zu erlangen (siehe Dokumentation ) und die Maus daher unabhängig von der jeweiligen Situation im Fenster zu lassen. Ab diesem Zeitpunkt bewegt sich die Maus unabhängig von Ihrer Framerate nicht mehr außerhalb des Fensters, und Sie sollten SDL_WarpCursor nicht mehr aufrufen, es sei denn, Sie möchten den Cursor tatsächlich irgendwohin teleportieren, anstatt ihn ständig zu spammen.
In diesem "Grabbing" -Modus empfangen Sie weiterhin Mausbewegungsereignisse, als wäre die Maus im Fenster nicht eingeschränkt. (Wenn sich der Cursor also am rechten Bildschirmrand befindet und der Benutzer die Maus weiter nach rechts bewegt, wird ein Mausbewegungsereignis angezeigt, das die Bewegung nach rechts anzeigt, die Cursorposition ändert sich jedoch nicht.) Dies ist sehr nützlich, wenn Sie beispielsweise die Steuerelemente für FPS-Spiele drehen, bei denen Sie sich nur um die relative Bewegung des Cursors und nicht um seine absolute Position kümmern.
Update für SDL2 - 9. Dezember 2013
Diese Schnittstelle wurde für SDL2 geändert. Wenn Sie SDL1.2 verwenden, ist die obige Antwort immer noch korrekt. Unter SDL2 ist die
SDL_WM_GrabInput(SDL_GrabMode)
Funktion jedoch nicht mehr verfügbar. SDL2 bietet die folgenden neuen Möglichkeiten zum Erfassen der Maus:Ansonsten ist dies identisch mit der vorherigen Funktion - in diesem Modus werden weiterhin
SDL_MOUSEMOTION
Ereignisse empfangen , als ob die Maus nicht innerhalb des Fensters eingeschränkt wäre.quelle
Die aktualisierte Antwort von Trevor gibt zwar den aktuellen Status von SDL2 wieder, Sie können jedoch auch die Maus fangen, indem Sie Ihre
SDL_Window
mit demSDL_WINDOW_INPUT_GRABBED
Set erstellen . Beachten Sie, dass ich unter Linux auf einige seltsame Probleme gestoßen bin (vermutlich aufgrund von X-Fenstern), bei denen Sie das Fenster erst verlassen können, wenn SDL_QUIT aufgerufen wird (auch wenn ein anderes OS-Ereignis den Fokus verliert).quelle
Für SDL2 scheint es auch die Funktion SDL_SetWindowGrab zu geben, wenn Sie sie aktivieren und deaktivieren möchten.
quelle
Du kannst den ... benutzen SDL-Bewegungsereignis erkennen, wann sich die Maus bewegt. Anschließend können Sie WarpCursor innerhalb dieses Befehls aufrufen, auch nachdem Sie ein Ereignis ausgelöst haben, um die relX- und relY-Werte weiterzuleiten. Sie können den OS-Cursor auch ausblenden und ein Fadenkreuz oder ähnliches in die Mitte des Bildschirms zeichnen. Dies stellt sicher, dass die Maus für den Benutzer immer in der Mitte zu sein scheint und Sie weiterhin Werte für Bewegung und dergleichen erhalten können.
quelle