gpt4 book ai didi

javascript - 防止蛇向反方向移动

转载 作者:行者123 更新时间:2023-11-30 11:40:08 26 4
gpt4 key购买 nike

为了周末的乐趣,我正在用 JavaScript 重制一个经典的蛇,我遇到了这个问题,如果我相当快地按下按钮 - 蛇(在我的例子中是毛毛虫)能够改变方向相反并撞到自己.

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

方向例如'left'

向上(或向下)按下然后快速向右按下

现在毛毛虫倒退了。我的目标是掉头

我检查了相反的目录,但这并不能阻止这种情况

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';
}
};

the full code

我使用普通的 addEventListener 进行按键监听,但我将其更改为另一种方法(在某处找到),我经常更新按键并且毛毛虫移动只是不时发生,因为我认为在同一时间间隔内直接关联绘图、改变方向和移动可能是一个问题。我希望我是可以理解的,如果有什么不清楚的话,我很抱歉 - 如果是的话,我很乐意提供更多信息。

最佳答案

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

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

初始化 key 缓冲区:

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);
}
};

一次处理缓冲区中的一个键:

var update = function() {
// *** Extract next key from buffer, and only treat that one
// -- could be `undefined`, but that is not a problem:
var key = keyBuffer.shift();
if(cat.direction != 'right' && key === 37){
cat.direction = 'left';
} else if(cat.direction != 'left' && key === 39){
cat.direction = 'right';
} else if(cat.direction != 'down' && key === 38){
cat.direction = 'up';
} else if(cat.direction != 'up' && key === 40){
cat.direction = 'down';
}
};

只有在要移动时才处理下一个键:

function loop() {
board.resetCanvas();
if(counter > 1000){
update(); // ***only process buffered keys when moving
cat.move();
counter = 0;
}
cat.draw();
counter += 5*cat.multiplier;
};

就是这样。请参阅下面的 fiddle :

var canvas = document.getElementById("board");
var context = canvas.getContext("2d", {alpha:false});
var pieceSideLength = canvas.width / 40;
var key = [];
var keyBuffer = [];

window.addEventListener('keyup', function(e) {
this.keyUp.call(this, e);
}, false);
window.addEventListener('keydown', function(e) {
this.keyDown.call(this, e);
}, false);

function Piece(x,y){
this.x = x;
this.y = y;
}

board = {

leftBound: 0,
rightBound: canvas.width / pieceSideLength,
topBound: 0,
bottomBound: canvas.height / pieceSideLength,

drawPiece: function(x, y, color){
context.fillStyle = color;
context.fillRect(x*pieceSideLength,y*pieceSideLength,pieceSideLength,pieceSideLength);
context.strokeStyle = 'white';
context.strokeRect(x*pieceSideLength,y*pieceSideLength,pieceSideLength,pieceSideLength);
},

resetCanvas: function(){
context.clearRect(0,0,canvas.width,canvas.height);
}

};
//cat as for caterpillar
cat = {

x: canvas.width/pieceSideLength/2, //initial x
y: canvas.height/pieceSideLength/2, //initial y
pieces: [],
direction: 'up',
color: '#5da03c',
shouldGrow: false,
multiplier: 5,

init: function(){
cat.pieces.push(new Piece(this.x, this.y));
},

move: function(){
if(cat.pieces.length <= 10){
cat.shouldGrow = true;
}
var newX = cat.pieces[cat.pieces.length-1].x;
var newY = cat.pieces[cat.pieces.length-1].y;
if(cat.direction=='up'){
cat.makeNewHeadAt(newX,newY-1);
}
if(cat.direction=='down'){
cat.makeNewHeadAt(newX,newY+1);
}
if(cat.direction=='left'){
cat.makeNewHeadAt(newX-1,newY);
}
if(cat.direction=='right'){
cat.makeNewHeadAt(newX+1,newY);
}
cat.grow();
},

makeNewHeadAt: function(x,y){
cat.pieces.push(new Piece(x,y));
},

grow: function(){
if(cat.shouldGrow == false){
cat.pieces.shift();
} else {
cat.shouldGrow = false;
}
},

draw: function(){
for(i=0;i<cat.pieces.length;i++){
var p = cat.pieces[i];
board.drawPiece(p.x,p.y,cat.color);
}
}







};
cat.init();
update = function() {
// *** Extract next key from buffer, and only treat that one
// -- could be `undefined`, but that is not a problem:
var key = keyBuffer.shift();
if(cat.direction != 'right' && key === 37){
cat.direction = 'left';
} else if(cat.direction != 'left' && key === 39){
cat.direction = 'right';
} else if(cat.direction != 'down' && key === 38){
cat.direction = 'up';
} else if(cat.direction != 'up' && key === 40){
cat.direction = 'down';
}
};
keyUp = function(e) {
var keyCode = e.which ? e.which : e.keyCode;
this.key[keyCode] = false;
};
keyDown = function(e) {
var keyCode = e.which ? e.which : e.keyCode;
// *** Queue the key presses
if (keyCode >= 37 && keyCode <= 40 &&
keyCode !== keyBuffer[keyBuffer.length-1]) {
keyBuffer.push(keyCode);
}
this.key[keyCode] = true;
};

var counter = 0;
function loop() {

board.resetCanvas();
if(counter > 1000){
update(); // ***only process buffered keys when moving
cat.move();
counter = 0;
}
cat.draw();

counter += 5*cat.multiplier;

};
setInterval(loop, 1);
body { margin: 0px }
<div>
<canvas id="board" width="300" height="200" style="display: block; margin: 0 auto; background-color: #553300; border-style: solid; border-color: green;"></canvas>
</div>

限制缓冲区大小

您可以通过替换此限制缓冲区大小:

keyBuffer.push(keyCode);

与:

keyBuffer = keyBuffer.slice(-2).concat(keyCode);

这会将大小限制为 3。根据需要调整 slice 参数。

关于javascript - 防止蛇向反方向移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43032014/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com