I'm working on a snake game project (For a JavaScript course). I try to avoid a "bug" that when two keys are used simultaneously, the game considers that there is collision while visually no.
Code for keyboard key management
document.onkeydown = function handleKeyDown(e){
const key = e.keyCode;
let newDirection;
switch(key){
case 37:
newDirection = "left";
break;
case 38:
newDirection = "up";
break;
case 39:
newDirection = "right";
break;
case 40:
newDirection = "down";
break;
case 32:
restart();
return;
default:
return;
}
snakee.setDirection(newDirection);
}
How to avoid this? Someone told me about the preventDefault () event, should I use it?
EDIT1
Here is the checkCollision method that is part of my constructor function for the snake:
this.checkCollision = function(){
let wallCollision = false;
let snakeCollision = false;
const head = this.body[0];
const rest = this.body.slice(1);
const snakeX = head[0];
const snakeY = head[1];
const minX = 0;
const minY = 0;
const maxX = widthInBlocks-1;
const maxY = heightInBlocks-1;
const isNotBetweenHorizontalWalls = snakeX < minX || snakeX > maxX;
const isNotBetweenVerticalWalls = snakeY < minY || snakeY > maxY;
if(isNotBetweenHorizontalWalls || isNotBetweenVerticalWalls){
wallCollision = true;
}
for(let i = 0;i < rest.length;i++){
if(snakeX == rest[i][0] && snakeY == rest[i][1]){
snakeCollision = true;
}
}
return wallCollision || snakeCollision;
};
EDIT2:
So, after your answers, here is the solution used.
I used a switch
before, I decided to use an if/else
instead.
const map = {};
onkeydown = onkeyup = function(e){
e = e || event;
map[e.keyCode] = e.type == 'keydown';
let newDirection;
if(map[37]){
newDirection = "left";
} else if(map[38]){
newDirection = "up";
} else if(map[39]){
newDirection = "right";
} else if(map[40]){
newDirection = "down";
} else if(map[32]){
restart();
}
snakee.setDirection(newDirection);
}
BUT, the problem still exist if all the properties of the map object are at false, what happens when I press two keys simultaneously.
Object {
32: false,
37: false,
38: false,
39: false,
40: false
}
I don't know how to prevent this.
Please take a look at this example on how to handle simultaneous keystrokes.
Click on the results screen with the console opened and press top + left or right and you'll see custom console.log to each one :)
var map = {}; // You could also use an array
onkeydown = onkeyup = function(e){
e = e || event; // to deal with IE
map[e.keyCode] = e.type == 'keydown';
/* insert conditional here */
console.log(map);
if(map[38] && map[39]) {
console.log('Moved Top & Right!')
}
if(map[38] && map[37]) {
console.log('Moved Top & Left!')
}
}
window.addEventListener('keydown', onkeyup);
window.addEventListener('keyup', onkeydown);
Example made based on this question: How to detect if multiple keys are pressed at once using JavaScript?