Detectando "Cualquier botón presionado"


10

Estoy tratando de permitir que el jugador presione cualquier botón para continuar desde la página principal. Pude hacer esto haciendo una Lista de botones y recorriéndolos y comprobando que uno de ellos no funcionara; sin embargo, siento que este código es un poco feo y me pregunto si hay una manera más simple de hacerlo que simplemente no estoy pensando.

Aquí está mi aspecto de mi código ahora:

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

Yo personalmente solo haría un gran bucle IF, en lugar de crear una matriz y bucle.
jgallant

@ Jon ¿Qué es un gran bucle IF y por qué sería mejor?
Craftworkgames

Me encanta toda la respuesta que esta pregunta está recibiendo. Sin embargo, creo que @Katu obtuvo la respuesta "correcta".
Seth Battin

Respuestas:


10

Esto debería hacer el trabajo. Al final de cada ciclo de actualización, guarde el estado de previousGamePadState. Entonces puedes compararlos. Esta es una forma rápida de detectar cambios. No hay necesidad de bucle.

GamePadState.PacketNumber :

Puede usar PacketNumber para determinar si el estado de entrada ha cambiado. Si el valor de PacketNumber permanece igual entre dos llamadas secuenciales a GetState, entonces no ha habido cambios en la entrada.

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

EDITAR: cambiado al método. No se garantiza que funcione correctamente como está, pero debería funcionar. Además, debido a que esto realmente detecta cambios en la entrada, por lo que si el usuario suelta el botón, también se ve con esto. También agregué ifpara detectar el movimiento del joystick, por lo que puede ignorarlos al menos.

Espero que esto te ayude. Avíseme, si no se ajusta a sus necesidades, estoy seguro de que podemos resolverlo.

Cómo: Detectar si se ha presionado un botón del controlador Esta propiedad GamePadState.PacketNumber de marco


Hay una forma análoga de escribir esto GamePadStatey enum Buttons, que está más cerca del contexto que parece estar usando el OP.
Seth Battin

1
No debería responder nada antes del café de la mañana :)
Katu

1
Ahora hace el trabajo y no puede ser más rápido que esto.
Katu

Whoa, método totalmente diferente, y creo que tienes razón acerca de que es el más rápido. Agradable.
Seth Battin

¿Detecta solo presionar botones, o también detecta la liberación de botones?
George Duckett

1

Si no le importa el uso de Reflection, puede usar algo como esto (posiblemente incluso esto exactamente):

        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

Puede construirGamePadState manualmente un vacío , y luego verificarlo para (in) igualdad con el real actual, que obtiene llamando 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.

}

No tengo idea si esto funciona; Nunca he intentado hacerlo. Avísame si te funciona.
Seth Battin

Idea inteligente, aunque solo funcionará si GamePadState anula Equals, lo que es poco probable. Lo más probable es que use la igualdad de referencia y, por lo tanto, la declaración if anterior nunca se evaluará como verdadera.
Craftworkgames

@craftworkgames Equalses diferente; compara dos referencias por ser la misma instancia. Pero GamePadStatesobrecarga el operador == para comparar sus valores, a los que he vinculado en mi respuesta ( op_Equality).
Seth Battin

En realidad, no me di cuenta de que GamePadState era una estructura que probablemente funcionaría. Sin embargo, técnicamente, el comportamiento de Equals y == es a menudo el mismo, por supuesto, depende de la implementación, pero las pautas lo recomiendan de esta manera. Si realmente desea la igualdad de referencia, también hay object.ReferenceEquals msdn.microsoft.com/en-us/library/bsc2ak47.aspx
craftworkgames

Ah, tienes razón, GamePadState es un tipo de valor, por lo que no es relevante. De todos modos, == está sobrecargado, también podría usarlo IMO.
Seth Battin

1

Como Buttons es una enumeración, puede usar el método Enum.GetValues ​​de esta manera:

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

foreach (var button in buttonList)
{
    if (GamePad.GetState(PlayerIndex.One).IsButtonDown(button))
        ExitMainMenu= true;
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.