Виявлення "Будь-якого натискання кнопки"


10

Я намагаюся дозволити гравцеві натиснути будь-яку кнопку, щоб продовжити на головній сторінці. Я зміг це зробити, створивши список кнопок і переглянувши їх і перевіривши, чи не знищується одна з них; однак я відчуваю, що цей код такий некрасивий, і мені цікаво, чи існує простіший спосіб зробити це, про що я просто не думаю?

Ось як виглядає мій код зараз:

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

Я особисто просто зробив великий цикл IF, на відміну від створення масиву та циклічного циклу.
jgallant

@Jon Що таке великий цикл IF, і чому це було б краще?
craftworkgames

Я люблю всі відповіді, які отримує це питання. Я думаю, що @Katu отримав "правильну" відповідь.
Сет Беттін

Відповіді:


10

Це має зробити роботу. Наприкінці кожного циклу оновлення збережіть стан previousGamePadState. Тоді ви можете порівняти їх. Це швидкий спосіб виявити зміни. Немає необхідності в циклі.

GamePadState.PacketNumber :

Ви можете використовувати PacketNumber, щоб визначити, чи змінився стан вводу. Якщо значення PacketNumber залишається однаковим між двома послідовними дзвінками до GetState, то зміни введення не відбулися.

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: Змінено на метод. Це не гарантовано працювати правильно, як є, але має працювати. Крім того, оскільки це дійсно виявляє зміни у введенні, тож якщо користувач відпускає кнопку, це спостерігається і з цим. Я також додав ifдля виявлення руху пальчикової палички, щоб ви могли принаймні їх ігнорувати.

Сподіваюся, що це вам допоможе. Повідомте мене, якщо це не відповідає вашим потребам, я впевнений, що ми зможемо це вирішити.

Як: Виявити, чи натиснула кнопка контролера цю рамку властивості GamePadState.PacketNumber


Існує аналогічний спосіб написання цього запису GamePadStateі enum Buttons, який ближче до контексту, як видається, використовує ОП.
Сет Беттін

1
Не слід нічого відповідати перед ранковою кавою :)
Кату

1
Тепер він робить цю роботу, і не може отримати швидше, ніж це.
Кату

Ого, абсолютно інший метод, і я думаю, ти маєш рацію в тому, щоб він був найшвидшим. Приємно.
Сет Беттін

Чи виявляє це лише натискання кнопок, або воно також виявляє звільнення кнопок?
Джордж Дакетт

1

Якщо ви не заперечуєте проти використання Reflection, ви можете використовувати щось подібне (можливо, навіть саме таке):

        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

Ви можете вручну побудувати порожнійGamePadState , а потім перевірити його на (не) рівність з поточним реальним, який ви отримуєте, зателефонувавши 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.

}

Я не маю уявлення, чи це працює; Я ніколи не намагався це зробити. Дайте мені знати, чи виходить у вас.
Сет Беттін

Розумна ідея, хоча вона працюватиме лише в тому випадку, якщо GamePadState замінить рівність, що малоймовірно. Швидше за все, він буде використовувати еталонну рівність, а тому вище, якщо твердження ніколи не буде оцінено як істинне.
craftworkgames

@craftworkgames Equalsвідрізняється; він порівнює дві посилання на те, що вони є одним і тим же екземпляром. Але GamePadStateчи не перевантажує оператор == для порівняння їх значень, до яких я посилався у своїй відповіді ( op_Equality).
Сет Беттін

Насправді я не розумів, що GamePadState - це структура, яка, ймовірно, буде працювати. Технічно, але поведінка рівних і == часто однакове, звичайно, це залежить від реалізації, але рекомендації рекомендують це таким чином. Якщо ви справді хочете довірити рівність, ви також маєте object.ReferenceEquals msdn.microsoft.com/en-us/library/bsc2ak47.aspx
craftworkgames

Ах ви праві, GamePadState - це ціннісний тип, тому це не актуально. Незалежно, == перевантажений, може також використовувати його ІМО.
Сет Беттін

1

Оскільки кнопки є перерахунком, ви можете використовувати такий метод Enum.GetValues :

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

foreach (var button in buttonList)
{
    if (GamePad.GetState(PlayerIndex.One).IsButtonDown(button))
        ExitMainMenu= true;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.