Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Na tej stronie opisano podstawy programowania certyfikowanych joysticków Xbox One z wykorzystaniem Windows.Gaming.Input.FlightStick i powiązanych interfejsów API platformy uniwersalnej systemu Windows (UWP).
Czytając tę stronę, dowiesz się:
- Jak zebrać listę połączonych joysticków i ich użytkowników
- jak wykryć, że drążek sterowy został dodany lub usunięty
- jak odczytywać dane wejściowe z co najmniej jednego kija lotu
- jak joysticki lotnicze zachowują się jako urządzenia do nawigacji interfejsu użytkownika
Przegląd
Joysticki do gier to urządzenia wejściowe, które są cenione za odtwarzanie uczucia sterowania, jakie można spotkać w kokpicie samolotu lub statku kosmicznego. Są one idealnym urządzeniem wejściowym do szybkiego i dokładnego sterowania lotem. Drążki sterowe są obsługiwane w aplikacjach systemu Windows 10 lub Windows 11 oraz Xbox One za pośrednictwem przestrzeni nazw Windows.Gaming.Input.
Certyfikowane kije lotnicze Xbox One są wyposażone w następujące kontrolki:
- Analogowy drążek sterowy zdolny do przechyłu, pochylenia i odchylenia.
- Analogowa przepustnica
- Dwa przyciski ognia
- 8-drogowy cyfrowy przełącznik kapeluszowy
- przyciski Widok i Menu
Uwaga / Notatka
Przyciski View i Menu są używane do obsługi nawigacji interfejsu użytkownika, a nie do poleceń rozgrywki, a zatem nie można łatwo uzyskiwać do nich dostępu jako przycisków joysticka.
Nawigacja po interfejsie użytkownika
Aby ułatwić obsługę różnych urządzeń wejściowych na potrzeby nawigacji interfejsu użytkownika i w celu ułatwienia spójności między grami i urządzeniami, większość urządzeń wejściowych fizycznych jednocześnie pełni rolę oddzielnych urządzeń wejściowych logicznych nazywanych kontrolerami nawigacji interfejsu użytkownika . Kontroler nawigacji interfejsu użytkownika udostępnia typowe słownictwo dla poleceń nawigacji interfejsu użytkownika na różnych urządzeniach wejściowych.
Jako kontroler nawigacji interfejsu użytkownika kij lotu mapuje
| Polecenie nawigacyjne | Wejście drążka sterowego |
|---|---|
| W górę | Joystick w górę |
| W dół | Strzałka w dół |
| Lewo | Strzałka w lewo |
| Prawo | Strzałka w prawo |
| Widok | przycisk Wyświetl |
| Menu | przycisk menu |
| Akceptuj | przycisk FirePrimary |
| Anuluj | przycisk FireSecondary |
Drążki sterowe nie mapują żadnego z opcjonalnego zestawu poleceń nawigacyjnych.
Wykrywanie i śledzenie drążków sterowych
Wykrywanie i śledzenie drążków sterowych działa w dokładnie taki sam sposób, jak w przypadku kontrolerów do gier, z wyjątkiem użycia klasy FlightStick zamiast klasy Gamepad. Aby uzyskać więcej informacji, zobacz Gamepad i wibrację.
Odczyt drążka sterowego
Po zidentyfikowaniu drążka sterowego, który cię interesuje, możesz pobierać z niego dane. Jednak w przeciwieństwie do niektórych innych rodzajów danych wejściowych, do jakich możesz być przyzwyczajony, joysticki nie komunikują zmiany stanu poprzez generowanie zdarzeń. Zamiast tego należy regularnie odczytywać ich bieżący stan, przeprowadzając sondaż wśród nich.
Odpytywanie drążka sterowego
Sondowanie przechwytuje migawkę drążka sterowego w precyzyjnym momencie czasu. Takie podejście do zbierania danych wejściowych jest dobrym rozwiązaniem dla większości gier, ponieważ ich logika zwykle działa w pętli deterministycznej, a nie w sterowaniu zdarzeniami. Zazwyczaj łatwiej jest również interpretować polecenia gry z danych wejściowych zebranych jednocześnie niż z wielu pojedynczych danych wejściowych zebranych w czasie.
Sondowanie joysticka odbywa się przez wywołanie FlightStick.GetCurrentReading. Ta funkcja zwraca FlightStickReading, który zawiera stan drążka sterowego.
W poniższym przykładzie sprawdza się joystick, aby określić jego bieżący stan.
auto flightStick = myFlightSticks->GetAt(0);
FlightStickReading reading = flightStick->GetCurrentReading();
Oprócz stanu drążka sterowego każdy odczyt zawiera znacznik czasu, który dokładnie wskazuje, kiedy stan został pobrany. Sygnatura czasowa jest przydatna w odniesieniu do chronometrażu poprzednich odczytów lub czasu symulacji gry.
Odczytywanie wejść z joysticka i przepustnicy
Joystick zapewnia odczyt analogowy z przedziału od -1,0 do 1,0 w osiach X, Y i Z (przechyłu, pochylenia i ziewania, odpowiednio). W przypadku przechyłu wartość -1.0 odpowiada skrajnej lewej pozycji drążka, podczas gdy wartość 1.0 odpowiada skrajnej prawej pozycji. W przypadku pochylenia wartość -1,0 odpowiada najniższej pozycji joysticka, a wartość 1,0 najwyższej pozycji. W przypadku yaw wartość -1.0 odpowiada najbardziej przeciwkręciowej pozycji, a wartość 1,0 odpowiada pozycji najbardziej zgodnie z ruchem wskazówek zegara.
We wszystkich osiach wartość wynosi około 0,0, gdy joystick znajduje się w pozycji środkowej, ale normalne jest, że dokładna wartość może się różnić, nawet pomiędzy kolejnymi odczytami. Strategie łagodzenia tej odmiany zostały omówione w dalszej części tej sekcji.
Wartość przechylenia jest odczytywana z właściwości FlightStickReading.Roll, wartość pochylenia jest odczytywana z właściwości FlightStickReading.Pitch, a wartość odchylenia jest odczytywana z właściwości FlightStickReading.Yaw.
// Each variable will contain a value between -1.0 and 1.0.
float roll = reading.Roll;
float pitch = reading.Pitch;
float yaw = reading.Yaw;
Podczas odczytywania wartości drążka zauważysz, że nie generują one niezawodnie neutralnych odczytów o wartości 0,0, gdy drążek znajduje się w spoczynku w pozycji środkowej; zamiast tego będą one wykazywać różne wartości w pobliżu 0,0 za każdym razem, gdy drążek jest przemieszcany i zwracany do pozycji środkowej. Aby zminimalizować te zmienności, można zaimplementować niewielką martwą strefę, czyli zakres wartości w pobliżu idealnej pozycji środkowej, które są ignorowane.
Jednym ze sposobów zaimplementowania martwej strefy jest określenie, jak daleko joystick przesunął się od środka, i ignorowanie odczytów, które są bliżej niż wybrana przez ciebie odległość. Odległość można obliczyć w przybliżeniu — nie jest to dokładne, ponieważ odczyty joysticka są zasadniczo wartościami polarnymi, a nie planarnymi — tylko przy użyciu twierdzenia Pitagorasa. Powoduje to promieniową martwą strefę.
W poniższym przykładzie pokazano podstawową strefę promieniową przy użyciu twierdzenia Pitagorasa.
// Choose a deadzone. Readings inside this radius are ignored.
const float deadzoneRadius = 0.1f;
const float deadzoneSquared = deadzoneRadius * deadzoneRadius;
// Pythagorean theorem: For a right triangle, hypotenuse^2 = (opposite side)^2 + (adjacent side)^2
float oppositeSquared = pitch * pitch;
float adjacentSquared = roll * roll;
// Accept and process input if true; otherwise, reject and ignore it.
if ((oppositeSquared + adjacentSquared) < deadzoneSquared)
{
// Input accepted, process it.
}
Odczytywanie przycisków i przełącznika kapelusza
Każdy z dwóch przycisków ognia drążka sterowego zapewnia cyfrowy odczyt, który wskazuje, czy jest wciśnięty (w dół) lub puszczony (w górę). W celu zwiększenia wydajności odczyty przycisków nie są reprezentowane jako pojedyncze wartości logiczne — zamiast tego wszystkie są zawarte w jednym polu bitowym reprezentowanym przez wyliczenie FlightStickButtons. Ponadto 8-kierunkowy przełącznik kapeluszowy zapewnia kierunek, który jest zapakowany w pojedyncze pole bitowe i reprezentowany przez wyliczenie GameControllerSwitchPosition.
Uwaga / Notatka
Drążki sterowe są wyposażone w dodatkowe przyciski używane do nawigacji interfejsu użytkownika, takie jak przyciski View i Menu. Te przyciski nie są częścią wyliczenia FlightStickButtons i mogą być odczytywane tylko poprzez dostęp do joysticka jako urządzenia nawigacyjnego w interfejsie użytkownika. Aby uzyskać więcej informacji, proszę się zapoznać z kontrolerem nawigacji interfejsu użytkownika.
Wartości przycisku są odczytywane z właściwości FlightStickReading.Buttons. Ponieważ ta właściwość jest polem bitowym, maskowanie bitowe jest używane do izolowania wartości przycisku, który cię interesuje. Przycisk jest wciśnięty (w dół), gdy odpowiedni bit jest ustawiony; w przeciwnym razie jest zwolniony (w górę).
Przykład poniżej określa, czy przycisk FirePrimary jest naciśnięty:
if (FlightStickButtons::FirePrimary == (reading.Buttons & FlightStickButtons::FirePrimary))
{
// FirePrimary is pressed.
}
Poniższy przykład określa, czy przycisk FirePrimary został zwolniony:
if (FlightStickButtons::None == (reading.Buttons & FlightStickButtons::FirePrimary))
{
// FirePrimary is released (not pressed).
}
Czasami możesz chcieć określić, kiedy przycisk przechodzi od naciśnięcia do zwolnienia lub od zwolnienia do naciśnięcia, czy wiele przycisków jest naciśniętych lub zwolnionych, lub czy zestaw przycisków jest rozmieszczony w określony sposób — niektóre są naciśnięte, a inne nie. Aby uzyskać informacje na temat wykrywania każdego z tych stanów, zobacz Wykrywanie przejść przycisków i Wykrywanie złożonych układów przycisków.
Wartość przełącznika kapelusza jest odczytywana z właściwości FlightStickReading.HatSwitch. Ponieważ ta właściwość jest również polem bitowym, maskowanie bitowe jest ponownie używane do izolowania położenia przełącznika kapelusza.
Poniższy przykład określa, czy przełącznik kapelusza znajduje się w pozycji w górę:
if (GameControllerSwitchPosition::Up == (reading.HatSwitch & GameControllerSwitchPosition::Up))
{
// The hat switch is in the up position.
}
Poniższy przykład określa, czy przełącznik kapelusza znajduje się w pozycji środkowej:
if (GameControllerSwitchPosition::Center == (reading.HatSwitch & GameControllerSwitchPosition::Center))
{
// The hat switch is in the center position.
}