Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 防止蛇向相反方向移动_Javascript - Fatal编程技术网

Javascript 防止蛇向相反方向移动

Javascript 防止蛇向相反方向移动,javascript,Javascript,为了周末的乐趣,我正在用JavaScript重新制作一条经典的蛇,我遇到了一个问题,如果我很快按下按钮,蛇毛虫在我的例子中能够改变方向到相反的方向并撞到自己 重现这种情况的方法如下所示: 例如,方向是“左” 向上或向下按,然后快速按 现在毛毛虫倒着走。我的目标是它应该掉头 我检查了反向目录,但这并不能阻止它 update = function() { if (cat.direction != 'right' && key[37] === true) { c

为了周末的乐趣,我正在用JavaScript重新制作一条经典的蛇,我遇到了一个问题,如果我很快按下按钮,蛇毛虫在我的例子中能够改变方向到相反的方向并撞到自己

重现这种情况的方法如下所示:

例如,方向是“左”

向上或向下按,然后快速按

现在毛毛虫倒着走。我的目标是它应该掉头

我检查了反向目录,但这并不能阻止它

update = function() {
    if (cat.direction != 'right' && key[37] === true) {
        cat.direction = 'left';
    }
    if (cat.direction != 'left' && key[39] === true) {
        cat.direction = 'right';
    }
    if (cat.direction != 'down' && key[38] === true) {
        cat.direction = 'up';
    }
    if (cat.direction != 'up' && key[40] === true) {
        cat.direction = 'down';
    }
};

我使用普通的addEventListener进行按键监听,但我将其改为另一种方法,在那里我经常更新按键,caterpillar移动只是偶尔发生,因为我认为在同一时间间隔内直接关联绘图、更改方向和移动可能会有问题。我希望我是可以理解的,抱歉,如果有什么不清楚-我会很高兴提供更多的信息,如果是这样

您可以跟踪蛇是否“移动”。如果你收到键盘输入,在蛇移动之前不要对另一次按键做出反应。这样,每个动作只允许一个键,所以你不能改变方向,撞到自己

修改示例:


依此类推

您可以跟踪蛇是否“移动”。如果你收到键盘输入,在蛇移动之前不要对另一次按键做出反应。这样,每个动作只允许一个键,所以你不能改变方向,撞到自己

修改示例:


等等

一种解决方案是每次移动不处理多个键,但为了实现更高的响应能力,您可以实现一个键缓冲区,而不是像您所知道的那样维护键状态。您将只收集该缓冲区中的箭头键按下次数,而不会将同一个键的任何重复推入该缓冲区

以下是对代码的相关更改:

初始化密钥缓冲区:

var keyBuffer = [];
按下时将箭头键推入缓冲区:

var keyDown = function(e) {
    var keyCode = e.which ? e.which : e.keyCode;
    // *** Queue the arrow key presses
    if (keyCode >= 37 && keyCode <= 40 && 
            keyCode !== keyBuffer[keyBuffer.length-1] && ) {
        keyBuffer.push(keyCode);
    }
};
仅在即将移动时处理下一个关键点:

function loop() {
    board.resetCanvas();
    if(counter > 1000){
        update(); // ***only process buffered keys when moving
        cat.move();
        counter = 0;
    }
    cat.draw();
    counter += 5*cat.multiplier;
};
就这样。请看下面的小提琴:

var canvas=document.getElementByIdboard; var context=canvas.getContext2d,{alpha:false}; var piecessidelength=canvas.width/40; var键=[]; var-keyBuffer=[]; window.addEventListener'keyup',函数e{ this.keyUp.callthis,e; },假; window.addEventListener'keydown',函数E{ this.keyDown.callthis,e; },假; 函数片x,y{ 这个.x=x; 这个。y=y; } 董事会={ 左边界:0, 右边界:canvas.width/piecessidelength, 上界:0, 底部装订:canvas.height/piecessidelength, 抽件:functionx、y、彩色{ context.fillStyle=颜色; context.fillRectx*分段长度,y*分段长度,分段长度,分段长度; context.strokeStyle='white'; context.strokeRectx*分段长度,y*分段长度,分段长度,分段长度; }, 重置画布:函数{ context.clearRect0,0,canvas.width,canvas.height; } }; //猫和毛毛虫 猫={ x:canvas.width/piecessidelength/2,//初始值x y:canvas.height/piecessidelength/2,//初始y 件数:[], 方向:'向上', 颜色:“5da03c”, 应该增长:错误, 乘数:5, init:函数{ cat.pieces.push新件this.x,this.y; }, 移动:功能{
ifcat.pieces.length一种解决方案是每次移动不处理多个键,但为了实现更高的响应能力,您可以实现一个键缓冲区,而不是像您所知道的那样保持键状态。您只会在该缓冲区中收集箭头键按下,而不会将同一个键的任何重复推入

以下是对代码的相关更改:

初始化密钥缓冲区:

var keyBuffer = [];
按下时将箭头键推入缓冲区:

var keyDown = function(e) {
    var keyCode = e.which ? e.which : e.keyCode;
    // *** Queue the arrow key presses
    if (keyCode >= 37 && keyCode <= 40 && 
            keyCode !== keyBuffer[keyBuffer.length-1] && ) {
        keyBuffer.push(keyCode);
    }
};
仅在即将移动时处理下一个关键点:

function loop() {
    board.resetCanvas();
    if(counter > 1000){
        update(); // ***only process buffered keys when moving
        cat.move();
        counter = 0;
    }
    cat.draw();
    counter += 5*cat.multiplier;
};
就是这样。请看下面的小提琴:

var canvas=document.getElementByIdboard; var context=canvas.getContext2d,{alpha:false}; var piecessidelength=canvas.width/40; var键=[]; var-keyBuffer=[]; window.addEventListener'keyup',函数e{ this.keyUp.callthis,e; },假; window.addEventListener'keydown',函数E{ this.keyDown.callthis,e; },假; 函数片x,y{ 这个.x=x; 这个。y=y; } 董事会={ 左边界:0, 右边界:canvas.width/piecessidelength, 上界:0, 底部装订:canvas.height/piecessidelength, 抽件:functionx、y、彩色{ context.fillStyle=颜色; context.fillRectx*分段长度,y*分段长度,分段长度,分段长度; context.strokeStyle='white'; context.strokeRectx*分段长度,y*分段长度,分段长度,分段长度; }, 重置画布:函数{ context.clearRect0,0,canvas.width,canvas.height; } }; //猫和毛毛虫 猫={ x:canvas.width/piecessidelength/2,//初始值x y:canvas.height/piecessidelength/2,//初始y 件数:[], 方向:'向上', 颜色:'5d a03c', 应该增长:错误, 乘数:5, init:函数{ cat.pieces.push新件this.x,this.y; }, 移动:功能{
ifcat.pieces.length当我制作一个蛇克隆游戏时,我有一个nextDirection变量,它可以指示蛇在到达下一个网格块时将转向的位置。这样,你仍然可以引用当前方向,并且可以防止它自己转向。当我制作一个蛇克隆游戏时,我有一个nextDirection变量,它将指示蛇在到达下一个网格块时将转向的位置。这样,你仍然有对当前方向的引用,并且可以防止它自己转向。哦,看起来它的想法与我尝试过的类似,只是它做得很好并且确实有效:D.我以前尝试过的e发布的问题是一个最多可以容纳2个元素的队列,但后来我犯了一个错误,在这个运行间隔内我仍然保留了更新。JS对我来说仍然是非常混乱的语言,我正在学习。但我很接近:谢谢你的全面回答,太糟糕了,我仍然不能给出+1。好吧,正如我所想的那样…当我按下方向按钮时任何时候它们都存储在缓冲区中,然后执行,直到它们全部用完,所以我需要限制缓冲区的容量?虽然这不是一个真正的问题,但甚至可能是一个功能:我在我的答案中添加了一种方法。哦,看起来这与我尝试过的方法类似,只是它做得很好并且实际有效:D.我在发布qu之前尝试过的方法estion是一个最多可以容纳2个元素的队列,但后来我犯了一个错误,在这个运行间隔内我仍然保留了更新。JS对我来说仍然是一种非常混乱的语言,我正在学习。但我很接近:谢谢你的全面回答,太糟糕了,我仍然不能给出+1。好吧,正如我所想的那样……当我多次按下方向按钮时,它们都是正确的e存储在缓冲区中,然后执行,直到它们全部用完,所以我需要限制缓冲区容量?虽然这不是一个真正的问题,但甚至可能是一个功能:我在回答中添加了一种方法。对不起,您的示例与我的示例一样工作-仍然反向运行。但感谢您的努力!对不起,您的示例与我的示例一样工作-仍然如此反向运行。但感谢您的努力!