Input Core APIs
The Input API provides a robust and unified way to handle user input from various devices in your .NET games. It abstracts away the complexities of different input methods, allowing you to focus on game logic.
Device Abstraction
The system defines abstractions for common input devices:
- Keyboard: Access to key presses, releases, and character input.
- Mouse: Track mouse position, button states (left, right, middle), and scroll wheel events.
- Gamepad/Controller: Support for multiple gamepads, including analog sticks, buttons, and triggers.
- Touch: For games on touch-enabled devices, handling touch points and gestures.
Key Classes and Interfaces
InputManager
The central hub for all input-related operations. It manages connected devices and provides methods to query their state.
IKeyboard
Represents the keyboard device.
- bool IsKeyDown(Keys key): Checks if a specific key is currently held down.
- bool WasKeyPressed(Keys key): Checks if a specific key was pressed in the current frame.
- bool WasKeyReleased(Keys key): Checks if a specific key was released in the current frame.
- string GetInputText(): Retrieves any text input since the last call.
IMouse
Represents the mouse device.
- Point Position: Gets the current mouse cursor position in screen coordinates.
- bool IsButtonDown(MouseButton button): Checks if a specific mouse button is held down.
- bool WasButtonPressed(MouseButton button): Checks if a specific mouse button was pressed in the current frame.
- bool WasButtonReleased(MouseButton button): Checks if a specific mouse button was released in the current frame.
- int ScrollDelta: Gets the amount the scroll wheel has moved since the last frame.
IGamepad
Represents a single gamepad/controller.
- int Index: The index of the gamepad (e.g., 0 for player 1).
- bool IsConnected: Indicates if the gamepad is currently connected.
- Vector2 LeftThumbstick: Gets the normalized position of the left analog stick (-1.0 to 1.0).
- Vector2 RightThumbstick: Gets the normalized position of the right analog stick (-1.0 to 1.0).
- float LeftTrigger: Gets the normalized value of the left trigger (0.0 to 1.0).
- float RightTrigger: Gets the normalized value of the right trigger (0.0 to 1.0).
- bool IsButtonDown(GamepadButton button): Checks if a specific gamepad button is held down.
- bool WasButtonPressed(GamepadButton button): Checks if a specific gamepad button was pressed in the current frame.
- bool WasButtonReleased(GamepadButton button): Checks if a specific gamepad button was released in the current frame.
Keys
Enum
An enumeration defining standard keyboard keys.
public enum Keys
{
A, B, C, ..., Z,
D0, D1, ..., D9,
Escape, Space, Enter,
LeftShift, RightShift,
LeftControl, RightControl,
LeftAlt, RightAlt,
LeftArrow, RightArrow,
UpArrow, DownArrow,
// ... and many more
}
MouseButton
Enum
An enumeration defining standard mouse buttons.
public enum MouseButton
{
Left,
Right,
Middle,
Button4,
Button5
}
GamepadButton
Enum
An enumeration defining standard gamepad buttons.
public enum GamepadButton
{
A, B, X, Y, // Xbox-style face buttons
LeftShoulder, RightShoulder,
Start, Back,
LeftThumb, RightThumb,
DPadUp, DPadDown, DPadLeft, DPadRight
// ...
}
Input Handling Example
Here's a typical pattern for handling input in your game's update loop:
using MyGameEngine.Input;
using MyGameEngine.Math;
public class PlayerController
{
private IKeyboard keyboard;
private IMouse mouse;
private IGamepad gamepad;
public PlayerController()
{
// Assuming InputManager provides instances of these interfaces
keyboard = InputManager.GetKeyboard();
mouse = InputManager.GetMouse();
gamepad = InputManager.GetGamepad(0); // Get the first gamepad
}
public void Update(float deltaTime)
{
// Keyboard input
if (keyboard.WasKeyPressed(Keys.Space))
{
Jump();
}
Vector2 moveDirection = Vector2.Zero;
if (keyboard.IsKeyDown(Keys.W)) moveDirection.Y -= 1;
if (keyboard.IsKeyDown(Keys.S)) moveDirection.Y += 1;
if (keyboard.IsKeyDown(Keys.A)) moveDirection.X -= 1;
if (keyboard.IsKeyDown(Keys.D)) moveDirection.X += 1;
if (moveDirection.LengthSquared() > 0)
{
Move(moveDirection.Normalized() * 5.0f * deltaTime);
}
// Mouse input
Point mousePos = mouse.Position;
if (mouse.WasButtonPressed(MouseButton.Left))
{
Fire(mousePos);
}
int scroll = mouse.ScrollDelta;
if (scroll != 0)
{
ChangeWeapon(scroll > 0);
}
// Gamepad input
if (gamepad.IsConnected)
{
Vector2 gamepadMove = gamepad.LeftThumbstick;
if (gamepadMove.LengthSquared() > 0.1f) // Dead zone
{
Move(gamepadMove * 10.0f * deltaTime);
}
if (gamepad.WasButtonPressed(GamepadButton.A))
{
Jump();
}
}
}
private void Jump() { /* Implement jump logic */ }
private void Move(Vector2 direction) { /* Implement movement logic */ }
private void Fire(Point target) { /* Implement firing logic */ }
private void ChangeWeapon(bool next) { /* Implement weapon switching */ }
}
Event Handling
For more responsive input, you can also subscribe to input events:
// Example of subscribing to key press events
InputManager.GetKeyboard().KeyPressed += (sender, args) => {
if (args.Key == Keys.Escape)
{
Application.Quit();
}
};
InputManager.GetMouse().ButtonPressed += (sender, args) => {
Console.WriteLine($"Mouse button {args.Button} pressed at {args.Position}");
};
Input Buffering and Dead Zones
Input managers typically handle input buffering for events and provide mechanisms to configure dead zones for analog sticks and triggers to prevent unwanted input from small movements.