Erkennen von "Beliebiger Tastendruck"


10

Ich versuche, dem Player zu erlauben, eine beliebige Taste zu drücken, um von der Hauptseite fortzufahren. Ich konnte dies tun, indem ich eine Liste von Schaltflächen erstellte, diese durchlief und überprüfte, ob eine davon ausgefallen war. Ich finde diesen Code jedoch irgendwie hässlich und frage mich, ob es einen einfacheren Weg gibt, an den ich einfach nicht denke.

So sieht mein Code jetzt aus:

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

Ich persönlich würde nur eine große IF-Schleife erstellen, anstatt ein Array und eine Schleife zu erstellen.
Jgallant

@ Jon Was ist eine große IF-Schleife und warum wäre es besser?
Craftworkgames

Ich liebe die Antwort, die diese Frage erhält. Ich denke, @Katu hat die "richtige" Antwort bekommen.
Seth Battin

Antworten:


10

Dies sollte den Job machen. Speichern Sie am Ende jeder Aktualisierungsschleife den Status von previousGamePadState. Dann kannst du sie vergleichen. Dies ist ein schneller Weg, um Änderungen zu erkennen. Keine Notwendigkeit zu schleifen.

GamePadState.PacketNumber :

Mit PacketNumber können Sie feststellen, ob sich der Eingabestatus geändert hat. Wenn der Wert von PacketNumber zwischen zwei aufeinander folgenden Aufrufen von GetState gleich bleibt, hat sich die Eingabe nicht geändert.

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

BEARBEITEN: In Methode geändert. Es ist nicht garantiert, dass es richtig funktioniert, sollte aber funktionieren. Da dies tatsächlich Änderungen in der Eingabe erkennt, wird dies auch angezeigt, wenn der Benutzer die Schaltfläche loslässt. Ich habe auch hinzugefügt if, um die Bewegung des Daumensticks zu erkennen, sodass Sie diese zumindest ignorieren können.

Hoffe das hilft dir. Lassen Sie mich wissen, wenn es nicht Ihren Bedürfnissen entspricht, können wir das sicher klären.

Gewusst wie: Ermitteln, ob eine Controller-Taste auf diese Frame- GamePadState.PacketNumber-Eigenschaft gedrückt wurde


Es gibt eine analoge Möglichkeit, dies für GamePadStateund zu schreiben enum Buttons, die näher an dem Kontext liegt, den das OP zu verwenden scheint.
Seth Battin

1
Sollte vor dem Morgenkaffee nichts beantworten :)
Katu

1
Jetzt macht es den Job und schneller geht es nicht.
Katu

Whoa, eine völlig andere Methode, und ich denke, Sie haben Recht damit, dass es die schnellste ist. Nett.
Seth Battin

Erkennt das nur Tastendrücke oder erkennt es auch Tastenfreigaben?
George Duckett

1

Wenn Ihnen die Verwendung von Reflection nichts ausmacht, können Sie so etwas verwenden (möglicherweise sogar genau das):

        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

Sie können ein LeerzeichenGamePadState manuell erstellen und es dann auf (Un-) Gleichheit mit dem aktuellen realen prüfen , das Sie durch Aufrufen abrufen 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.

}

Ich habe keine Ahnung, ob das funktioniert; Ich habe es nie versucht. Lassen Sie mich wissen, ob es für Sie funktioniert.
Seth Battin

Clevere Idee, obwohl sie nur funktioniert, wenn GamePadState Equals überschreibt, was unwahrscheinlich ist. Höchstwahrscheinlich wird die Referenzgleichheit verwendet, und daher wird die obige if-Anweisung niemals als wahr bewertet.
Craftworkgames

@craftworkgames Equalsist anders; Es vergleicht zwei Referenzen, um dieselbe Instanz zu sein. Überlädt GamePadStateaber den Operator ==, um seine Werte zu vergleichen, auf die ich in meiner Antwort ( op_Equality) verwiesen habe .
Seth Battin

Eigentlich wusste ich nicht, dass GamePadState eine Struktur ist, die wahrscheinlich funktionieren würde. Technisch gesehen ist das Verhalten von Equals und == oft das gleiche, natürlich hängt es von der Implementierung ab, aber die Richtlinien empfehlen es auf diese Weise. Wenn Sie wirklich Referenz Gleichheit wollen Sie auch , dass es object.ReferenceEquals msdn.microsoft.com/en-us/library/bsc2ak47.aspx
craftworkgames

Ah, Sie haben Recht, GamePadState ist ein Werttyp, daher ist er nicht relevant. Unabhängig davon, == ist überladen, könnte es genauso gut IMO verwenden.
Seth Battin

1

Da Buttons eine Aufzählung ist, können Sie die Enum.GetValues- Methode wie folgt verwenden:

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

foreach (var button in buttonList)
{
    if (GamePad.GetState(PlayerIndex.One).IsButtonDown(button))
        ExitMainMenu= true;
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.