贪食蛇游戏很有趣, 而且也不复杂, 是学习一门编程语言的最好的入门练手的项目. 我在加入GE后接触到GE开发的Magik语言(Wiki), 便很快的用它写了一个贪吃蛇的游戏.
今天, 我们就来用当今最火的语言 Javascript 来写一下, 你就会发现, 其实这个游戏很简单就能实现了.
画板
我们需要一个游戏场景, 也就是画板 Canvas, 画板上我们需要每次清空, 然后画上蛇和苹果.
<canvas width="400" height="400" id="game"></canvas>
然后, 我们需要定义几个全局变量:
var context;
var canvas; // 画板
var score = 0; // 分数
var bestscore = 0; // 最高分数
var grid = 16; // 每格相素点
var count = 0;
var snake = {
x: 160,
y: 160,
// 方向偏移量
dx: grid,
dy: 0,
// 蛇的身体坐标
cells: [],
// 蛇的最小长度
maxCells: 4
};
var apple = {
x: 320,
y: 320
};
游戏控制
在HTML页面加载完后, 我们可以通过事件 body.onload 来加载一个 windowload 函数.
<body onload="windowload()">
在这个函数里, 我们需要定义对蛇的控制, 也就是四个方向键. 当蛇往右的行走的时候, 方向左右键是没有效果的, 同样的, 当蛇往上行走的时候, 方向上下键是没有效果的, 这样避免了贪吃蛇马上吃到自己就狗带了.
function windowload() {
canvas = document.getElementById('game');
canvas.setAttribute('tabindex','0');
canvas.focus();
context = canvas.getContext('2d');
// 按键事件
document.addEventListener('keydown', function(e) {
// 左
if (e.which === 37 && snake.dx === 0) {
snake.dx = -grid;
snake.dy = 0;
}
// 上
else if (e.which === 38 && snake.dy === 0) {
snake.dy = -grid;
snake.dx = 0;
}
// 右
else if (e.which === 39 && snake.dx === 0) {
snake.dx = grid;
snake.dy = 0;
}
// 下
else if (e.which === 40 && snake.dy === 0) {
snake.dy = grid;
snake.dx = 0;
}
});
window.requestAnimationFrame(loop);
}
在函数的最后我们调用了 window.requestAnimationFrame函数. 这个函数需要一个回调函数. 让画板在重画的时候会调用它.
我们需要几个用到的 helper 函数.
// 返回一个在 [min, max) 的随机整数
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function showScore(score) {
document.getElementById('score').innerHTML = score;
}
function showBestScore(score) {
document.getElementById('bestscore').innerHTML = score;
}
// 重置游戏
function resetGame() {
snake.x = 160;
snake.y = 160;
snake.cells = [];
snake.maxCells = 4;
snake.dx = grid;
snake.dy = 0;
score = 0;
showScore(score);
apple.x = getRandomInt(0, 25) * grid;
apple.y = getRandomInt(0, 25) * grid;
}
主游戏循环
在游戏循环中, 我们需要递归地调用 requestAnimationFrame. 然后, 清除画布并绘制蛇的身体碎片和苹果. 如果蛇撞到墙壁或与身体碰撞, 则需要触发游戏结束. 当它移动时, 我们可以从它的尾部弹出一个坐标并将其插入到数组前面(头部).
function loop() {
requestAnimationFrame(loop);
// 缓慢游戏循环速度到15 fps = 60/4
if (++count < 4) {
return;
}
count = 0;
context.clearRect(0,0,canvas.width,canvas.height);
// 蛇的位置移到下一格
snake.x += snake.dx;
snake.y += snake.dy;
if ((snake.x < 0) || (snake.x >= canvas.width)) {
resetGame();
return;
}
if ((snake.y < 0) || (snake.y >= canvas.height)) {
resetGame();
return;
}
// 把新位置加到头部
snake.cells.unshift({x: snake.x, y: snake.y});
// 如果大于 maxCells, 我们就把尾巴去掉一个
if (snake.cells.length > snake.maxCells) {
snake.cells.pop();
}
// 画苹果
context.fillStyle = 'red';
context.fillRect(apple.x, apple.y, grid-1, grid-1);
// 每次画一个绿色的身体
context.fillStyle = 'green';
snake.cells.forEach(function(cell, index) {
// 绘制比网格小1像素的像素会在蛇体内创建网格效果, 因此您可以看到它有多长
context.fillRect(cell.x, cell.y, grid-1, grid-1);
// 吃了苹果
if (cell.x === apple.x && cell.y === apple.y) {
snake.maxCells++;
// 画板 400x400 也就是 25x25 格
apple.x = getRandomInt(0, 25) * grid;
apple.y = getRandomInt(0, 25) * grid;
score ++;
bestscore = Math.max(bestscore, score);
showBestScore(bestscore);
showScore(score);
}
// 是否和身体碰撞了
for (var i = index + 1; i < snake.cells.length; i += 1) {
// snake occupies same space as a body part. reset game
if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) {
resetGame();
return;
}
}
});
}
如果蛇可以从屏幕的一边穿越到另一边, 你则需要使用下面的代码:
// 水平穿越
if (snake.x < 0) {
snake.x = canvas.width - grid;
}
else if (snake.x >= canvas.width) {
snake.x = 0;
}
// 垂直穿越
if (snake.y < 0) {
snake.y = canvas.height - grid;
}
else if (snake.y >= canvas.height) {
snake.y = 0;
}
在线玩贪吃蛇游戏: https://helloacm.com/static/game/snake/
想立马玩贪吃蛇游戏?
英文: How to Make a Simple Snake Game in Javascript?
游戏人生
- DOTA2 玩火枪的人伤不起
- 玩DOTA输了就是在陪别人快乐
- 找回童年, 任天堂迷你版 Nintendo Classic Mini Console: Super Nintendo Entertainment System
- 终于在Steam平台上玩了最终幻想7-Remake-蒂法和爱丽丝真是美啊
- 用 Javascript 做一个贪食蛇的游戏
- Microbit 游戏编程: 贪心算法也无法让贪吃蛇永生
- Facebook/Meta的Oculus VR眼镜游戏体验
- 试用 Google 云主机游戏 Stadia
- 8位任天堂掌上游戏机: 重温童年(超级玛丽/Super Mario)
- 完蛋了, 我被美女包围了!
上一篇: 英国 stagecoach 表演课真是又贵又费时的课外兴趣班啊
下一篇: Microbit 游戏编程: 贪心算法也无法让贪吃蛇永生
扫描二维码,分享本文到微信朋友圈

