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.