Keyboard HTML5 input events for a 2D Javscript Typescript game

- 5 mins
Hello1
ViewSource code

Intro

Some of the best games we all know and love use input.

This post is going to focus on listening to keyboard input events, capturing them and displaying their results to the canvas.

Keyboard events

In terms of html keyboard events keyup and keydown are two events that can be used to listen to input from the keyboard.

By default the keyup and keydown events are passed an argument of type KeyboardEvent.

The keydown event is fired whenever a keyboard key is pressed. It will continue to fire for as long as you hold the key down.

The keyup event is fired whenever a keyboard key is released.

Code vs Key

The KeyboardEvent type has a code and key property that is a predefined string value that maps to which key triggered the event.

You'll notice when working through the example below that the code and key look similar and like they are performing the same function but there is an important distinction between them.

The code property provides a value that refers to the physical key being pressed whether as the key property refers to the actual character that key is mapped to.

For the A key for example the code is KeyA whether the key is a.

The key property takes into account different custom keyboard mappings and locales (Ie the language of the keyboard) whether as code property does not.

Example setup

Enough theory lets see the keyboard events in action. We are going to create an application that displays different keyboard events on the canvas.

This tutorial will use the typescript-html5-canvas-starter project as a base. The typescript-html5-canvas-starter is a simple typescript canvas game skeleton project that comprises of code from the previous tutorials, it sets up a typescript html5 canvas project with cold reloading. Tap the typescript-html5-canvas-starter link to download the base zip file. Unzip the content of the zip file and navigate to that directory.

Add the following lines to index.ts

let lastKeyUpCode = ''
let lastKeyDownCode = ''
let lastKeyUpKey = ''
let lastKeyDownKey = '

This will help us keep track of the code and keys's relating to the last key that was pressed and released.

const draw = () => {

  if (context) {
    context.clearRect(0, 0, canvas.width, canvas.height)
    context.font = '20px arial'
    context.fillText(`Keyboard events`, 30, 30)
    context.fillText(`Last keydown code: ${lastKeyDownCode}`, 30, 60)
    context.fillText(`Last keydown key: ${lastKeyDownKey}`, 30, 90) 
    context.fillText(`Last keyup code: ${lastKeyUpCode}`, 30, 120)
    context.fillText(`Last keyup key: ${lastKeyUpKey}`, 30, 150)
    context.fillText(`Press a key to see the key code`, 30, 180)
  }
}

draw()

If you checked out my previous post on basic canvas html5 operations, see link below or you've worked with the html canvas element before the code above should be familiar.

We are clearing the canvas and then populating it via the fillText method with our lastKey variables defined above.

Build and run the application and check you can see the various text elements above.

Adding keyboard events

Adding keyboard events can be achieved using the keyup and keydown events mentioned above. Add the following code to index.ts.

const keyUpHandler = (event: KeyboardEvent) => {
  lastKeyUpCode = event.code
  lastKeyUpKey = event.key

  draw()
}

const keyDownHandler = (event: KeyboardEvent) => {
  lastKeyDownCode = event.code
  lastKeyDownKey = event.key

  draw()
}

document.addEventListener('keyup', keyUpHandler, false)
document.addEventListener('keydown', keyDownHandler, false)

The last two lines setup our eventListeners on the html document.

The document refers to the root object of the document object model (dom). The addEventListener method allows us to enable a element (in this case the document) to listen for some defined event and choose to trigger some effect when it occurs.

In our case we are assigning the keyUpHandler method to the keyup event and the keyDownHandler method to the keydown event.

These methods will trigger each time the document records the associated event occurring.

The event argument is assigned to the default KeyboardEvent that has been triggered.

The keyUpHandler method is assigning the lastKeyUpCode to event.code and lastKeyUpKey to event.key, the keyDownHandler is doing the same for it's respective variables.

Then we call the draw() method which updates the canvas output.

Build and run the application. Try pressing and releasing keys and check the display is updating appropriately.

Try set your keyboard locale or key mapping to something different than the qwerty standard. The key output should change to match the custom keyboard mapping.

Summary

When adding input to a game it's worth considering whether it makes sense for players to map their inputs how they would like or whether the physical layout of the buttons is required.

This forms the basis of keyboard input in html games. Typically a game will poll for keyboard input and update the gameState based on the inputs and then draw the reflected change in gameState to the canvas. We'll use this pattern in upcoming posts.

As a further challenge share a link to how you have used the keyboard events above to interact with the canvas!

*It might be all actually