Javascript 防止蛇向相反方向移动
为了周末的乐趣,我正在用JavaScript重新制作一条经典的蛇,我遇到了一个问题,如果我很快按下按钮,蛇毛虫在我的例子中能够改变方向到相反的方向并撞到自己 重现这种情况的方法如下所示: 例如,方向是“左” 向上或向下按,然后快速按 现在毛毛虫倒着走。我的目标是它应该掉头 我检查了反向目录,但这并不能阻止它Javascript 防止蛇向相反方向移动,javascript,Javascript,为了周末的乐趣,我正在用JavaScript重新制作一条经典的蛇,我遇到了一个问题,如果我很快按下按钮,蛇毛虫在我的例子中能够改变方向到相反的方向并撞到自己 重现这种情况的方法如下所示: 例如,方向是“左” 向上或向下按,然后快速按 现在毛毛虫倒着走。我的目标是它应该掉头 我检查了反向目录,但这并不能阻止它 update = function() { if (cat.direction != 'right' && key[37] === true) { c
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存储在缓冲区中,然后执行,直到它们全部用完,所以我需要限制缓冲区容量?虽然这不是一个真正的问题,但甚至可能是一个功能:我在回答中添加了一种方法。对不起,您的示例与我的示例一样工作-仍然反向运行。但感谢您的努力!对不起,您的示例与我的示例一样工作-仍然如此反向运行。但感谢您的努力!