HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Get array of pressed buttons using extension method

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
methodarraypressedextensionbuttonsgetusing

Problem

In my game, I need to detect whether any buttons/keys are pressed at all before I try to process any input. This is easy enough for keys since the XNA library provides a GetPressedKeys method on the KeyboardState class:

private void ProcessKeyboard()
{
    keyboardState = Keyboard.GetState( PlayerIndex.One );

    if ( !keyboardState.GetPressedKeys().Any() )
    {
        DoAction( Actions.Idle );
        return;
    }

    foreach ( var binding in keyboardBindings )
    {
        if ( keyboardState.IsKeyDown( binding.Key ) )
        {
            DoAction( binding.Value );
        }
    }
}


However, it doesn't provide a corollary for the GamePadState class:

private void ProcessGamePad()
{
    gamePadState = GamePad.GetState( PlayerIndex.One );

    // detect no input?

    foreach ( var binding in gamePadBindings )
    {
        if ( gamePadState.IsButtonDown( binding.Key ) )
        {
            DoAction( binding.Value );
        }
    }
}


I tried whipping up my own extension method but, as I'm not really familiar with enums or arrays in C#, I'm afraid it's a little sloppy:

public static class GamePadStateExtensions
{
    public static Buttons[] GetPressedButtons( this GamePadState gamePadState )
    {
        // 25 is the number of items in Buttons
        var pressedButtons = new Buttons[25];

        foreach ( Buttons button in Enum.GetValues( typeof(Buttons) ) )
        {
            if ( gamePadState.IsButtonDown( button ) )
            {
                pressedButtons[pressedButtons.Count()] = button;
            }
        }

        return pressedButtons;
    }
}


Would I be better off doing something else with ProcessKeyboard and/or ProcessGamePad? How can I improve GetPressedButtons?

Solution

Rather than using an array to return you should use a List which can be easily appended to:

public static List GetPressedButtons( this GamePadState gamePadState )
{
    var pressedButtons = List();

    foreach ( Buttons button in Enum.GetValues( typeof(Buttons) ) )
    {
        if ( gamePadState.IsButtonDown( button ) )
        {
            pressedButtons.Add(button);
        }
    }

    return pressedButtons;
}


However this can be simplified still with the use of LINQ. The for loop basically selects all buttons which are pressed:

public static List GetPressedButtons(this GamePadState gamePadState)
{
    return Enum.GetValues(typeof(Buttons))
               .Cast()
               .Where(b => gamePadState.IsButtonDown(b))
               .ToList();
}


The Cast is required because GetValue returns a non-generic Array.

Code Snippets

public static List<Buttons> GetPressedButtons( this GamePadState gamePadState )
{
    var pressedButtons = List<Buttons>();

    foreach ( Buttons button in Enum.GetValues( typeof(Buttons) ) )
    {
        if ( gamePadState.IsButtonDown( button ) )
        {
            pressedButtons.Add(button);
        }
    }

    return pressedButtons;
}
public static List<Buttons> GetPressedButtons(this GamePadState gamePadState)
{
    return Enum.GetValues(typeof(Buttons))
               .Cast<Buttons>()
               .Where(b => gamePadState.IsButtonDown(b))
               .ToList();
}

Context

StackExchange Code Review Q#42395, answer score: 4

Revisions (0)

No revisions yet.