Delen via


vluchtstick

Op deze pagina worden de basisbeginselen beschreven van programmeren voor Xbox One-gecertificeerde flightsticks met behulp van Windows.Gaming.Input.FlightStick en gerelateerde API's voor het Universal Windows Platform (UWP).

Door deze pagina te lezen, leert u het volgende:

  • hoe je een lijst kunt verzamelen van verbonden flightsticks en hun gebruikers
  • hoe te detecteren dat een vluchtstick is toegevoegd of verwijderd
  • hoe je invoer leest van een of meer joysticks
  • hoe flight sticks zich gedragen als UI-navigatieapparaten

Overzicht

Flightsticks zijn gaming-invoerapparaten die worden gewaardeerd omdat ze lijken op de stuurknuppels die je in de cockpit van een vliegtuig of ruimteschip zou vinden. Ze zijn het perfecte invoerapparaat voor snelle en nauwkeurige controle van de vlucht. Flight sticks worden ondersteund in Windows 10 en Windows 11, evenals in Xbox One-apps via de Windows.Gaming.Input naamruimte.

Xbox One-gecertificeerde vluchtsticks zijn uitgerust met de volgende besturingselementen:

  • Een draaibare analoge joystick die in staat is tot rollen, pitchen en gieren.
  • Een analoge gasklep
  • Twee vuurknoppen
  • Een 8-weg digitale hatschakelaar
  • Bekijk en Menu knoppen

Opmerking

De knoppen Weergave en Menu worden gebruikt om navigatie in de gebruikersinterface te ondersteunen, geen gameplay-opdrachten en kunnen daarom niet direct worden geopend als stickknoppen.

Navigatie in de gebruikersinterface

Om de belasting van de verschillende invoerapparaten voor navigatie in de gebruikersinterface te vereenvoudigen en consistentie tussen games en apparaten te stimuleren, fungeren de meeste fysieke invoerapparaten tegelijkertijd als afzonderlijke logische invoerapparaten genaamd UI-navigatiecontrollers. De UI-navigatiecontroller biedt een algemene woordenlijst voor UI-navigatieopdrachten op invoerapparaten.

Als navigatiecontroller van de gebruikersinterface wijst een flight stick de vereist van navigatieopdrachten toe aan de joystick en View, Menu, FirePrimaryen FireSecondary knoppen.

Navigatieopdracht Invoer van vluchtstick
Omhoog Joystick omhoog
Omlaag Joystick omlaag
Links Joystick links
Rechts Joystick rechts
Bekijk knop weergeven
Menulijst Menu knop
Accepteren FirePrimary knop
Annuleren Knop FireSecondary

Flight sticks koppelen geen enkele van de optionele set navigatieopdrachten.

Vluchtsticks detecteren en volgen

Het detecteren en volgen van vluchtsticks werkt op exact dezelfde manier als voor gamepads, behalve met de FlightStick-klasse in plaats van de Gamepad klasse. Zie Gamepad en trillingen voor meer informatie.

De vluchtstick lezen

Nadat u de flightstick hebt geïdentificeerd waarin u geïnteresseerd bent, kunt u de input ervan verzamelen. In tegenstelling tot andere soorten invoer waarmee u misschien bekend bent, geven flightsticks echter geen statuswijzigingen door via het activeren van evenementen. In plaats daarvan voert u regelmatige metingen van hun huidige status uit door hen te peilen.

De vluchtstick peilen

Polling legt een momentopname van de vluchtstick vast op een nauwkeurig tijdstip. Deze methode voor het verzamelen van invoer is geschikt voor de meeste games, omdat hun logica doorgaans wordt uitgevoerd in een deterministische lus in plaats van gebeurtenisgestuurd te zijn. Het is meestal ook eenvoudiger om gameopdrachten te interpreteren van invoer die allemaal tegelijk zijn verzameld dan van veel enkele invoer die in de loop van de tijd is verzameld.

U peilt een vluchtstick door FlightStick.GetCurrentReadingaan te roepen. Deze functie retourneert een FlightStickReading die de toestand van de flightstick bevat.

In het volgende voorbeeld wordt een vluchtstick gecontroleerd op de huidige status:

auto flightStick = myFlightSticks->GetAt(0);
FlightStickReading reading = flightStick->GetCurrentReading();

Naast de status van de vluchtstick bevat elke lezing een tijdstempel die precies aangeeft wanneer de status is opgehaald. De tijdstempel is handig voor het bepalen van de timing van eerdere metingen of de timing van de gamesimulatie.

Lezen van de joystick- en gashendelinvoer

De joystick biedt een analoge lezing tussen -1.0 en 1.0 in de X-, Y- en Z-assen (rol, pitch en yaw, respectievelijk). Voor rollen komt een waarde van -1,0 overeen met de meest linkse stickpositie, terwijl een waarde van 1,0 overeenkomt met de meest rechtse positie. Voor pitch komt een waarde van -1,0 overeen met de meest onderste stickpositie, terwijl een waarde van 1,0 overeenkomt met de hoogste positie. Voor yaw komt een waarde van -1,0 overeen met de meest rechtsom draaiende positie, terwijl een waarde van 1,0 overeenkomt met de meest rechtsom geplaatste positie.

In alle assen is de waarde ongeveer 0,0 wanneer de stick zich in de middelste positie bevindt, maar het is normaal dat de exacte waarde varieert, zelfs tussen volgende metingen. Strategieën voor het beperken van deze variatie worden verderop in deze sectie besproken.

De waarde van de joystick's roll wordt gelezen uit de eigenschap FlightStickReading.Roll, de waarde van de pitch wordt gelezen uit de eigenschap FlightStickReading.Pitch, en de waarde van de yaw wordt gelezen uit de eigenschap 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;

Wanneer u de joystickwaarden leest, zult u merken dat ze niet betrouwbaar een neutrale lezing van 0,0 produceren wanneer de stick in rust is op de middenpositie; In plaats daarvan produceren ze verschillende waarden in de buurt van 0,0 telkens wanneer de joystick wordt verplaatst en teruggezet naar de middenpositie. Als u deze variaties wilt beperken, kunt u een kleine deadzoneimplementeren. Dit is een bereik met waarden in de buurt van de ideale middenpositie die worden genegeerd.

Een manier om een deadzone te implementeren, is om te bepalen hoe ver de joystick van het centrum is verplaatst en leesingen negeert die groter zijn dan een bepaalde afstand die u kiest. U kunt de afstand ruwweg berekenen—het is niet exact omdat de joystickmetingen in wezen polair zijn en niet planar—gewoon door gebruik te maken van de Pythagorese stelling. Dit produceert een radiale deadzone.

In het volgende voorbeeld ziet u een eenvoudige radiale deadzone met behulp van de Pythagorese theorema:

// 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.
}

De knoppen en hoedschakelaar lezen

Elk van de twee vuurknoppen van de vluchtstick biedt een digitale lezing die aangeeft of deze wordt ingedrukt (omlaag) of vrijgegeven (omhoog). Voor efficiëntie worden knopmetingen niet weergegeven als afzonderlijke Booleaanse waarden. In plaats daarvan worden ze allemaal verpakt in één bitveld dat wordt vertegenwoordigd door de FlightStickButtons opsomming. Bovendien biedt de 8-way hatswitch een richting die in één bitveld is verpakt en wordt vertegenwoordigd door de GameControllerSwitchPosition enumeratie.

Opmerking

Flight sticks zijn uitgerust met extra knoppen die worden gebruikt voor ui-navigatie, zoals de knoppen Weergave en Menu. Deze knoppen maken geen deel uit van de opsomming FlightStickButtons en kunnen alleen worden gelezen door de flight stick te openen als navigatieapparaat voor de gebruikersinterface. Zie ui-navigatiecontrollervoor meer informatie.

De knopwaarden worden gelezen uit de eigenschap FlightStickReading.Buttons. Omdat deze eigenschap een bitfield is, wordt bitwise maskering gebruikt om de waarde te isoleren van de knop waarin u geïnteresseerd bent. De knop wordt ingedrukt (omlaag) wanneer de bijbehorende bit is ingesteld; anders wordt deze losgelaten (omhoog).

In het volgende voorbeeld wordt bepaald of de knop FirePrimary wordt ingedrukt:

if (FlightStickButtons::FirePrimary == (reading.Buttons & FlightStickButtons::FirePrimary))
{
    // FirePrimary is pressed.
}

In het volgende voorbeeld wordt bepaald of de knop FirePrimary wordt vrijgegeven:

if (FlightStickButtons::None == (reading.Buttons & FlightStickButtons::FirePrimary))
{
    // FirePrimary is released (not pressed).
}

Soms wilt u misschien bepalen wanneer een knop overgaat van ingedrukt naar losgelaten of van losgelaten naar ingedrukt, of er meerdere knoppen worden ingedrukt of losgelaten, of dat een set knoppen op een bepaalde manier is gerangschikt—sommige ingedrukt, sommige niet. Zie Knopovergangen detecteren en Complexe knopindelingen detecterenvoor meer informatie over het detecteren van deze voorwaarden.

De waarde van de hatswitch wordt uit de eigenschap FlightStickReading.HatSwitch gelezen. Omdat deze eigenschap ook een bitfield is, wordt bitwise maskering opnieuw gebruikt om de positie van de hoedschakelaar te isoleren.

In het volgende voorbeeld wordt bepaald of de hoedschakelaar zich in de bovenpositie bevindt.

if (GameControllerSwitchPosition::Up == (reading.HatSwitch & GameControllerSwitchPosition::Up))
{
    // The hat switch is in the up position.
}

In het volgende voorbeeld wordt bepaald of de hoedschakelaar zich in de middelste positie bevindt:

if (GameControllerSwitchPosition::Center == (reading.HatSwitch & GameControllerSwitchPosition::Center))
{
    // The hat switch is in the center position.
}

Zie ook