Javascript-如何避免重复使用键盘键

Javascript-如何避免重复使用键盘键,javascript,preventdefault,onkeydown,Javascript,Preventdefault,Onkeydown,我正在从事一个蛇游戏项目(JavaScript课程)。 我试图避免一个“错误”,即当同时使用两个键时,游戏会认为存在碰撞,而视觉上没有碰撞 键盘按键管理代码 document.onkeydown = function handleKeyDown(e){ const key = e.keyCode; let newDirection; switch(key){ case 37: newDirection = "left";

我正在从事一个蛇游戏项目(JavaScript课程)。 我试图避免一个“错误”,即当同时使用两个键时,游戏会认为存在碰撞,而视觉上没有碰撞

键盘按键管理代码

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);
}
如何避免这种情况? 有人告诉我preventDefault()事件,我应该使用它吗

EDIT1

以下是checkCollision方法,它是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;
        };
但是如果贴图对象的所有属性都为false,那么问题仍然存在,当我同时按下两个键时会发生什么

Object {
  32: false,
  37: false,
  38: false,
  39: false,
  40: false
}

我不知道如何防止这种情况。

你说的碰撞是什么意思?即使按住多个键,
onkeydown
事件也只会返回键盘上最后按下的键

如果按下
down
然后按下
left
,则
onkeydown
事件将返回
left
键的键码

您不需要使用
event.preventDefault()
,因为这将停止查找keydown键,而不返回任何内容

您的代码应该可以很好地与我看到的一致

如果要检测多个击键,则应为此保留一个映射对象

const keysPressed = {};
onkeydown = function(e) => {
  const e = e || event;
  keyPressed[e.keyCode] = e.keyCode >= 37 && e.keyCode <= 40;

  // move your snake now with the keys pressed
}
const keysPressed={};
onkeydown=功能(e)=>{
常数e=e | |事件;

按下键[e.keyCode]=e.keyCode>=37&&e.keyCode您应该使用onkeyup事件来代替onkeydown,它将解决您的冲突问题。

这是游戏构建中一个众所周知的问题,最好的方法是排队操作。这可能是通过标志或实际队列。按下键时,用户操作会被记录,或添加到列表中,然后执行

游戏循环负责在适当的时间检查标志或输入队列,并相应地更新游戏状态

以下教程将对如何实现和更新基本输入状态提供一些见解:

请了解如何处理同时击键

在控制台打开的情况下单击结果屏幕,然后按top+left或right,您将看到每个控制台的custom console.log:)

var-map={};//还可以使用数组
onkeydown=onkeyup=功能(e){
e=e | | event;//处理IE
map[e.keyCode]=e.type=='keydown';
/*在此处插入条件*/
控制台日志(map);
如果(映射[38]&映射[39]){
console.log('Moved Top&Right!')
}
如果(映射[38]&映射[37]){
console.log('Moved Top&Left!')
}
}
window.addEventListener('keydown',onkeydup);

window.addEventListener('keyup',onkeydown);
你的碰撞检测代码是什么?你需要添加更多的代码。例如,你可以添加一个标志
snakeMoved
,并在
keydown
事件中检查它,这样当第一个键还没有完成移动时,你就不会以另一种方式移动蛇。这里会提出类似的问题:如何检测是否在o处按了多个键nce使用JavaScript?好的,我明白了。问题是我不希望同时使用两个键。所以我可以使用开关来代替if?或者我说了一些愚蠢的话?好吧,我尝试了if/else语句,它似乎工作得很好!:)好吧,经过几次尝试,我仍然有这个问题,当map对象的所有属性都为false时(我编辑了原始帖子)。@mangasource你能将你的全部代码上传到吗?这将有助于解决问题:)嘿@mangasource,我在这里进行了测试,似乎缺少的是将事件侦听器添加到窗口:
const keysPressed = {};
onkeydown = function(e) => {
  const e = e || event;
  keyPressed[e.keyCode] = e.keyCode >= 37 && e.keyCode <= 40;

  // move your snake now with the keys pressed
}