Jak mogę uwięzić mysz użytkownika w mojej grze? Nie jest to gra pełnoekranowa, ale chcę, żeby użytkownik nie mógł przeciągnąć myszy poza ekran.
Czy muszę sprawdzić współrzędne myszy i SDL_WarpCursor, aby powiedzieć to w oknie (ręcznie), czy też istnieje sposób automatyczny?
Dziękuję Ci.
Odpowiedzi:
Chociaż możesz to zaimplementować za pomocą SDL_WarpCursor (), mam problemy z tą metodą na niektórych platformach. Miałem prawdziwy problem z niektórymi platformami, które niezawodnie wykonywały akcję WarpCursor (), szczególnie gdy wywoływałem ją w każdej ramce.
Pamiętaj też, że na wielu platformach kursor jest obsługiwany z większą częstotliwością niż Twoja aplikacja. Jest to szczególnie ważne, jeśli pracujesz poniżej 60 klatek na sekundę! Więc nawet jeśli platforma z powodzeniem wypacza mysz w każdej ramce gry, kursor może nadal uciec od okna, jeśli odbiera aktualizacje między renderowanymi ramkami.
Prawidłowa metoda pułapki myszy pod SDL to:
To mówi SDL, że twoim celem jest przejęcie pełnej kontroli nad myszą + klawiaturą (zobacz dokumentację ), a zatem trzymanie myszy wewnątrz okna bez względu na wszystko. Od tego momentu mysz nie będzie się przesuwać poza okno, bez względu na liczbę klatek na sekundę, i nie powinieneś wywoływać SDL_WarpCursor, chyba że naprawdę zamierzasz gdzieś teleportować kursor, zamiast spamować go w sposób ciągły.
W tym trybie „chwytania” będziesz nadal otrzymywać zdarzenia ruchu myszy, tak jakby mysz nie była ograniczana w oknie. (Jeśli więc kursor znajduje się na prawej krawędzi ekranu, a użytkownik przesuwa mysz dalej w prawo, otrzymasz zdarzenie ruchu myszy pokazujące ruch w prawo, chociaż pozycja kursora się nie zmieni). Jest to bardzo przydatne (na przykład) do obracania kontrolek w grach FPS, w których zależy tylko na względnym ruchu kursora, a nie na jego absolutnej pozycji.
Aktualizacja dla SDL2 - 9 grudnia 2013 r
Ten interfejs został zmieniony dla SDL2. Jeśli używasz SDL 1.2, powyższa odpowiedź jest nadal poprawna. Jednak w SDL2
SDL_WM_GrabInput(SDL_GrabMode)
funkcja nie jest już dostępna. Nowym sposobem SDL2 na przechwycenie myszy jest:W przeciwnym razie jest to identyczne z wcześniejszą funkcją - w tym trybie będziesz nadal otrzymywać
SDL_MOUSEMOTION
zdarzenia, tak jakby mysz nie była ograniczona w oknie.źródło
Chociaż zaktualizowana odpowiedź Trevora odzwierciedla bieżący stan SDL2, możesz również uwięzić mysz, tworząc ją
SDL_Window
za pomocąSDL_WINDOW_INPUT_GRABBED
zestawu. Pamiętaj, że natknąłem się na dziwne problemy w Linuksie (prawdopodobnie z powodu dziwactwa okienkowego X), w których nigdy nie możesz wyjść z okna, dopóki nie zostanie wywołane SDL_QUIT (nawet jeśli inne zdarzenie systemu operacyjnego wykradnie fokus).źródło
W przypadku SDL2 wydaje się również istnieć funkcja SDL_SetWindowGrab, jeśli chcesz ją włączyć lub wyłączyć.
źródło
Za pomocą SDL Motion Event można wykryć ruch myszy. Następnie możesz wywołać WarpCursor, który nawet po odpaleniu zdarzenia potokuje wartości relX i relY. Możesz także ukryć kursor systemu operacyjnego i narysować celownik lub coś podobnego na środku ekranu. Zapewnia to, że mysz wydaje się zawsze znajdować się w środku dla użytkownika i nadal można odbierać wartości ruchu i tym podobne.
źródło