To implement a keyboard component for game menus in XNA (or MonoGame), you must shift from continuous input polling to discrete key-press detection. Continuous polling works well for character movement but causes menu options to scroll uncontrollably fast.
Using a dedicated GameComponent encapsulates this behavior seamlessly across different menu screens. 1. The Core Architecture
The architecture requires an input handling mechanism that tracks state changes between frames. This tracks when a key changes from an unpressed state to a pressed state, isolating a single distinct click.
┌────────────────────────────────────────────────────────┐ │ KeyboardComponent (GameComponent) │ ├────────────────────────────────────────────────────────┤ │ • Reads current frame snapshot │ │ • Stores previous frame snapshot │ │ • Exposes “WasKeyPressed()” utility method │ └───────────────────────────┬────────────────────────────┘ │ Refreshes state every frame ▼ ┌────────────────────────────────────────────────────────┐ │ MenuScreen / MenuManager │ ├────────────────────────────────────────────────────────┤ │ • Checks key states via the KeyboardComponent │ │ • Increments or decrements activeItem index pointer │ └────────────────────────────────────────────────────────┘ 2. Implementing the Input Handler Component
Create a class inheriting from GameComponent. Register it in your game instance’s service provider container so that any active menu screen can query it.
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; public class KeyboardComponent : GameComponent { private KeyboardState currentKey // Holds current frame state private KeyboardState priorKey; // Holds previous frame state public KeyboardComponent(Game game) : base(game) { // Add component instance to game services game.Services.AddService(typeof(KeyboardComponent), this); } public override void Update(GameTime gameTime) { // Cycle the old state forward before getting new data priorKey = currentKey; currentKey = Keyboard.GetState(); base.Update(gameTime); } // Helper evaluating if key transition just occurred public bool WasKeyPressed(Keys key) { return currentKey.IsKeyDown(key) && priorKey.IsKeyUp(key); } } Use code with caution. 3. Creating the Menu Class Logic
Leave a Reply