-
-
Notifications
You must be signed in to change notification settings - Fork 2
Keyboard Input Quick Start
A compact, code-first reference for wiring keyboard input into a Gondwana game.
- The Three-Step Pattern
- Show the A Key Being Pressed
- Pressed, Repeated, and Released
- Arrow-Key Movement
- Modifier Keys
- Held-Key Movement
- Pause or Remove a Binding
- Platform Key Codes
- Cleanup
- Cheat Sheet
- Common Problems
- Further Reading
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.
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.
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 |
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.
KeyDownEventArgs provides convenience properties:
e.IsShift
e.IsCtrl
e.IsAltExample: 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
}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 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.
The Gondwana core accepts integer key codes. Use the enum supplied by the active platform adapter.
using System.Windows.Forms;
keyboard.StartMonitoringKey(
(int)Keys.Space,
nameof(Keys.Space));using Avalonia.Input;
keyboard.StartMonitoringKey(
(int)Key.Space,
nameof(Key.Space));keyboard.StartMonitoringKey(
(int)BlazorKey.Space,
nameof(BlazorKey.Space));Do not mix codes from one platform enum with another platform's adapter.
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.
keyboard.StartMonitoringKey(
(int)Keys.A,
nameof(Keys.A));if (e.KeyAction == KeyAction.Pressed)
{
}if (e.KeyAction == KeyAction.Repeated)
{
}if (e.KeyAction == KeyAction.Released)
{
}if (e.IsCtrl)
{
}keyboard.PauseAllKeyEvents = true;Check that:
- the platform adapter was initialized
-
KeyboardEventPolleris notnull - the key was registered
- the engine is running
- the key code belongs to the active platform
Supply a display name:
keyboard.StartMonitoringKey(
(int)Keys.A,
nameof(Keys.A));Filter for:
e.KeyAction == KeyAction.PressedThe 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.
- Home
- Make Your First Game in 30 Minutes
- Engine Architecture Overview
- Gondwana Engine Lifecycle
- Gondwana CLI Cheatsheet
- Assets Files
- Tilesheets
- Scenes and SceneLayers
- Sprites
- Views, Cameras, and Viewports
- DirectDrawing
- Game State Files
- Logging
- Movement and Controllers
- Input Handling
- Collision Detection
- Timers and Engine Timing
- Using the Effects System
- Engine Configuration