制作坊贪吃蛇 专区

贪吃蛇

cxbd2020-04-23 640人围观
这一次, 我们将对游戏的关键部分进行修改, 不过考虑到整个 Microbit 的屏幕才25个像素点, 我们加个限制让蛇在长度为10的时候停止生长, 这样的话, 只要你玩得好, 游戏能一直进行下去.

贪吃蛇的身体
由于蛇的身体不再是单个game.LedSprite对象, 我们将需要将蛇的身体块存储在数组中. 我们可以定义一个initSnake函数, 该函数需要传进一组蛇身体坐标并创建相应的精灵数组.

1
2
3
4
5
6
7
function initSnake(arr: Array<number>) {
let result = [];
for (let i = 0; i + 1 < arr.length; i += 2) {
result.push(game.createSprite(arr[i], arr[i + 1]));
}
return result;
};
游戏初始化蛇的身体

1
2
3
4
5
6
let direction = 1; // initial direction is down
let dxOffset = [[1, 0], [0, 1], [-1, 0], [0, -1]];
let snake = initSnake([px, py, px + 1, py]);
//当蛇长到10像素时, 它停止增长
//避免填充LED
const maxLength = 10;
碰撞检测
蛇的下一个像素点必须不是蛇的身体, 否则蛇就会立刻狗带.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 检查(x, y)是否为蛇体的坐标之一.
function isOnSnake(x: number, y: number): boolean {
for (let body of snake) {
if (body.x() == x && body.y() == y) {
return true;
}
}
return false;
}

function validPixelCoordinate(nx: number, ny: number): boolean {
return (nx >= 0 && nx <= 4 &&
ny >= 0 && ny <= 4) && (!isOnSnake(nx, ny));
}
同样, 我们需要调整苹果生成函数, 确保新苹果不位于贪吃蛇的身体之一上.

1
2
3
4
5
6
7
8
9
function placeNextApple() {
let x, y;
do {
x = Math.randomRange(0, 4);
y = Math.randomRange(0, 4);
} while (isOnSnake(x, y));
apple.goTo(x, y);
apple.setBrightness(100);
}
重置游戏
重置游戏resetGame函数的一项更改是在重新初始化新的主体之前, 删除贪吃蛇的身体. 删除精灵将使该精灵对象从内存中删除, 删除后的精灵对象既不会与其他精灵对象进行交互, 也不会显示在LED屏幕上.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function resetGame() {
game.setScore(0);
score = 0;
direction = 0;
px = 0;
py = 0;
// 释放蛇的身体和占用的内存
for (let s of snake) {
s.delete();
}
snake = initSnake([px, py, px + 1, py]);
placeNextApple();
game.resume();
}
蛇向前爬行
当蛇移动时, 我们可以使用Javascript的数组unshift方法将新的像素坐标推到数组的最前面. 然后, 我们需要通过pop()方法删除最后一个元素.

1
2
3
4
5
6
7
8
9
10
11
function moveForward() {
let dx = dxOffset[direction];
px += dx[0];
py += dx[1];
if (!validPixelCoordinate(px, py)) {
gameOver();
}
snake.unshift(game.createSprite(px, py));
let last = snake.pop();
last.delete();
}
贪吃蛇吃了胖 胖了吃
这部分可以在主游戏循环中处理. 当检测到蛇头和苹果之间发生碰撞时, 我们可以将新像素推到身体的尾部(复制一个尾巴).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
basic.forever(function () {
if (game.isGameOver()) {
return;
}
let delay = Math.max(100, 1000 - score * 50);
basic.pause(delay);
//letComputerPlay();
moveForward();
if (snake[0].isTouching(apple)) { // 吃到了苹果
// 在大于 maxLength 后就不长了
if (snake.length < maxLength) {
// 复制一个尾巴
snake.push(snake[snake.length - 1]);
}
score++;
placeNextApple();
}
})
3 +1

评论