0

I'm trying to create a game in HTML5 and I've come to the point where I need to enable keyboard input.

So Here's my code:

window.addEventListener('keydown', function(e) {
    let key = e.keyCode;
    console.log(key);
    if (key == 37) {
        canvas.player.x -= 5;
    }
    if (key == 38) {
        canvas.player.y -= 5;
    }
    if (key == 39) {
        canvas.player.x += 5;
    }
    if (key == 40) {
        canvas.player.y += 5;
    }
}, false);

Where canvas is the canvas object and canvas.player the player object. It works, but not very well... Let's say I'm pressing (and holding down) the right arrow key (39) and than press the down arrow key (40) the player is not moving to the right anymore since we last pressed the down arrow key. Works fine. Until I only release the down arrow key while still pressing down the right arrow key. So I never released the right arrow key. Than the player stops and the browser doesn't seem to understand that I'm pressing the right arrow key.

You can easily see this in the console log of this fiddle.


Does anybody has a solution for this problem? A way to detect the keycode anyways?


Derk Jan Speelman
  • 11,291
  • 4
  • 29
  • 45
  • 1
    Possible duplicate of [JavaScript multiple keys pressed at once](https://stackoverflow.com/questions/5203407/javascript-multiple-keys-pressed-at-once) – James Jun 01 '17 at 12:26

2 Answers2

2

Keyboard IO.

Generally IO events like the mouse, touch, and keyboards should only be used to get the current state of the devices they are listening to. The job of reacting to input is done in your game.

one way to handle keyboard input is as follows

// this defines what keys you are listening to and 
// holds the current state of the key true for down false for up
const keys = {
    ArrowUp : false,  // list the keyboard keys you want to listen to
    ArrowDown : false,
    ArrowLeft : false,
    ArrowRight : false,
};
// the event listener listens for key events
function keyEvents(e){
    if(keys[e.code] !== undefined){ // check if its a key we are listening for
        keys[e.code] = event.type === "keydown" ; // set the state up or down
        e.preventDefault();  // stop default action
    } 
}
addEventListener("keyup",keyEvents);  // set up the listeners
addEventListener("keydown",keyEvents);

Then in your game's main loop or called from there check the key state and perform the action that the state requires..

  if (keys.ArrowDown) { player.y += 5 }
  if (keys.ArrowUp) { player.y -= 5 }
  if (keys.ArrowLeft) { player.x -= 5 }
  if (keys.ArrowRight) { player.x += 5 }
Community
  • 1
  • 1
Blindman67
  • 51,134
  • 11
  • 73
  • 136
0

It may be a bug, I thought that it used keyboard events but on mac it seems to repeat the character when held but when typing normally on a mac holding down a key doesn't do that.

I have done a workaround before using a combination of keydown and keyup to set booleans for each of the keys. Then an interval using something like setInterval which checks each of the booleans for each of the keys. If they are true then I carry out the action for that key.

Tom Banister
  • 171
  • 1
  • 8