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:

Key Classes and Interfaces

InputManager

The central hub for all input-related operations. It manages connected devices and provides methods to query their state.

public static class InputManager

IKeyboard

Represents the keyboard device.

public interface IKeyboard

IMouse

Represents the mouse device.

public interface IMouse

IGamepad

Represents a single gamepad/controller.

public interface IGamepad

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}");
};
Note: Event handling may depend on the underlying windowing system and input polling frequency. It's often recommended to use polled input for movement and direct actions, and events for one-off commands like pausing or exiting.

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.

Important: Always consider implementing dead zones for analog inputs to ensure a smooth and predictable user experience, especially when dealing with slightly worn controllers.