Tutorial: How to make a top-down shooter in JavaScript

Lesson 5) Detecting key-press input

Moving swiftly on

At the moment we move our character – a particularly heroic red square – randomly about the screen by updating his x and y coordinates with values between -1 and 1 every time our game function loops around.

To allow the player to move the character, all we do is set up a key press detector for the keys we want to use for movement, and change the player’s x or y coordinates whenever we detect that one of these keys was pressed. We’ll use these familiar keys:

w = up
a = left
s = down
d = right

JavaScript has a number of built in “Event Listeners” that listen out for various things that can happen on a web page. There are loads of them, but we need just one of them for now: keydown.

This does exactly what you expect – detect when a key is pressed, and which key it was.

All we need to do is check if the they that was pressed was one of our movement keys, and if so, update our four-cornered friend’s coordinates accordingly!

Pay attention, this part is key

Remove the bits of code that made out character move randomly, and then add the following outside of the mainDraw loop:

function playerMove(e) {
  if ( e.key === "w" ) {
    player1y -= 1;
  if ( e.key === "s" ) {
    player1y += 1;
  if ( e.key === "a" ) {
    player1x -= 1;
  if ( e.key === "d" ) {
    player1x += 1;
  return false;
canvas.addEventListener('keydown', playerMove, true);

We’ve added an event listener to the canvas — this means that the user needs to click inside the canvas before input will be detected. This is important, because it allows the user to do other things on the web page without affecting the game.

If our program detects a key press, it runs the playerMove function and passes an object to it. The (e) bit of our playerMove function means we’ve labelled that object “e” (you could label it anything you wanted, but “e” is pretty standard). This “e” object contains parameters with information about the key that was just pressed. In fact if you send e to the console (by putting “console.log(e);” into playerMove), you’ll see something like the following:

keydown { target: <canvas#canvas>, key: "w", charCode: 0, keyCode: 87 }

Just like the player we created earlier, the e object has a load of properties. One of them is called “key” (in this case, key = “w”, meaning the w key was pressed). Our playerMove function has an if statement saying that if this property, e.key, is equaly to “w”, deduct 1 from Player1.y. So, the next time our program loops through mainDraw, the rectangle representing our player will be drawn one pixel higher than it was before (I keep saying this, but remember: y=0 is at the top of the canvas, so deducting numbers from y makes the player go UP the screen).

Have a go yourself (remember to click inside the canvas!):

OK he’s moving! That’s good, but would you be happy with a game where the player moved like this? I wouldn’t – changing directions is jerky, and we can’t move diagonally.

This happens because the event listener is only passing one object to playerMove at a time. Whatever key was pressed most recently will be passed to playerMove, and the square will move in that one direction.

We need more from our geometric journeyman! Next time, we’ll make his movement smoother.

Leave a Reply

Your email address will not be published. Required fields are marked *