In the next chapter we will see how so called events are processed to handle input of any kind (keyboard, mouse, joystick,…) Before that I’d like to introduce a simple, yet powerful way to handle keyboard input.
The keyboard state represents the state (pressed = 1 or unpressed = 0) of all the keyboard keys, hence the key states. By
function SDL_GetKeyboardState(numkeys: PInt): PUInt8
we have easy access to this array.

The following code example will draw a red rectangle which can be moved by the WASD keys. Therefore we read out their key states on every cycle of the program loop.
program SDL_KeyboardState;
uses SDL2;
var
sdlWindow1: PSDL_Window;
sdlRenderer: PSDL_Renderer;
sdlRectangle: TSDL_Rect;
sdlKeyboardState: PUInt8;
Running: Boolean = True;
begin
//initilization of video subsystem
if SDL_Init(SDL_INIT_VIDEO) < 0 then Halt;
if SDL_CreateWindowAndRenderer(500, 500, SDL_WINDOW_SHOWN, @sdlWindow1, @sdlRenderer) <> 0
then Halt;
// prepare rectangle
sdlRectangle.x := 250;
sdlRectangle.y := 250;
sdlRectangle.w := 10;
sdlRectangle.h := 10;
// program loop
while Running = True do
begin
SDL_PumpEvents;
sdlKeyboardState := SDL_GetKeyboardState(nil);
// ESC pressed
if sdlKeyboardState[SDL_SCANCODE_ESCAPE] = 1 then
Running := False;
// WASD keys pressed
if sdlKeyboardState[SDL_SCANCODE_W] = 1 then
sdlRectangle.y := sdlRectangle.y-1;
if sdlKeyboardState[SDL_SCANCODE_A] = 1 then
sdlRectangle.x := sdlRectangle.x-1;
if sdlKeyboardState[SDL_SCANCODE_S] = 1 then
sdlRectangle.y := sdlRectangle.y+1;
if sdlKeyboardState[SDL_SCANCODE_D] = 1 then
sdlRectangle.x := sdlRectangle.x+1;
// black background
SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(sdlRenderer);
// draw red rectangle
SDL_SetRenderDrawColor(sdlRenderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderDrawRect(sdlRenderer, @sdlRectangle);
SDL_RenderPresent(sdlRenderer);
SDL_Delay(20);
end;
// clear memory
SDL_DestroyRenderer(sdlRenderer);
SDL_DestroyWindow (sdlWindow1);
//closing SDL2
SDL_Quit;
end.
To get the keyboard state, we define a unsigned 8 bit pointer variable sdlKeyboardState in the var clause. It points to the array of key states.
// program loop
while Running = True do
begin
SDL_PumpEvents;
sdlKeyboardState := SDL_GetKeyboardState(nil);
After setting up a SDL2 window and and preparing a SDL2 rectangle, the program loop is entered. Here we need to update the event queue by procedure SDL_PumpEvents. After that we can grab the keyboard state by the former mentioned function SDL_GetKeyboardState. The argument should be nil. These actions have to performed on every cycle.
// ESC pressed
if sdlKeyboardState[SDL_SCANCODE_ESCAPE] = 1 then
Running := False;
// WASD keys pressed
if sdlKeyboardState[SDL_SCANCODE_W] = 1 then
sdlRectangle.y := sdlRectangle.y-1;
if sdlKeyboardState[SDL_SCANCODE_A] = 1 then
sdlRectangle.x := sdlRectangle.x-1;
if sdlKeyboardState[SDL_SCANCODE_S] = 1 then
sdlRectangle.y := sdlRectangle.y+1;
if sdlKeyboardState[SDL_SCANCODE_D] = 1 then
sdlRectangle.x := sdlRectangle.x+1;
We now can check for the of any key in the array by sdlKeyboardState[SDL_SCANCODE_…] using its
scancode as a handle (e.g. SDL_SCANCODE_ESCAPE for the escape key) and react as desired, e.g. exit the program loop or change the x/y coordinates of the rectangle. The scancode represents the position of the related key state in the array. A detailed description of scancodes in the next chapter. A list of all the scancodes shows all possible scancodes.
← previous Chapter | next Chapter →
The “previous chapter” and “next chapter” links on this article link to the wrong chapters.
Thanks, fixed it!
Ukrainian translation avaliable on https://lazarus-games.blogspot.com/p/13.html