Input¶
Learn how to handle player input from keyboard, mouse, and gamepads in your Brine2D games.
Quick Start¶
using Brine2D.Input;
public class GameScene : Scene
{
protected override void OnUpdate(GameTime gameTime)
{
var speed = 200f * (float)gameTime.DeltaTime;
// Keyboard
if (Input.IsKeyDown(Key.W)) _position.Y -= speed;
if (Input.IsKeyDown(Key.S)) _position.Y += speed;
if (Input.IsKeyDown(Key.A)) _position.X -= speed;
if (Input.IsKeyDown(Key.D)) _position.X += speed;
// Mouse
if (Input.IsMouseButtonPressed(MouseButton.Left))
Logger.LogInformation("Clicked at {Pos}", Input.MousePosition);
// Gamepad
if (Input.IsGamepadButtonPressed(GamepadButton.A))
Logger.LogInformation("Gamepad A pressed");
}
}
Topics¶
Getting Started¶
| Guide | Description | Difficulty |
|---|---|---|
| Keyboard | Handle keyboard input | |
| Mouse | Mouse position, clicks, and scroll wheel |
Advanced¶
| Guide | Description | Difficulty |
|---|---|---|
| Gamepad Support | Controller/gamepad input | |
| Input Actions | Rebindable logical actions with multiple bindings | |
| Input Layers | Priority-based input routing for UI |
Key Concepts¶
The Input Framework Property¶
Input is an IInputContext available on every Scene from OnLoadAsync onwards -- no constructor injection needed:
public class GameScene : Scene
{
protected override void OnUpdate(GameTime gameTime)
{
if (Input.IsKeyDown(Key.W))
_position.Y -= 200f * (float)gameTime.DeltaTime;
}
}
Keyboard¶
if (Input.IsKeyDown(Key.W)) MoveUp(); // Held (continuous)
if (Input.IsKeyPressed(Key.Space)) Jump(); // Just pressed (one-shot)
if (Input.IsKeyReleased(Key.E)) ReleaseCharge(); // Just released
if (Input.IsAnyKeyPressed()) StartGame(); // Any key this frame
Mouse¶
var pos = Input.MousePosition; // Vector2, screen coordinates
var delta = Input.MouseDelta; // Frame-to-frame movement
var scroll = Input.ScrollWheelDelta; // float, positive = up
var hscroll = Input.ScrollWheelDeltaX; // float, horizontal scroll
if (Input.IsMouseButtonPressed(MouseButton.Left))
SpawnAt(pos);
Input.IsCursorVisible = false; // Hide OS cursor
Input.IsRelativeMouseMode = true; // Capture mouse for FPS cameras
Gamepad¶
if (Input.IsGamepadConnected())
{
if (Input.IsGamepadButtonPressed(GamepadButton.A)) Jump();
// Sticks return Vector2 with radial deadzone already applied (default 0.15)
var stick = Input.GetGamepadLeftStick();
_position += stick * speed * deltaTime;
var trigger = Input.GetGamepadTrigger(GamepadAxis.RightTrigger);
Input.RumbleGamepad(0.5f, 0.8f, TimeSpan.FromMilliseconds(200));
}
Input Actions (Rebindable)¶
var jumpAction = new InputAction("Jump",
new KeyBinding(Key.Space),
new GamepadButtonBinding(GamepadButton.A));
if (jumpAction.IsPressed(Input)) Jump();
Input Layers (UI Priority)¶
_inputLayerManager.RegisterLayer(myUiLayer);
protected override void OnUpdate(GameTime gameTime)
{
_inputLayerManager.ProcessInput();
if (!_inputLayerManager.KeyboardConsumed) HandleGameKeyboard();
if (!_inputLayerManager.MouseConsumed) HandleGameMouse();
if (!_inputLayerManager.GamepadConsumed) HandleGameGamepad();
}
Best Practices¶
DO¶
- Use the
Inputframework property in scenes - Poll input in
OnUpdate()only - Use
deltaTimefor movement -- frame-rate independent - Use
IsKeyPressed()for one-shot actions -- jump, shoot, toggle - Use
IsKeyDown()for continuous actions -- movement, sprint
protected override void OnUpdate(GameTime gameTime)
{
if (Input.IsKeyDown(Key.W))
_position.Y -= _speed * (float)gameTime.DeltaTime;
if (Input.IsKeyPressed(Key.Space))
Jump();
}
DON'T¶
- Don't poll input in
OnRender()-- wrong lifecycle method - Don't forget
deltaTime-- movement will be FPS-dependent - Don't use
IsKeyPressed()for movement -- will be choppy
// Bad pattern
protected override void OnRender(GameTime gameTime)
{
if (Input.IsKeyDown(Key.W))
_position.Y -= _speed; // No deltaTime and wrong lifecycle!
}
Troubleshooting¶
Input Not Responding¶
- Check you are in
OnUpdate, notOnRender - Click the game window -- input only works when focused
Movement Too Fast or Slow¶
// Wrong -- FPS dependent
_position.Y -= 5;
// Correct -- 200 pixels per second regardless of frame rate
_position.Y -= 200f * (float)gameTime.DeltaTime;
Gamepad Not Detected¶
if (!Input.IsGamepadConnected())
{
Logger.LogWarning("No gamepad connected");
return;
}