Rilevamento di "qualsiasi pulsante premuto"


10

Sto cercando di consentire al giocatore di premere qualsiasi pulsante per continuare dalla pagina principale. Sono stato in grado di farlo facendo un elenco di pulsanti e scorrendo questi e verificando che uno di essi fosse inattivo; tuttavia, mi sembra che questo codice sia un po 'brutto e mi chiedo se c'è un modo più semplice per farlo che non sto pensando?

Ecco il mio aspetto del mio codice ora:

            if (GamePad.GetState(PlayerIndex.One).IsConnected)
            {
                var buttonList = new List<Buttons>()
                {
                    {Buttons.A},
                    {Buttons.B},
                    {Buttons.Y},
                    {Buttons.X},
                    {Buttons.Start},
                    {Buttons.Back},
                    {Buttons.RightShoulder},
                    {Buttons.LeftShoulder},
                    {Buttons.RightTrigger},
                    {Buttons.LeftTrigger}
                };

                foreach (var button in buttonList)
                {
                    if (GamePad.GetState(PlayerIndex.One).IsButtonDown(button))
                        ExitMainMenu= true;
                }
            }

Personalmente farei solo un grande loop IF, invece di creare un array e un looping.
jgallant,

@Jon Che cos'è un grande loop IF e perché dovrebbe essere migliore?
craftworkgames

Adoro tutta la risposta che sta ricevendo questa domanda. Penso che @Katu abbia ottenuto la risposta "corretta" però.
Seth Battin,

Risposte:


10

Questo dovrebbe fare il lavoro. Alla fine di ogni ciclo di aggiornamento, salva lo stato di previousGamePadState. Quindi puoi confrontarli. Questo è un modo rapido per rilevare le modifiche. Non è necessario eseguire il loop.

GamePadState.PacketNumber :

È possibile utilizzare PacketNumber per determinare se lo stato di input è stato modificato. Se il valore di PacketNumber rimane lo stesso tra due chiamate sequenziali a GetState, non si è verificato alcun cambiamento nell'input.

public bool HasInputChanged(GamePadState previousGamePadState, bool ignoreThumbsticks)
{ 
    GamePadState currentState = GamePad.GetState( PlayerIndex.One );
    if ((currentState.IsConnected) && (currentState.PacketNumber != previousGamePadState.PacketNumber))
    {
        //ignore thumbstick movement
        if ((ignoreThumbsticks == true) && ((currentState.ThumbSticks.Left.Length() != previousGamePadState.ThumbSticks.Left.Length() )&&(currentState.ThumbSticks.Right.Length() != previousGamePadState.ThumbSticks.Right.Length()) ))
            return false;
        return true
    }
    return false;
}

EDIT: modificato al metodo. Non è garantito per funzionare così come è, ma dovrebbe funzionare. Inoltre, poiché questo rileva davvero i cambiamenti nell'input, quindi se l'utente rilascia il pulsante, lo si vede anche con questo. Ho anche aggiunto ifper rilevare il movimento della levetta, quindi puoi ignorarli almeno.

Spero che questo ti aiuti. Fammi sapere, se non soddisfa le tue esigenze, sono sicuro che potremo risolverlo.

Procedura: rilevare se è stato premuto un pulsante del controller in questo frame Proprietà GamePadState.PacketNumber


C'è un modo analogo di scrivere questo per GamePadStatee enum Buttons, che è più vicino al contesto che l'OP sembra usare.
Seth Battin,

1
Non dovrebbe rispondere a niente prima del caffè del mattino :)
Katu

1
Ora fa il lavoro e non può andare più veloce di così.
Katu il

Whoa, metodo completamente diverso, e penso che tu abbia ragione sul fatto che sia il più veloce. Bello.
Seth Battin,

Rileva solo la pressione dei pulsanti o rileva anche il rilascio dei pulsanti?
George Duckett,

1

Se non ti dispiace l'uso di Reflection, puoi usare qualcosa del genere (forse anche esattamente):

        var properties = typeof(GamePadButtons).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (var property in properties)
        {
            var value = property.GetValue(GamePad.GetState(PlayerIndex.One).Buttons);
            if (value is ButtonState && (ButtonState)value == ButtonState.Pressed)
                ExitMainMenu = true;
        }

1

È possibile costruireGamePadState manualmente un vuoto , quindi verificarne l'uguaglianza (in) con quella reale corrente, che si recupera chiamando GamePad.GetState.

playerInput = GamePad.GetState(PlayerIndex.One);  
emptyInput = new GamePadState(Vector2.Zero, Vector2.Zero, 0, 0);
if (playerInput != emptyInput){

    // yay!!!!, a button push!
    // 
    // P.S., remember to allow any PlayerIndex to take control of the the game 
    // from the main menu.  It sucks when you pick up controller2 and it doesn't work.

}

Non ho idea se questo funziona; Non ho mai provato a farlo. Fammi sapere se funziona per te.
Seth Battin,

Un'idea intelligente, sebbene funzionerà solo se GamePadState sostituisce Equals, il che è improbabile. Molto probabilmente, utilizzerà l'uguaglianza di riferimento e quindi la precedente istruzione if non valuterà mai come vera.
craftworkgames

@craftworkgames Equalsè diverso; confronta due riferimenti per essere la stessa istanza. Ma GamePadStatesovraccarica l'operatore == per confrontare i loro valori, a cui ho collegato nella mia risposta ( op_Equality).
Seth Battin,

In realtà non mi rendevo conto che GamePadState era una struttura che probabilmente avrebbe funzionato. Tecnicamente, il comportamento di Equals e == è spesso lo stesso, ovviamente dipende dall'implementazione ma le linee guida lo raccomandano in questo modo. Se si vuole veramente l'uguaglianza di riferimento si c'è anche object.ReferenceEquals msdn.microsoft.com/en-us/library/bsc2ak47.aspx
craftworkgames

Ah hai ragione, GamePadState è un tipo di valore, quindi non è rilevante. Indipendentemente da ciò, == è sovraccarico, potrebbe anche usarlo IMO.
Seth Battin,

1

Poiché Buttons è un enumaration, puoi usare il metodo Enum.GetValues ​​in questo modo:

var buttonList = (Buttons[])Enum.GetValues(typeof(Buttons));

foreach (var button in buttonList)
{
    if (GamePad.GetState(PlayerIndex.One).IsButtonDown(button))
        ExitMainMenu= true;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.