Input
Input turns raw key and mouse events into answers to the questions gameplay code actually asks: is it held, did it just go down, how far did the mouse move.
The concept
The OS reports events ("key down", "key up"); a game wants state. Engines keep two snapshots, the current and the previous frame, and derive three queries from them: down (held now), pressed (up last frame, down now) and released (down last frame, up now). Edge queries such as "pressed" are what make a jump fire once instead of every frame the key is held.
Why snapshots?
Reacting to events directly ("on key down, jump") scatters input handling across the code and makes it hard to ask state questions such as "is the player holding right?". Polling a per-frame snapshot gives every system one consistent answer for the whole frame, no matter how many events arrived or in what order, and keeps input code in the update step where gameplay logic lives.
Mouse input
The mouse adds continuous values: a position (where the pointer is now), a delta (how far it moved this frame) and a scroll amount. Positions are in window space, so converting to world coordinates is the camera's job. Deltas and scroll must be accumulated across all events in a frame and reset on the next one, otherwise several small motions in one frame are lost.
Keys, not characters
Game controls care about physical keys (a "move left" binding), not the text the key would type. That is why input is expressed in key codes; remapping then means changing a binding instead of rewriting logic.
How ASGE does it
asge::input::InputSystem is owned by Application and mirrors VideoSystem's shape.
Every frame the loop calls NewFrame() to roll the current snapshot into the previous one, then feeds each
polled SystemEvent through ProcessEvent() (see Events & signals).
It is not a second event source: InputState simply consumes the same stream that also reaches
Game::OnSystemEvent.
Games never touch the system. Each state's Update receives a read-only
InputState const&:
IsKeyDown/IsKeyPressed/IsKeyReleasedwith aKeycodeIsMouseButtonDown/IsMouseButtonPressed/IsMouseButtonReleasedwith aMouseButton(LEFT,MIDDLE,RIGHT,X1,X2)GetMousePosition()(window-relative),GetMouseDelta()andGetScrollDelta(), allFloat2; the deltas accumulate since the lastNewFrame()
void Update( float inDeltaTime, asge::input::InputState const& inInput ) override
{
using asge::input::Keycode;
using asge::input::MouseButton;
if ( inInput.IsKeyPressed( Keycode::A ) ) { /* fires on the frame A went down */ }
if ( inInput.IsKeyDown( Keycode::A ) ) { /* fires every frame A is held */ }
if ( inInput.IsMouseButtonPressed( MouseButton::LEFT ) )
{
auto where = inInput.GetMousePosition(); // asge::math::Float2
}
}
See also
Source: Input/InputSystem.hpp, Input/InputState.hpp.
Input demo · Game loop & timing