SDL2::Events#

📦 std

Keyboard, mouse and window events.

SDL_PollEvent takes the next event off the queue and returns it as a plain hash reference, or undef when the queue is empty. Draining the queue each frame is the shape of every SDL program:

while (my $ev = SDL_PollEvent()) {
    last if $ev->{type} == SDL_QUIT;
    if ($ev->{type} == SDL_KEYDOWN) {
        $paddle_x -= 25 if $ev->{sym} == SDLK_LEFT;
        $paddle_x += 25 if $ev->{sym} == SDLK_RIGHT;
    }
}

Every event has type and timestamp. What else it carries depends on the type, and only the relevant keys are present:

Event

Keys

SDL_QUIT

-

SDL_KEYDOWN, SDL_KEYUP

window_id, state, repeat, scancode, sym, mod, key_name

SDL_TEXTINPUT

window_id, text

SDL_MOUSEMOTION

window_id, which, state, x, y, xrel, yrel

SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP

window_id, which, button, state, clicks, x, y

SDL_MOUSEWHEEL

window_id, which, x, y, direction, precise_x, precise_y

SDL_WINDOWEVENT

window_id, event, data1, data2

sym is the key as a layout-dependent symbol - compare it against the SDLK_* constants, which is what you want for “the user pressed left”. scancode is the physical key position, layout-independent, and compares against SDL_SCANCODE_*; that is what you want for WASD, which should stay in the same place on an AZERTY keyboard.

Held keys#

Events tell you when a key changed. For “is it held down right now”, which is what smooth movement needs, ask the keyboard state instead:

SDL_PumpEvents();
$x -= 4 if SDL2::key_pressed(SDL_SCANCODE_LEFT);
$x += 4 if SDL2::key_pressed(SDL_SCANCODE_RIGHT);

key_pressed reads SDL’s live key array directly and allocates nothing, so it is safe to call several times per frame.