Skip to content

Keyboard Input Quick Start

Mike Adkins edited this page Aug 25, 2026 · 2 revisions

A compact, code-first reference for wiring keyboard input into a Gondwana game.


Contents


The Three-Step Pattern

Keyboard input in Gondwana follows three steps:

Subscribe
    ↓
Register the keys to monitor
    ↓
Handle KeyAction

In a GameHostBase-derived host, wire it up after the platform adapter is ready:

protected override void OnKeyboardAdapterInitialized()
{
    var keyboard = Engine.Input.KeyboardEventPoller;
    if (keyboard is null)
        return;

    keyboard.KeyDown += OnKeyDown;

    keyboard.StartMonitoringKey(
        (int)Keys.A,
        nameof(Keys.A));
}

The examples on this page use WinForms Keys. Avalonia and Blazor use their own key enums, but the Gondwana event pattern is the same.


Show the A Key Being Pressed

using Gondwana.Input.Keyboard;
using System.Windows.Forms;
protected override void OnKeyboardAdapterInitialized()
{
    var keyboard = Engine.Input.KeyboardEventPoller;
    if (keyboard is null)
        return;

    keyboard.KeyDown += OnKeyDown;

    keyboard.StartMonitoringKey(
        (int)Keys.A,
        nameof(Keys.A));
}

private void OnKeyDown(KeyDownEventArgs e)
{
    if (e.KeyConfig.Key == nameof(Keys.A) &&
        e.KeyAction == KeyAction.Pressed)
    {
        Console.WriteLine("A was pressed.");
    }
}

Pressed occurs once when the key transitions from up to down.


Pressed, Repeated, and Released

private void OnKeyDown(KeyDownEventArgs e)
{
    if (e.KeyConfig.Key != nameof(Keys.A))
        return;

    switch (e.KeyAction)
    {
        case KeyAction.Pressed:
            Console.WriteLine("A started.");
            break;

        case KeyAction.Repeated:
            Console.WriteLine("A is still held.");
            break;

        case KeyAction.Released:
            Console.WriteLine("A stopped.");
            break;
    }
}
Action When it occurs
Pressed Once when the key goes down
Repeated While the key remains held, subject to throttling
Released Once when the key comes up

Arrow-Key Movement

Register the keys:

protected override void OnKeyboardAdapterInitialized()
{
    var keyboard = Engine.Input.KeyboardEventPoller;
    if (keyboard is null)
        return;

    keyboard.KeyDown += OnKeyDown;

    keyboard.StartMonitoringKey(
        (int)Keys.Left,
        nameof(Keys.Left));

    keyboard.StartMonitoringKey(
        (int)Keys.Right,
        nameof(Keys.Right));

    keyboard.StartMonitoringKey(
        (int)Keys.Up,
        nameof(Keys.Up));

    keyboard.StartMonitoringKey(
        (int)Keys.Down,
        nameof(Keys.Down));
}

Respond once per press:

private void OnKeyDown(KeyDownEventArgs e)
{
    if (e.KeyAction != KeyAction.Pressed)
        return;

    switch (e.KeyConfig.Key)
    {
        case nameof(Keys.Left):
            MovePlayer(-1, 0);
            break;

        case nameof(Keys.Right):
            MovePlayer(1, 0);
            break;

        case nameof(Keys.Up):
            MovePlayer(0, -1);
            break;

        case nameof(Keys.Down):
            MovePlayer(0, 1);
            break;
    }
}

This pattern is appropriate for grid movement, menu navigation, and one-step actions.


Modifier Keys

KeyDownEventArgs provides convenience properties:

e.IsShift
e.IsCtrl
e.IsAlt

Example: Ctrl+S.

keyboard.StartMonitoringKey(
    (int)Keys.S,
    nameof(Keys.S));
private void OnKeyDown(KeyDownEventArgs e)
{
    if (e.KeyAction == KeyAction.Pressed &&
        e.KeyConfig.Key == nameof(Keys.S) &&
        e.IsCtrl)
    {
        SaveGame();
    }
}

Multiple modifiers may be active at once.

if (e.IsCtrl && e.IsShift)
{
    // Ctrl+Shift+key
}

Held-Key Movement

Use Pressed and Released to maintain game state:

private bool _moveLeft;
private void OnKeyDown(KeyDownEventArgs e)
{
    if (e.KeyConfig.Key != nameof(Keys.Left))
        return;

    switch (e.KeyAction)
    {
        case KeyAction.Pressed:
            _moveLeft = true;
            break;

        case KeyAction.Released:
            _moveLeft = false;
            break;
    }
}

Then apply movement in your update logic:

if (_moveLeft)
{
    player.Movement.SetVelocity(
        new Vector2(-3f, 0f));
}

This is usually better than tying physics directly to keyboard-repeat timing.


Pause or Remove a Binding

Pause all keyboard events:

Engine.Input.KeyboardEventPoller!
    .PauseAllKeyEvents = true;

Resume:

Engine.Input.KeyboardEventPoller!
    .PauseAllKeyEvents = false;

Stop monitoring one key:

keyboard.StopMonitoringKey(
    (int)Keys.A);

Stop monitoring every key:

keyboard.StopMonitoringAllKeys();

For complete temporary suppression, prefer the global pause or stop monitoring. A per-key configuration pause is primarily relevant to held-key repeat behavior in the current implementation.


Platform Key Codes

The Gondwana core accepts integer key codes. Use the enum supplied by the active platform adapter.

WinForms

using System.Windows.Forms;

keyboard.StartMonitoringKey(
    (int)Keys.Space,
    nameof(Keys.Space));

Avalonia

using Avalonia.Input;

keyboard.StartMonitoringKey(
    (int)Key.Space,
    nameof(Key.Space));

Blazor

keyboard.StartMonitoringKey(
    (int)BlazorKey.Space,
    nameof(BlazorKey.Space));

Do not mix codes from one platform enum with another platform's adapter.


Cleanup

Detach the handler when the host is disposed:

protected override void UnhookEvents()
{
    if (Engine.Input.KeyboardEventPoller is { } keyboard)
        keyboard.KeyDown -= OnKeyDown;
}

GameHostBase.Dispose() calls UnhookEvents() before the engine is torn down.


Cheat Sheet

Register a key

keyboard.StartMonitoringKey(
    (int)Keys.A,
    nameof(Keys.A));

One-time press

if (e.KeyAction == KeyAction.Pressed)
{
}

Held key

if (e.KeyAction == KeyAction.Repeated)
{
}

Release

if (e.KeyAction == KeyAction.Released)
{
}

Ctrl+key

if (e.IsCtrl)
{
}

Pause everything

keyboard.PauseAllKeyEvents = true;

Common Problems

Nothing happens

Check that:

  • the platform adapter was initialized
  • KeyboardEventPoller is not null
  • the key was registered
  • the engine is running
  • the key code belongs to the active platform

KeyConfig.Key is a number

Supply a display name:

keyboard.StartMonitoringKey(
    (int)Keys.A,
    nameof(Keys.A));

The action repeats while held

Filter for:

e.KeyAction == KeyAction.Pressed

Arrow keys are swallowed by a WinForms control

The WinForms adapter uses a global message filter and is designed to see arrow-key state regardless of normal control-key handling. Confirm the adapter was initialized against a live control and has not been disposed.


Further Reading

Clone this wiki locally