Monday, April 11, 2016

xna - Global keyboard states



I have following idea about processing keyboard input. We capture input in "main" Game class like this:


protected override void Update(GameTime gameTime)
{
this.CurrentKeyboardState = Keyboard.GetState();

// main :Game class logic here

base.Update(gameTime);

this.PreviousKeyboardState = this.CurrentKeyboardState;

}

then, reuse keyboard states (which have internal scope) in all other game components. The reasons behind this are 1) minimize keyboard processing load, and 2) reduce "pollution" of all other classes with similar keyboard state variables.


Since I'm quite a noob in both game and XNA development, I would like to know if all of this sounds reasonable.


UPDATE: If someone is interested, actual utility class, as suggested by David Gouveia, I've created can be found here.



Answer



Yes it's perfectly reasonable, and I could leave it at that!


... but personally I prefer having a bit more encapsulation. So instead of managing the state inside the Game class and providing global access to it, I prefer wrapping it in its own class instead.


Here's an example from memory. Not sure if I missed some detail but what's important is the general idea:


public static class InputManager

{
public static void Update()
{
_previousKeyboardState = _currentKeyboardState;
_currentKeyboardState = Keyboard.GetState();
}

public static bool IsKeyDown(Keys key)
{
return _currentKeyboardState.IsKeyDown(key);

}

public static bool IsKeyUp(Keys key)
{
return _currentKeyboardState.IsKeyUp(key);
}

public static bool OnKeyDown(Keys key)
{
return _currentKeyboardState.IsKeyDown(key) && _previousKeyboardState.IsKeyUp(key);

}

public static bool OnKeyUp(Keys key)
{
return _currentKeyboardState.IsKeyUp(key) && _previousKeyboardState.IsKeyDown(key);
}

private static KeyboardState _currentKeyboardState;
private static KeyboardState _previousKeyboardState;
}


Then at the top of Game.Update I simply call Update on the manager:


InputManager.Update();

And finally everywhere else on the game I can use the wrapper directly:


if(InputManager.OnKeyDown(Keys.Space))
{
// Shoot once
}


Some advantages:



  • Like in your solution, there's only one place in the application that needs to manage the current and previous keyboard states.

  • But instead of polluting the game class with keyboard processing, it's encapsulated in its own class just for that.

  • The class is static making it globally accessible, so that if you don't want you don't need to provide global access to your game class.

  • It's also easily reusable - if you start a new project, you can just drop that class in and you're good to go.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...