今天我们来一起用JavaScript做一个贪吃蛇小游戏。就像养一条永远吃不饱的小蛇,我们要用键盘操控它满地图找"披萨"吃!准备好了吗?让我们开始吧~ 🐍🍕
第一章:搭建游戏舞台(HTML+CSS)
<!DOCTYPE html>
<html>
<head>
<title>贪吃蛇大冒险</title>
<style>
body {
margin: 0;
padding: 0;
background: #ecf0f1;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
background: #34495e;
color: #ecf0f1;
}
#score {
font-size: 18px;
}
#restart {
font-size: 18px;
cursor: pointer;
}
/* 游戏舞台 */
#game-board {
position: relative;
margin: 0 auto;
background: #2c3e50; /* 深蓝背景像夜空 */
border: 3px solid #ecf0f1; /* 白色边框 */
}
/* 贪吃蛇的皮肤 */
.snake {
background: #2ecc71; /* 青绿色蛇身 */
border: 1px solid #27ae60; /* 深绿边框 */
}
/* 蛇头的特别装扮 */
.snake-head {
background: #e74c3c !important; /* 红色蛇头 */
}
/* 食物看起来像小披萨 */
.food {
background: #f1c40f; /* 金黄色 */
border-radius: 50%; /* 圆形 */
}
</style>
</head>
<body>
<div class="header">
<div id="score">得分:0</div>
<div id="restart">重新开始</div>
</div>
<div id="game-board"></div>
</body>
</html>
这里我们创建了:
- 一个显示得分的区域
- 游戏画布(用CSS绘制背景和边框)
- 定义了蛇和食物的样式,用颜色区分
第二章:召唤贪吃蛇(JavaScript核心代码)
<script>
class SnakeGame {
constructor() {
this.boardSize = 20; // 20x20的网格
this.cellSize = 20; // 每个格子20像素
this.snake = [[10, 10]]; // 初始位置
this.direction = "right"; // 初始方向
this.food = this.generateFood();
this.score = 0;
// 创建游戏地图
this.board = document.getElementById("game-board");
this.board.style.width = this.boardSize * this.cellSize + "px";
this.board.style.height = this.boardSize * this.cellSize + "px";
// 绘制初始地图
this.draw();
// 开始游戏循环
this.gameLoop = setInterval(() => this.move(), 150);
// 监听键盘事件
document.addEventListener("keydown", (e) => this.handleKeyPress(e));
}
// 绘制整个地图
draw() {
this.board.innerHTML = ""; // 清空画布
// 绘制蛇
this.snake.forEach((segment, index) => {
const cell = document.createElement("div");
cell.style.width = this.cellSize + "px";
cell.style.height = this.cellSize + "px";
cell.style.position = "absolute";
cell.style.left = segment[0] * this.cellSize + "px";
cell.style.top = segment[1] * this.cellSize + "px";
cell.className = "snake" + (index === 0 ? " snake-head" : "");
this.board.appendChild(cell);
});
// 绘制食物
const foodCell = document.createElement("div");
foodCell.style.width = this.cellSize + "px";
foodCell.style.height = this.cellSize + "px";
foodCell.style.position = "absolute";
foodCell.style.left = this.food[0] * this.cellSize + "px";
foodCell.style.top = this.food[1] * this.cellSize + "px";
foodCell.className = "food";
this.board.appendChild(foodCell);
}
// 生成随机食物
generateFood() {
while (true) {
const x = Math.floor(Math.random() * this.boardSize);
const y = Math.floor(Math.random() * this.boardSize);
// 确保食物不在蛇身上
if (
!this.snake.some(
(segment) => segment[0] === x && segment[1] === y
)
) {
return [x, y];
}
}
}
// 处理键盘事件
handleKeyPress(e) {
const keyMap = {
ArrowUp: "up",
ArrowDown: "down",
ArrowLeft: "left",
ArrowRight: "right",
};
const newDir = keyMap[e.key];
// 禁止反向移动(比如不能从右直接转左)
if (
newDir &&
!(
(this.direction === "up" && newDir === "down") ||
(this.direction === "down" && newDir === "up") ||
(this.direction === "left" && newDir === "right") ||
(this.direction === "right" && newDir === "left")
)
) {
this.direction = newDir;
}
}
// 蛇的移动逻辑
move() {
const head = [...this.snake[0]];
// 计算新头部位置
switch (this.direction) {
case "up":
head[1]--;
break;
case "down":
head[1]++;
break;
case "left":
head[0]--;
break;
case "right":
head[0]++;
break;
}
// 碰撞检测
if (
head[0] < 0 ||
head[0] >= this.boardSize || // 撞墙
head[1] < 0 ||
head[1] >= this.boardSize ||
this.snake.some(
(segment) => segment[0] === head[0] && segment[1] === head[1]
) // 撞自己
) {
clearInterval(this.gameLoop);
alert("游戏结束!得分:" + this.score);
return;
}
// 吃食物逻辑
if (head[0] === this.food[0] && head[1] === this.food[1]) {
this.score += 10;
document.getElementById("score").textContent =
"得分:" + this.score;
this.food = this.generateFood();
} else {
this.snake.pop(); // 没吃到食物就去尾
}
this.snake.unshift(head); // 添加新头部
this.draw();
}
}
document.getElementById("restart").addEventListener("click", () => {
document.getElementById("game-board").innerHTML = ""; // 清空游戏板
document.getElementById("score").textContent = "得分:0"; // 重置得分
new SnakeGame(); // 重新开始游戏
});
// 等待页面加载完成后再启动游戏
window.addEventListener("load", (
new SnakeGame()
));
</script>
第三章:代码核心原理解析
1. 贪吃蛇的骨架(数据结构)
- 用二维数组
snake
存储身体坐标,如[[10,10], [9,10], [8,10]] - 蛇头总是数组的第一个元素
- 移动时在头部添加新坐标,尾部删除(除非吃到食物)
2. 移动的魔法(move方法)
- 像传送带一样工作:每次移动时:
- 复制蛇头坐标
- 根据方向修改坐标
- 检查是否撞墙/撞自己
- 吃到食物就长身体,否则保持长度
- 把新头部插入数组开头
3. 食物的诞生(generateFood方法)
- 使用while循环确保食物不会出现在蛇身上
- 随机生成坐标直到找到合法位置
4. 控制蛇的秘籍(handleKeyPress)
- 使用键盘事件监听方向键
- 禁止180度急转弯(比如不能从右直接转左)
5. 视觉呈现(draw方法)
- 通过动态创建div元素实现
- 蛇头用特殊样式(红色)
- 每次重绘前清空画布
第四章:如何让你的蛇更酷?
试试这些升级方案:
- 速度升级:每吃5个食物加快游戏速度
if(this.score % 50 === 0 && this.score > 0) {
clearInterval(this.gameLoop);
this.gameLoop = setInterval(() => this.move(), 150 - Math.floor(this.score/50)*10);
}
- 特殊食物:随机生成加速/减速食物
- 皮肤系统:让玩家选择不同颜色的蛇
- 关卡系统:增加障碍物
第五章:启动你的贪吃蛇!
把以上所有代码保存为.html文件,用浏览器打开就能玩啦!用方向键控制你的小蛇,看看你能得多少分~ 🚀