Détection de «n'importe quel appui sur un bouton»


10

J'essaie de permettre au joueur d'appuyer sur n'importe quel bouton pour continuer à partir de la page principale. J'ai pu le faire en faisant une liste de boutons et en les parcourant et en vérifiant que l'un d'entre eux était en panne; cependant, j'ai l'impression que ce code est un peu moche et je me demande s'il existe un moyen plus simple de le faire auquel je ne pense tout simplement pas?

Voici à quoi ressemble mon code maintenant:

            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;
                }
            }

Personnellement, je ferais juste une grosse boucle IF, au lieu de créer un tableau et de boucler.
jgallant

@Jon Qu'est-ce qu'une grande boucle IF et pourquoi serait-elle meilleure?
craftworkgames

J'adore toutes les réponses que cette question reçoit. Je pense que @Katu a obtenu la "bonne" réponse.
Seth Battin

Réponses:


10

Cela devrait faire l'affaire. À la fin de chaque boucle de mise à jour, enregistrez l'état de previousGamePadState. Ensuite, vous pouvez les comparer. C'est un moyen rapide de détecter les changements. Pas besoin de boucler.

GamePadState.PacketNumber :

Vous pouvez utiliser PacketNumber pour déterminer si l'état d'entrée a changé. Si la valeur de PacketNumber reste la même entre deux appels séquentiels à GetState, il n'y a eu aucun changement d'entrée.

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: changé en méthode. Il n'est pas garanti de fonctionner correctement, mais devrait fonctionner. De plus, parce que cela détecte vraiment les changements d'entrée, donc si l'utilisateur relâche le bouton, cela se voit également. J'ai également ajouté ifpour détecter le mouvement de la baguette, afin que vous puissiez au moins les ignorer.

J'espère que cela vous aidera. Faites-le moi savoir, si cela ne correspond pas à vos besoins, je suis sûr que nous pouvons régler cela.

Comment: détecter si un bouton de contrôleur a été enfoncé dans cette propriété FramePadState.PacketNumber


Il existe une manière analogue d'écrire ceci pour GamePadStateet enum Buttons, qui est plus proche du contexte que l'OP semble utiliser.
Seth Battin

1
Ne devrait rien répondre avant le café du matin :)
Katu

1
Maintenant, il fait le travail et ne peut pas aller plus vite que cela.
Katu

Whoa, méthode totalement différente, et je pense que vous avez raison de dire que c'est la plus rapide. Agréable.
Seth Battin

Cela détecte-t-il uniquement les pressions sur les boutons ou détecte-t-il également les relâchements des boutons?
George Duckett

1

Si cela ne vous dérange pas l'utilisation de Reflection, vous pouvez utiliser quelque chose comme ça (peut-être même exactement cela):

        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

Vous pouvez manuellement construire un videGamePadState , puis le vérifier pour (in) l'égalité avec le réel actuel, que vous récupérez en appelant 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.

}

Je n'ai aucune idée si cela fonctionne; Je n'ai jamais essayé de le faire. Faites-moi savoir si cela fonctionne pour vous.
Seth Battin

Idée intelligente, même si cela ne fonctionnera que si GamePadState remplace Equals, ce qui est peu probable. Très probablement, il utilisera l'égalité de référence et donc l'instruction if ci-dessus ne sera jamais évaluée à true.
craftworkgames

@craftworkgames Equalsest différent; il compare deux références pour être la même instance. Mais GamePadStatesurcharge l'opérateur == pour comparer leurs valeurs, auxquelles j'ai lié dans ma réponse ( op_Equality).
Seth Battin

En fait, je ne savais pas que GamePadState était une structure qui fonctionnerait probablement. Techniquement cependant, le comportement de Equals et == est souvent le même, bien sûr, cela dépend de l'implémentation mais les directives le recommandent de cette façon. Si vous voulez vraiment l'égalité de référence, il y a aussi object.ReferenceEquals msdn.microsoft.com/en-us/library/bsc2ak47.aspx
craftworkgames

Ah vous avez raison, GamePadState est un type de valeur, donc ce n'est pas pertinent. Quoi qu'il en soit, == est surchargé, pourrait aussi bien l'utiliser IMO.
Seth Battin

1

Étant donné que les boutons sont une énumération, vous pouvez utiliser la méthode Enum.GetValues comme ceci:

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

foreach (var button in buttonList)
{
    if (GamePad.GetState(PlayerIndex.One).IsButtonDown(button))
        ExitMainMenu= true;
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.