好吧,既然你正在制作蛇游戏,我们知道你想做什么,我认为如果我们试图让你走上正确的轨道而不是修改你现有的代码会更有用。
假设我们的逻辑游戏网格是 60x60。所以蛇片可以在这个网格中的任何地方,X 和 Y 值在 0 到 59 之间。这意味着:
左上角的一条蛇在[0, 0]
右上角的一条蛇在[59, 0]
让我们进一步假设一条蛇由许多段组成。开始4段怎么样。这意味着我们需要保留 4 个位置的数组:
[position1, position2, position3, position4]
我们必须选择一个前端,所以可以说数组的末端是蛇的“前端”。如果我们选择左上 4 个位置,蛇将是:
var mySnake = [[0, 0], [1,0], [2,0], [3,0]]
板上的内容如下所示:
++++OOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
这意味着它的 4 条蛇从左到右,就像你到目前为止一样。问题是,通过保存这些位置,我们已经为我们的程序添加了一些持久状态。
现在蛇是一个有趣的游戏,因为“移动”蛇实际上意味着两件事:
- 拿走最后一块(尾巴)
- 为蛇添加一个新片段
所以我们应该做一个移动蛇的函数来完成这两个任务。我们将根据方向制作一个:
// modifies a snake's array
function moveSnake(snake, direction) {
// First we must remove a piece of the snake's tail, which is at the start of the array
// There's a built in command in JavaScript for this called shift()
snake.shift();
// Now we must add the new piece!
// To tell where we need to go we must look at the last location:
var lastLoc = snake[snake.length - 1];
// Just to be a little more clear:
var lastX = lastLoc[0];
var lastY = lastLoc[1];
switch (direction) {
case 'up':
snake.push([lastX, lastY-1]);
break;
case 'down':
snake.push([lastX, lastY+1]);
break;
case 'left':
snake.push([lastX-1, lastY]);
break;
case 'right':
snake.push([lastX+1, lastY]);
break;
}
// redraw after every move!
drawSnake(ctx, mySnake);
}
使用这种方法,我们可以做到:
var mySnake = [[0, 0], [1,0], [2,0], [3,0]];
moveSnake(mySnake, 'down');
// mySnake is now [[1,0], [2,0], [3,0], [3,1]];
这条蛇现在看起来像这样:
O+++OOOOOOOO
OOO+OOOOOOOO
OOOOOOOOOOOO
现在这个方法很笨,在真正的蛇游戏中我们需要添加一些条件。通常:
- 如果新的蛇在食物上,尾巴不会被移除,而是蛇长+1格
- 如果新棋子超出 60x60 网格,则用户输掉游戏
- 如果新棋子位于任何其他蛇棋子已经存在的位置,则用户输掉游戏
唉,这些还没有在这里完成
我们仍然需要把它全部画出来,但是因为我们要跟踪蛇的位置,所以很容易。我们可以为每条蛇画一个正方形:
function drawSnake(context, snake) {
// Remember to clear the board!
ctx.clearRect(0, 0, 600, 600);
var length = snake.length;
for (var i = 0; i < length; i++) {
context.fillStyle = 'teal';
// position is its own array and looks like: [x, y]
var position = snake[i];
// our logical snake board is 60x60, but the real canvas is 600x600,
// so we multiply x and y by 10.
// We also use "9" for the width and height so theres a tiny gap
context.fillRect(position[0]*10, position[1]*10, 9, 9);
}
}
在此处查看已完成的演示。
http://jsfiddle.net/FsqXE/
请注意,它允许箭头键控制蛇以炫耀 moveSnake 方法,但常规蛇游戏的移动由计时器控制,用户通常只能更改下一个可能的方向。