Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questa pagina descrive le nozioni di base della programmazione per joystick di volo certificati Xbox One usando Windows.Gaming.Input.FlightStick e le API correlate per la piattaforma UWP (Universal Windows Platform).
Leggendo questa pagina, si apprenderà quanto segue:
- come creare un elenco di joystick di volo connessi e i relativi utenti
- come rilevare che un bastone di volo è stato aggiunto o rimosso
- come leggere l'input da uno o più bastoncini di volo
- come i joystick di volo si comportano come dispositivi di navigazione nell'interfaccia utente
Informazioni generali
Le cloche di volo sono dispositivi di input di gioco apprezzati per riprodurre la sensazione delle cloche di volo che si trovano nella cabina di pilotaggio di un aereo o di un'astronave. Sono il dispositivo di input perfetto per un controllo rapido e accurato del volo. I joystick sono supportati nelle app di Windows 10 o Windows 11 e Xbox One tramite il namespace Windows.Gaming.Input.
I bastoncini di volo certificati Xbox One sono dotati dei controlli seguenti:
- Un joystick analogico torcibile in grado di rotolare, inclinazione e yaw
- Un acceleratore analogico
- Due pulsanti di fuoco
- Un interruttore a cappello digitale a 8 direzioni
- Pulsanti visualizzazione e menu
Annotazioni
I pulsanti Visualizza e Menu vengono usati per supportare la navigazione dell'interfaccia utente, non i comandi di gioco, e pertanto non possono essere facilmente accessibili come pulsanti del joystick.
Navigazione nell'interfaccia utente
Per semplificare il carico di supporto dei diversi dispositivi di input per lo spostamento dell'interfaccia utente e per incoraggiare la coerenza tra giochi e dispositivi, la maggior parte dei dispositivi di input fisici fisica agisce simultaneamente come dispositivi di input logici chiamati controller di spostamento interfaccia utente . Il controller di navigazione dell'interfaccia utente fornisce un vocabolario comune per i comandi di navigazione dell'interfaccia utente attraverso i dispositivi di input.
Come controller di spostamento interfaccia utente, un bastone di volo esegue il mapping dei necessari di comandi di spostamento al joystick e Visualizza, Menu, FirePrimarye pulsanti FireSecondary.
Comando di navigazione | Input della levetta in anteprima |
---|---|
Attivo | Joystick in alto |
Giù | Joystick verso il basso |
Sinistra | Joystick sinistro |
Giusto | Joystick a destra |
Visualizza | pulsante Visualizza |
Menù | menu pulsante |
Accettare | pulsante FirePrimary |
Annulla | pulsante FireSecondario |
I joystick non eseguono il mapping di nessuno dei set facoltativi dei comandi di navigazione.
Rilevare e monitorare i joystick di volo
Il rilevamento e il tracciamento delle levette di volo funzionano esattamente come per i game pad, ad eccezione della classe FlightStick
Lettura del bastone di volo
Dopo aver identificato il bastone di volo a cui sei interessato, sei pronto a raccogliere l'input da esso. Tuttavia, a differenza di altri tipi di input che potresti usare, i joystick non comunicano la modifica dello stato generando eventi. Invece, prendi letture regolari del loro stato corrente effettuando il polling.
Campionamento del joystick
Il polling acquisisce uno snapshot del bastone di volo in un momento preciso. Questo approccio alla raccolta di input è ideale per la maggior parte dei giochi, perché la logica viene in genere eseguita in un ciclo deterministico anziché basata su eventi. In genere è anche più semplice interpretare i comandi del gioco dall'input raccolto in una sola volta rispetto a molti input singoli raccolti nel corso del tempo.
Si interroga una cloche di volo chiamando FlightStick.GetCurrentReading. Questa funzione restituisce un FlightStickReading che contiene lo stato della levetta di volo.
Nell'esempio seguente si effettua il polling di un joystick per il suo stato corrente:
auto flightStick = myFlightSticks->GetAt(0);
FlightStickReading reading = flightStick->GetCurrentReading();
Oltre allo stato della levetta di comando, ogni lettura include un timestamp che indica esattamente quando è stato recuperato lo stato. Il timestamp è utile per la correlazione tra la tempistica delle letture precedenti o la tempistica della simulazione del gioco.
Lettura dell'input del joystick e della manetta
Il joystick fornisce una lettura analogica tra -1,0 e 1,0 rispettivamente negli assi X, Y e Z (rotolo, inclinazione e yaw). Per il roll, il valore -1,0 corrisponde alla posizione del joystick più a sinistra, mentre il valore 1,0 corrisponde alla posizione più a destra. Per il passo, il valore -1,0 corrisponde alla posizione del joystick più in basso, mentre il valore 1,0 corrisponde alla posizione superiore. Per l'imbardata, il valore -1,0 corrisponde alla posizione più ruotata in senso antiorario, mentre il valore 1,0 corrisponde alla posizione più in senso orario.
In tutti gli assi, il valore è circa 0,0 quando il joystick si trova nella posizione centrale, ma è normale che il valore preciso possa variare, anche tra letture successive. Le strategie per ridurre questa variante sono illustrate più avanti in questa sezione.
Il valore del roll del joystick viene letto dalla proprietà
// Each variable will contain a value between -1.0 and 1.0.
float roll = reading.Roll;
float pitch = reading.Pitch;
float yaw = reading.Yaw;
Quando si legge i valori del joystick, si noterà che non producono in modo affidabile una lettura neutra di 0,0 quando il joystick è inattivo nella posizione centrale; producono invece valori diversi vicino a 0,0 ogni volta che il joystick viene spostato e restituito alla posizione centrale. Per attenuare queste variazioni, è possibile implementare una piccola zona morta, ovvero un intervallo di valori vicino alla posizione centrale ideale ignorata.
Un modo per implementare una zona morta consiste nel determinare quanto lontano il joystick si è spostato dal centro e ignorare le letture che sono più vicine a una distanza scelta. È possibile calcolare la distanza approssimativamente, non è esatta perché le letture del joystick sono essenzialmente valori polari, non planari, usando solo il teorema di Pitagora. In questo modo viene generata una zona morta radiale.
L'esempio seguente illustra una zona morta radiale di base usando il teorema pythagore:
// 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.
}
Lettura dei pulsanti e del controllo a cappello
Ognuno dei due pulsanti di fuoco del bastone di volo fornisce una lettura digitale che indica se è premuto (giù) o rilasciato (su). Per efficienza, le letture dei pulsanti non sono rappresentate come singoli valori booleani, ma sono tutti incorporati in un unico bitfield rappresentato dall'enumerazione FlightStickButtons. Inoltre, l'interruttore cappello a 8 vie fornisce una direzione compressa in un singolo campo di bit rappresentato dall'enumerazione GameControllerSwitchPosition.
Annotazioni
I joystick di volo sono dotati di pulsanti aggiuntivi utilizzati per la navigazione dell'interfaccia utente, come i pulsanti Visualizzazione e Menu. Questi pulsanti non fanno parte dell'enumerazione FlightStickButtons
e possono essere letti solo accedendo alla levetta di comando come dispositivo di navigazione dell'interfaccia utente. Per altre informazioni, vedere controller di navigazione dell'interfaccia utente.
I valori dei pulsanti vengono letti dalla proprietà FlightStickReading.Buttons. Poiché questa proprietà è un campo di bit, il mascheramento bit per bit viene usato per isolare il valore del pulsante di cui sei interessato. Il pulsante viene premuto (verso il basso) quando viene impostato il bit corrispondente; se no, viene rilasciato (in alto).
Nell'esempio seguente viene determinato se il pulsante FirePrimary è premuto:
if (FlightStickButtons::FirePrimary == (reading.Buttons & FlightStickButtons::FirePrimary))
{
// FirePrimary is pressed.
}
Nell'esempio seguente viene determinato se il pulsante FirePrimary viene rilasciato:
if (FlightStickButtons::None == (reading.Buttons & FlightStickButtons::FirePrimary))
{
// FirePrimary is released (not pressed).
}
A volte potresti voler determinare quando un pulsante passa da premuto a rilasciato o da rilasciato a premuto, se più pulsanti vengono premuti o rilasciati o se un insieme di pulsanti è disposto in modo particolare, con alcuni premuti e altri no. Per informazioni su come rilevare ognuna di queste condizioni, vedere Rilevamento delle transizioni dei pulsanti e Rilevamento di disposizioni complesse dei pulsanti.
Il valore di HatSwitch viene letto dalla proprietà FlightStickReading.HatSwitch. Poiché questa proprietà è anche un campo bit, il mascheramento bitwise viene usato di nuovo per isolare la posizione del hat switch.
L'esempio seguente determina se l'interruttore del cappello si trova nella posizione su:
if (GameControllerSwitchPosition::Up == (reading.HatSwitch & GameControllerSwitchPosition::Up))
{
// The hat switch is in the up position.
}
L'esempio seguente determina se il pulsante direzionale (hat switch) si trova nella posizione centrale:
if (GameControllerSwitchPosition::Center == (reading.HatSwitch & GameControllerSwitchPosition::Center))
{
// The hat switch is in the center position.
}