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;
}
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With