Klawiatura, mysz i joystick

Wstęp


W tej części poradnika zajmiemy się omówieniem instrukcji warunkowych klawiatury, myszy i joysticka. Przydają się one do sprawdzenia, czy określony klawisz jest wciąż wciśnięty.

 

Klawiatura


Klasa, która daje nam dostęp do klawiszy na klawiaturze to sf::Keyboard. Ta klasa zawiera tylko jedną metodę: isKeyPressed, która sprawdza czy klawisz jest wciśnięty, jeżeli tak to zwraca true, w przeciwnym razie false. Jako argument przyjmuje klawisz, który ma zostać sprawdzony. Co trzeba zaznaczyć to fakt, że to metoda sprawdza bezpośrednio stan klawisza, czyli działa nawet wtedy gdy okno jest niekatywne.

 

Mysz


Klasą odpowiedzialną za obsługę myszy jest sf::Mouse. Podobnie jak w przypadku klawiatury mysz posiada instrukcję warunkową wciśnięcia klawiszy.

Przyciski myszy zawarte są w enum sf::Mouse::Button.

Możesz także pobrać pozycję myszy względem pulpitu lub okna gry.

Analogicznie można też ustawić pozycję myszy:

 

Joystick


Klasa, która daje nam dostęp do obsługi pada to sf::Joystick. Tak jak reszta klas w tym tutorialu posiada wyłącznie funkcje statyczne (z przedrostkiem static).

Każdy Joystick posida swoje id numerowane od 0-7 (bo SFML obsługuje maksymalnie 8 padów). Pierwszy argument każdej metody sf:Joysticks to jego id.

Możesz sprawdzić, czy Joystick o określonym id jest podłączony w następujący sposób:

Można także sprawdzić niektóre parametry joysticków:

Osie są zdefiniowane w enum sf::Joystick::Axis. A przyciski są ponumerowane od 0 do 31.

W ten sposób możesz sprawdzić czy jakiś klawisz jest wciśnięty, a także możesz sprawdzić pozycję osi:

Oryginalny artykuł

Zarządzanie eventami

Czym są eventy?


Eventy, czyli po polsku zdarzenia to czynności, które mógł wykonać użytkownik w naszym programie, a my możemy je obsłużyć w odpowiedni sposób. Eventem może być np wciśnięcie klawisza.

W SFML klasa eventów nazywa się po prostu sf::Event i standardowo są one obsługiwane w pętli z użyciem pollEvent, czy też waitEvent. Przykładowe kod z użyciem eventów:

Ewentualnie można napisać to tak jak poniżej:

 

Event żądania zamknięcia


Jest to event, który się uaktywania w przypadku gdy użytkownik kliknie przycisk X (Zamknij) lub użyje skrótu zamknięcia programu np Alt + F4

 

Event zmiany rozmiaru okna


Ten event jest uaktywaniany gdy użytkownik w sposób manualny zmieni rozmiar okna za pomocą myszy. Dzięki tej informacji możesz np samodzielnie przeskalować textury itp. Event podaje nam rozmiary aktualnego okna:

 

Event sprawdzający czy okno jest aktywne


Czyli sprawdzenie czy okno jest „kliknięte”. Może to nam się przydać gdy chcemy aby podczas gdy okno jest niekatywne gra się spauzowała:

 

Wprowadzanie tekstu


W przypadku gdy chcemy aby użytkownik wprowadził jakiś tekst do programu (np. swój nick) to gdy będziemy się chcieli za to zabrać będzie mogło się okazać, że sprawdzenie jaka litera została wciśnięta może być niewygodne, bo trzeba by było wziąć pod uwagę wszystkie klawisze. N a szczęście istnieje prosta metoda przechwytywania tekstu:

 

Wciśnięcie i puszczenie klawiszy


SFML wyróżnia 2 typy użycia klawiszy: KeyPressed (klawisz wciśnięty) oraz KeyReleased (klawisz puszczono).  Standardowo zdarzenie KeyPressed jest generowane zgodnie z opóźnieniem OS dopóki ten klawisz jest wciśnięty, działa to na tej samej zasadzie co wypisywanie tej samej litery gdy trzymamy wciśnięty klawisz w notatniku. Możemy to wyłączyć używając window.setKeyRepeatEnabled(false), oczywiście KeyReleased nie jest nigdy powtarzany.

Możemy także używać kombinacji klawiszy:

 

Obsługa myszy


Jeżeli chcemy możemy sprawdzać zdarzenia dotyczące rolki (kółka) myszy:

Można także obsługiwać przyciski myszy, SFML obsługuje maksymalnie pięć przycisków: lewy, prawy, środkowy (kółko/rolka) i dwa dodatkowe. Możemy także sprawdzać czy przycisk jest wciśnięty czy puszczony (Event::MouseButtonPressed / Event::MouseBottonReleased).

W przypadku gdy mysz się poruszyła można sprawdzić jej nową (aktualną) pozycję względem okna:

Dosyć przydatną rzeczą może być też sprawdzenie czy mysz jest poza oknem:

 

Joystick


Jeżeli chciałbyś obsługiwać pada w grze to nie ma problemu. SFML wspiera przynajmniej większość kontrolerów. Zanim zaczniesz używać swojego musisz sprawdzić czy kontroler jest podłączony:

Te eventy się uaktywniają gdy pad zostanie podłączony dopiero podczas działania tej pętli. Istnieje jeszcze inny sposób na sprawdzenie tego, ale o tym w innym poradniku.

Tak jak w przypadku innych klawiszy, tak też i tutaj można sprawdzać czy klawisz jest wciśnięty czy puszczony. SFML wspiera maksymalnie do 8 kontrolerów oraz po 32 przyciski na każdy z nich.

Osie joysticków są zazwyczaj bardzo czułe dlatego w SFML stosuje się próg detekcji poruszenia gałką. Możesz go zmienić używajac Window::setJoystickThreshold. Wspierane jest 8 osi joystick’ów: X, Y, Z, R, U, V, POV X i POV Y. Sposób ich mapowania zależy od ich sterownika.

Zdarzenie poruszenia posiada id joysticka, nazwę osi oraz obecną pozycję (w przedziale <-100,100>).

Oryginalny artykuł

Zarządzanie oknem w SFML

Tworzenie okna


W SFML można utworzyć okno w bardzo łatwy sposób, najwygodniej jest je utworzyć poprzez konstruktor, dzięki czemu nie będziemy się musieli bawić w ustawianie go używając dużej ilości metod.

Aby móc używać okna można dodać <SFML/Graphics.hpp> zamiast Window.hpp.

Konstruktor ma kilka możliwych form, w przykładzie powyżej pierwszym argumentem jest konstruktor VideoMode, który przyjmuje argumenty: szerokość okna, wysokość okna, tryb kolorów (opcjonalnie), kolejnym jest nazwa okna, tzw „caption”, czyli napis wyświetlany na pasku tytułu.

Konstruktor może także przyjmować kolejny argument, którym są style okna:

  • Style::None – okno bez żadnych dodatków, nie może być łączony z innymi stylami
  • Style::Titlebar – okno z paskiem tytułu
  • Style::Resize – można zmieniać wielkość okna przez użytkownika, posiada także przycisk do maksymalizowania
  • Style::Close – okno posiada przycisk X (do zamykania)
  • Style::Fullscreen – okno uruchamia się w trybie pełnego ekranu, nie może być łączone z innymi stylami oraz wymaga odpowiednio ustawionego VideoMode
  • Style::Default – standardowy styl, połączenie Resize | Close | Titlebar

Ewentualnie możemy w konstruktorze podać uchwyt do okna i zostanie ono utworzone poprzez użycie np. openGL. Istnieje jeszcze jeden sposób poza konstruktorem który pozwoli nam w łatwy sposób utworzyć nasze okno:

 

Powoływanie okna do życia


Skoro nasz okno zostało już utworzone, przydałoby się je uruchomić. Poniżej mamy standardową główną pętlę gry w SFML

Prześledźmy działanie kodu, pierwsze linie są nam znane jednak dojdźmy do pierwszej pętli while, jest to tzw. pętla główna programu, która powtarza się dopóki nie zostanie utworzone żądanie zakończenia programu. W tym przykładzie używamy metody typu bool, która sprawdza czy okno jest wciąż otwarte.

Następną ciekawostką jest Event, który jest kontenerem zdarzeń i to w nim przechowuje się informacje o np. wciśnięciu określonych klawiszy. Dzięki temu możemy w odpowiedni sposób zareagować.

W kolejnej pętli jest sprawdzenie czy nasz kontener Event jest pełny, jeżeli tak to wykonywane są odpowiednie instrukcje. W tej pętli mamy warunek dla wciśnięcia X (Zamknij) na naszym oknie, konsekwencją tego jest zamknięcie okna. Mógłbyś się zapytać: „czemu okno po wciśnięciu X nie jest zamykane automatycznie?”, a to dlatego że w ten sposób gracz mógłby stracić postępy w grze, dlatego w ten sposób możemy najpierw wywołać funkcję zapisującą grę i dopiero później zamknąć okno.

 

Przykłady niektórych metod


SFML może przyjmować także okna które przygotowaliśmy wcześniej w QT, wxWidgets, czy openGL, jednak nie posiada obsługi niektórych zaawansowanych elementów. Pamiętajmy, że SFML został zbudowany na openGL. Dlatego istnieje także parę metod, które być może będziesz musiał użyć, gdy użyjesz okien z innych bibliotek

Jeżeli jesteś ciekawy działania i użycia innych metod zapraszam do dokumentacji sf::Window.

Tak jak wspomniałem można podać uchwyt (handle) do innego okna. Robi się to w następujący sposób:

Możesz także pobrać uchwyt do okna stworzonego w SFML i użyć w ten sposób funkcji specyficznych dla danego OS.

Instrukcje jak należy to zrobić znajdziesz na różnych stronach, czy też forach. Nie będę się tutaj nad tym rozpisywał.

 

Kontrola FPS


Może się zdarzyć, że podczas działania okna, gdy będzie aplikacja działała szybko będziesz mógł doznać tzw. artefaktów, które będą powodowane przez niezsynchronizowanie odświeżania twojej aplikacji z monitorem. Można to łatwo naprawić:

Po tym wywołaniu twoja aplikacja będzie działała na równi z odświeżaniem monitora czyli 60 fps. Jeżeli chcesz możesz użyć także funkcji:

 

Rzeczy, które powinieneś wiedzieć o oknach


 

  • zamiast sf::Window preferuje się używanie sf::RenderWindow, jego użycie jest takie samo jak metod powyżej
  • możesz stworzyć i mieć uruchomionych więcej niż jedno okno w jednej aplikacji
  • w tej wersji SFML nie jest wspierane wiele monitorów
  • metoda pollEvent musi zostać wywołane w tym samym wątku, w którym zostało utworzone okno
  • na OS X okna i eventy muszą być tworzone (okna) i obsługiwane (eventy) w głównym wątku (main thread)
  • na systemie Windows okno, które jest większe niż pulpit nie zachowuje się prawidłowo, tzn są większe niż okno

Oryginalny artykuł