While reading all the latest WP7 buzz, I got to thinking that I am going to need some way of managing input between devices so as not to have a billion #if WINDOWS_PHONE or #if XBOX preprocessor statements all over my game logic. The solution is a pretty simple yet elegant abstracted IGameActionManager interface.

Here is the interface I have defined so far:

public interface IGameActionManager
{
	bool IsJumping();
	bool IsMovingRight();
	bool IsMovingLeft();
	bool IsMovingUp();
	bool IsMovingDown();
	bool IsIdle();
	bool IsFiring();
	void GetNewState();
}

Each function corresponds to a typical game action, and the GetNewState() function gets the state for all input devices associated with the implented class itself. Knowing nothing of the implementation, other than which one you want, your game logic would look something like this:

IGameActionManager actionManager = new WindowsGameActionManager();

// somewhere in your update method:
actionManager.GetNewState();
if (actionManager.IsJumping())
{
	// Do your jump logic here
}
if (actionManager.IsMovingLeft())
{
	// Do your move left logic here
}

That eliminates code like:

#if !XBOX
KeyboardState keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.Space) && previousKeyboardState.IsKeyUp(Keys.Space))
#else
GamePadState gamePadState = GamePad.GetState();
if (gamePadState.DPad.Up == ButtonState.Pressed)
#endif
{
	// Do your jump logic here
}

The result is less clutter in your game code itself, but more importantly, your code is more game related. You are now worrying about things like “Is the player trying to jump” instead of “is the player pressing the key that I designated to jump?”

I’m still working out exactly how to handle previous state code within the class, but for now you would probably have to declare a previous IGameActionManager object and get a new state at the appropriate time. The code is still cleaner than worrying about actual key presses throughout still, though.

Here is a windows implementation example for the IGameActionManager:

public class WindowsGameActionManager : IGameActionManager
 {
	KeyboardState keyboardState;
	GamePadState gamepadState;

	public WindowsGameActionManager()
	{
		GetNewState();
	}

	#region IGameActionManager Members

	public bool IsJumping()
	{
		return keyboardState.IsKeyDown(Keys.Space) ||
		gamepadState.DPad.Up == ButtonState.Pressed;
	}

	public bool IsMovingRight()
	{
		return (keyboardState.IsKeyDown(Keys.Right) &&
		keyboardState.IsKeyUp(Keys.Left)) ||
		(gamepadState.DPad.Right == ButtonState.Pressed &&
		gamepadState.DPad.Left == ButtonState.Released);
	}

	public bool IsMovingLeft()
	{
		return (keyboardState.IsKeyDown(Keys.Left) &&
		keyboardState.IsKeyUp(Keys.Right)) ||
		(gamepadState.DPad.Left == ButtonState.Pressed &&
		gamepadState.DPad.Right == ButtonState.Released);
	}

	public bool IsIdle()
	{
		return !IsMovingDown() && !IsMovingLeft() && !IsMovingRight() && !IsMovingUp();
	}

	public bool IsFiring()
	{
		return keyboardState.IsKeyDown(Keys.RightControl) ||
		gamepadState.Triggers.Right > 0.0f;
	}

	public bool IsMovingUp()
	{
		return (keyboardState.IsKeyDown(Keys.Up) && keyboardState.IsKeyUp(Keys.Down)) ||
		(gamepadState.DPad.Up == ButtonState.Pressed && gamepadState.DPad.Down == ButtonState.Released);
	}

	public bool IsMovingDown()
	{
		return (keyboardState.IsKeyDown(Keys.Down) && keyboardState.IsKeyUp(Keys.Up)) ||
		(gamepadState.DPad.Down == ButtonState.Pressed && gamepadState.DPad.Up == ButtonState.Released);
	}

	public void GetNewState()
	{
		keyboardState = Keyboard.GetState();
		gamepadState = GamePad.GetState(PlayerIndex.One);
	}

	#endregion
 }

Please drop a comment if you find this useful, or send me a tweet: @DomenicDatti

4 thoughts on “IGameActionManager interface for simplifying input management.

  1. Pingback: Creators Club Communiqué 46 | Adibit

  2. A friend pointed out that (not in his words) this is great for digital input, but not so much for analog style.

    I will hopefully be doing more of my personal projects soon again, so perhaps I will rewrite this to work in some sort of analog input.

  3. Pingback: Putting the IGameActionManager interface to work

  4. Pingback: Touch Input in Windows 7 or 8 desktop mode. | Geek Powers

Leave a Reply

Your email address will not be published. Required fields are marked *