第一步:贪吃蛇算法:
首先用Jscex把整个游戏的Loop搭建起来:
var moveAsync = eval(Jscex.compile("async", function (p) {
while (true) {
$await(Jscex.Async.sleep(100));
}
}));
然后把相关的算法加进去,首先是蛇的移动算法,采用每一个时间间隔去掉尾部一个节点,并且向蛇的头部云运动方向增加一个节点的方法:
if (direction == "right") {
p.push({
x: p[p.length - 1].x + 1,
y: p[p.length - 1].y
});
}
if (direction == "left") {
p.push({
x: p[p.length - 1].x - 1,
y: p[p.length - 1].y
});
}
if (direction == "up") {
p.push({
x: p[p.length - 1].x,
y: p[p.length - 1].y - 1
});
}
if (direction == "down") {
p.push({
x: p[p.length - 1].x,
y: p[p.length - 1].y + 1
});
}
蛇的头部运动方向共有4个,蛇在运动时都是往头部运动方向增加一个节点,因为当蛇吃到食物时节点增加一个,所以不是每次都会去掉尾部节点,在判断到蛇没有吃到食物时去掉尾部的一个节点:
if (p[p.length - 1].x == foodPositions.x && p[p.length - 1].y == foodPositions.y) {
foodPositions.x = -1;
foodPositions.y = -1;
} else {
clearColor(p[0]);
p.shift();
}
然后是随机生成蛇的食物(这里可以加一个递归,如果生成的位置和蛇的位置重叠,则重新生成,一直递归下去,直到没有重叠)。
var MR = Math.random;
function drawSnakeAndFood(p) {
if (foodPositions.x == -1 && foodPositions.y == -1) {
foodPositions.x = MR() * 40 | 0;
foodPositions.y = MR() * 40 | 0;
}
cxt.fillStyle = randomColor();
cxt.fillRect(foodPositions.x * width, foodPositions.y * height, height, width);
for (i = 0; i < p.length; i++) {
cxt.fillStyle = "#D1EEEE";
cxt.fillRect(p[i].x * width, p[i].y * height, height, width);
}
}
GameOver 的判定
if (p[p.length - 1].x < 0 || p[p.length - 1].x > 39 || p[p.length - 1].y < 0 || p[p.length - 1].y > 39) {
gameOver = true;
}
if (IsInSnake(p, {
x: p[p.length - 1].x,
y: p[p.length - 1].y
})) {
gameOver = true;
}
GameOver分两种情况,一种是撞到墙和障碍物,一种是撞到自己身体,代码如下:
var moveAsync = eval(Jscex.compile("async", function (p) {
while (true) {
$await(Jscex.Async.sleep(100));
if (p[p.length - 1].x < 0 || p[p.length - 1].x > 39 || p[p.length - 1].y < 0 || p[p.length - 1].y > 39) {
gameOver = true;
}
if (direction == "right") {
if (lastDirection != "left") {
lastDirection = "right";
p.push({
x: p[p.length - 1].x + 1,
y: p[p.length - 1].y
});
if (p[p.length - 1].x == foodPositions.x && p[p.length - 1].y == foodPositions.y) {
foodPositions.x = -1;
foodPositions.y = -1;
} else {
clearColor(p[0]);
p.shift();
}
}
else {
direction = "left";
}
}
if (direction == "left") {
if (lastDirection != "right") {
lastDirection = "left";
p.push({
x: p[p.length - 1].x - 1,
y: p[p.length - 1].y
});
if (p[p.length - 1].x == foodPositions.x && p[p.length - 1].y == foodPositions.y) {
foodPositions.x = -1;
foodPositions.y = -1;
} else {
clearColor(p[0]);
p.shift();
}
}
else {
direction = "right";
}
}
if (direction == "up") {
if (lastDirection != "down") {
lastDirection = "up";
p.push({
x: p[p.length - 1].x,
y: p[p.length - 1].y - 1
});
if (p[p.length - 1].x == foodPositions.x && p[p.length - 1].y == foodPositions.y) {
foodPositions.x = -1;
foodPositions.y = -1;
} else {
clearColor(p[0]);
p.shift();
}
}
else {
direction = "down";
}
}
if (direction == "down") {
if (lastDirection != "up") {
lastDirection = "down";
p.push({
x: p[p.length - 1].x,
y: p[p.length - 1].y + 1
});
if (p[p.length - 1].x == foodPositions.x && p[p.length - 1].y == foodPositions.y) {
foodPositions.x = -1;
foodPositions.y = -1;
} else {
clearColor(p[0]);
p.shift();
}
}
else {
direction = "up";
}
}
if (IsInSnake(p, {
x: p[p.length - 1].x,
y: p[p.length - 1].y
})) {
gameOver = true;
}
drawSnakeAndFood(p);
if (gameOver) {
drawGameOver();
document.getElementById("btnReset").disabled = "";
break;
}
}
}));
运行效果如下: