Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent a multiple keypresses in Javascript

I'm beginner at JS and I'm working on a project to create a game, which is in my case a Snake-game. Everything is going fine, except that if I quickly press multiple keys at once, the Snake dies, because (i think) it's a collision. That's why I want to disable multiple keypresses somehow, to try if it solves the problem. My code:

var Snake = function()
{
  //this is the direction table; UP, RIGHT, DOWN, LEFT
  this.directions = [[0, -1], [1, 0], [0, 1], [-1, 0]];
}

function onKeyDown(event)
{
  if (gameover)
    tryNewGame();
  else 
  {
    if (event.keyCode == 37 || event.keyCode == 65)
    {
      if (snake.direction != 1)  
        snake.direction = 3;
    } 
    else if (event.keyCode == 38 || event.keyCode == 87) 
    {
      if (snake.direction != 2) 
        snake.direction = 0;
    } 
    else if (event.keyCode == 39 || event.keyCode == 68) 
    {
      if (snake.direction != 3) 
        snake.direction = 1;
    } 
    else if (event.keyCode == 40 || event.keyCode == 83) 
    {
      if (snake.direction != 0)
        snake.direction = 2;
    }   
  }
}
like image 488
Zsolti Avatar asked Nov 26 '25 00:11

Zsolti


1 Answers

The problem is probably that the direction changes twice before the snake's shape is updated, and so the first of those two direction changes is actually ignored.

A way to overcome this, is to buffer the direction changes in a queue (implemented as array).

So in your key event handler you would not do this:

if (snake.direction != 1)  
    snake.direction = 3;

But instead:

if ((snake.queue.length ? snake.queue[0] : snake.direction) != 1) 
    snake.queue.unshift(3);

This queue should be initialised in the Snake constructor:

this.queue = [];

Then when you update the snake's position (at a time interval), you would consume that queue if there is something in it:

if (snake.queue.length)
    snake.direction = snake.queue.pop();
// Now apply this direction:
//   ... this would be code you already have...

You could set a maximum to this queue size, as it can get awkward if the user keeps pressing keys faster than the snake updates.

like image 175
trincot Avatar answered Nov 27 '25 13:11

trincot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!