您只需要将下面的代码复制到一个文本编辑器中,保存为 snake.html 文件,然后用浏览器打开这个文件即可开始游戏。

(图片来源网络,侵删)
完整代码 (snake.html)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">贪吃蛇游戏</title>
<style>
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #1e3c72, #2a5298);
color: #fff;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
flex-direction: column;
}
/* 游戏容器 */
.game-container {
text-align: center;
background: rgba(0, 0, 0, 0.3);
padding: 30px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}
h1 {
margin-bottom: 20px;
font-size: 2.5em;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
/* 游戏信息栏 */
.game-info {
display: flex;
justify-content: space-between;
margin-bottom: 15px;
font-size: 1.2em;
max-width: 400px;
}
/* 游戏画布 */
#gameCanvas {
border: 3px solid #fff;
border-radius: 10px;
background-color: #111;
box-shadow: 0 0 20px rgba(255, 255, 255, 0.2);
}
/* 控制按钮 */
.controls {
margin-top: 20px;
}
button {
background-color: #4CAF50;
color: white;
border: none;
padding: 12px 24px;
font-size: 16px;
border-radius: 8px;
cursor: pointer;
margin: 0 10px;
transition: background-color 0.3s, transform 0.1s;
}
button:hover {
background-color: #45a049;
}
button:active {
transform: scale(0.98);
}
/* 游戏结束覆盖层 */
.game-over {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.8);
padding: 30px;
border-radius: 10px;
text-align: center;
display: none; /* 默认隐藏 */
}
.game-over h2 {
color: #ff4757;
margin-bottom: 15px;
}
/* 移动端控制按钮 */
.mobile-controls {
display: none; /* 默认隐藏 */
margin-top: 20px;
grid-template-columns: repeat(3, 60px);
grid-template-rows: repeat(3, 60px);
gap: 5px;
justify-content: center;
}
.mobile-controls button {
width: 60px;
height: 60px;
font-size: 24px;
padding: 0;
}
.mobile-controls button:nth-child(2) { grid-column: 2; grid-row: 1; } /* 上 */
.mobile-controls button:nth-child(3) { grid-column: 1; grid-row: 2; } /* 左 */
.mobile-controls button:nth-child(4) { grid-column: 3; grid-row: 2; } /* 右 */
.mobile-controls button:nth-child(5) { grid-column: 2; grid-row: 3; } /* 下 */
/* 响应式设计:当屏幕宽度小于600px时显示移动端控制 */
@media (max-width: 600px) {
.mobile-controls {
display: grid;
}
}
</style>
</head>
<body>
<div class="game-container">
<h1>贪吃蛇</h1>
<div class="game-info">
<div>得分: <span id="score">0</span></div>
<div>最高分: <span id="highScore">0</span></div>
</div>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<div class="controls">
<button id="startBtn">开始游戏</button>
<button id="pauseBtn">暂停</button>
</div>
<div class="mobile-controls">
<button id="upBtn">↑</button>
<button id="leftBtn">←</button>
<button id="rightBtn">→</button>
<button id="downBtn">↓</button>
</div>
</div>
<div class="game-over" id="gameOverScreen">
<h2>游戏结束!</h2>
<p>你的得分是: <span id="finalScore">0</span></p>
<button id="restartBtn">重新开始</button>
</div>
<script>
// 游戏配置
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreElement = document.getElementById('score');
const highScoreElement = document.getElementById('highScore');
const finalScoreElement = document.getElementById('finalScore');
const gameOverScreen = document.getElementById('gameOverScreen');
// 游戏设置
const gridSize = 20; // 网格大小
const tileCount = canvas.width / gridSize; // 网格数量 (20x20)
let snake = [
{x: 10, y: 10} // 蛇的初始位置
];
let food = {};
let dx = 0; // x轴方向移动速度
let dy = 0; // y轴方向移动速度
let score = 0;
let highScore = localStorage.getItem('snakeHighScore') || 0;
let gameRunning = false;
let gamePaused = false;
highScoreElement.textContent = highScore;
// 生成食物
function generateFood() {
food = {
x: Math.floor(Math.random() * tileCount),
y: Math.floor(Math.random() * tileCount)
};
// 确保食物不会生成在蛇身上
for (let segment of snake) {
if (segment.x === food.x && segment.y === food.y) {
generateFood(); // 如果重叠,递归调用直到找到合适位置
return;
}
}
}
// 绘制游戏元素
function drawGame() {
// 清空画布
ctx.fillStyle = '#111';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制蛇
ctx.fillStyle = '#4CAF50'; // 蛇的颜色
for (let segment of snake) {
ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize - 2, gridSize - 2);
}
// 绘制蛇头(用不同颜色)
ctx.fillStyle = '#8BC34A';
ctx.fillRect(snake[0].x * gridSize, snake[0].y * gridSize, gridSize - 2, gridSize - 2);
// 绘制食物
ctx.fillStyle = '#ff4757'; // 食物的颜色
ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize - 2, gridSize - 2);
}
// 移动蛇
function moveSnake() {
const head = {x: snake[0].x + dx, y: snake[0].y + dy};
snake.unshift(head); // 在蛇头添加一个新的头部
// 检查是否吃到食物
if (head.x === food.x && head.y === food.y) {
score += 10;
scoreElement.textContent = score;
generateFood();
} else {
snake.pop(); // 如果没吃到,移除蛇尾
}
}
// 检查游戏是否结束
function checkGameOver() {
const head = snake[0];
// 1. 撞墙检测
if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) {
return true;
}
// 2. 撞到自己检测
for (let i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) {
return true;
}
}
return false;
}
// 游戏主循环
function gameLoop() {
if (!gameRunning || gamePaused) return;
moveSnake();
if (checkGameOver()) {
gameOver();
return;
}
drawGame();
setTimeout(gameLoop, 100); // 控制游戏速度
}
// 游戏结束逻辑
function gameOver() {
gameRunning = false;
finalScoreElement.textContent = score;
gameOverScreen.style.display = 'block';
// 更新最高分
if (score > highScore) {
highScore = score;
highScoreElement.textContent = highScore;
localStorage.setItem('snakeHighScore', highScore);
}
}
// 开始游戏
function startGame() {
snake = [{x: 10, y: 10}];
dx = 0;
dy = 0;
score = 0;
scoreElement.textContent = score;
generateFood();
gameRunning = true;
gamePaused = false;
gameOverScreen.style.display = 'none';
gameLoop();
}
// 暂停/继续游戏
function togglePause() {
if (!gameRunning) return;
gamePaused = !gamePaused;
if (!gamePaused) {
gameLoop();
}
}
// 键盘控制
document.addEventListener('keydown', (e) => {
if (!gameRunning || gamePaused) return;
// 防止蛇直接掉头
switch(e.key) {
case 'ArrowUp':
if (dy !== 1) { dx = 0; dy = -1; }
break;
case 'ArrowDown':
if (dy !== -1) { dx = 0; dy = 1; }
break;
case 'ArrowLeft':
if (dx !== 1) { dx = -1; dy = 0; }
break;
case 'ArrowRight':
if (dx !== -1) { dx = 1; dy = 0; }
break;
}
});
// 移动端按钮控制
document.getElementById('upBtn').addEventListener('click', () => { if (gameRunning && !gamePaused && dy !== 1) { dx = 0; dy = -1; } });
document.getElementById('downBtn').addEventListener('click', () => { if (gameRunning && !gamePaused && dy !== -1) { dx = 0; dy = 1; } });
document.getElementById('leftBtn').addEventListener('click', () => { if (gameRunning && !gamePaused && dx !== 1) { dx = -1; dy = 0; } });
document.getElementById('rightBtn').addEventListener('click', () => { if (gameRunning && !gamePaused && dx !== -1) { dx = 1; dy = 0; } });
// 按钮事件监听
document.getElementById('startBtn').addEventListener('click', startGame);
document.getElementById('pauseBtn').addEventListener('click', togglePause);
document.getElementById('restartBtn').addEventListener('click', startGame);
// 初始绘制
drawGame();
</script>
</body>
</html>
代码结构解析
这个贪吃蛇游戏主要由三部分构成:HTML、CSS 和 JavaScript。
HTML 结构
<canvas>: 这是游戏的核心画布,所有的图形(蛇、食物)都将在这里被绘制。<div>容器: 用于包裹游戏界面,包括标题、得分显示、控制按钮等,方便进行样式布局。<button>: 提供了“开始游戏”、“暂停”和“重新开始”的功能。<span>: 用于动态显示当前得分和最高分。<div class="game-over">: 游戏结束时显示的弹窗,覆盖在游戏画布上。
CSS 样式
- 整体布局: 使用
flexbox将游戏容器居中显示,并设置了一个漂亮的渐变背景。 - 画布样式: 给
canvas添加了白色边框和圆角,使其看起来像一个独立的游戏区域。 - 按钮样式: 设计了有悬停和点击效果的按钮,提升用户体验。
- 响应式设计: 通过
@media查询,在屏幕宽度较小时(如手机)显示虚拟方向键,方便触摸操作。
JavaScript 游戏逻辑
这是游戏最核心的部分,负责处理所有的游戏行为。
-
变量定义:
snake: 一个数组,存储蛇身体的每一节坐标。[{x:10, y:10}, {x:9, y:10}]表示一个两节长的蛇。food: 一个对象,存储食物的坐标。dx,dy: 控制蛇的移动方向。dx=1, dy=0表示向右移动。score,highScore: 记录当前得分和历史最高分,最高分使用localStorage保存,这样即使刷新页面也不会丢失。
-
核心函数:
(图片来源网络,侵删)generateFood(): 随机生成食物的坐标,并确保不会生成在蛇身上。drawGame(): 清空画布,然后分别绘制蛇和食物。moveSnake(): 根据当前方向dx,dy计算新的蛇头位置,并将其添加到蛇身体数组的开头,如果蛇头碰到食物,则身体增长(不删除尾部);否则,删除蛇尾。- `checkGameOver()**: 检查游戏是否结束,条件有两个:蛇头是否撞到墙壁,或者蛇头是否撞到了自己的身体。
gameLoop(): 游戏的主循环,它调用moveSnake()和drawGame(),并使用setTimeout来控制游戏速度(每100毫秒执行一次)。startGame() / gameOver() / togglePause(): 控制游戏状态(开始、结束、暂停)的函数。
-
事件监听:
- 键盘事件: 监听键盘的上下左右箭头键,来改变蛇的移动方向,代码中加入了防止蛇直接掉头的逻辑。
- 按钮事件: 监听“开始”、“暂停”等按钮的点击事件,调用相应的游戏控制函数。
如何运行和修改
- 运行: 将上述全部代码复制到一个名为
snake.html的文件中,然后用 Chrome、Firefox 等任何现代浏览器打开它即可。 - 修改:
- 改变游戏速度: 修改
gameLoop函数中的setTimeout的延迟时间,数值越小,游戏速度越快。 - 改变颜色: 在 CSS 的
drawGame函数中修改fillStyle的值,或在 HTML 的<style>部分修改对应的 CSS 类。 - 改变画布大小: 修改
<canvas>的width和height属性,同时也要相应调整gridSize和tileCount变量,以确保网格划分正确。
- 改变游戏速度: 修改
这个贪吃蛇游戏代码结构清晰,功能完整,并且具有良好的用户界面,是学习和实践网页游戏开发的绝佳范例。

(图片来源网络,侵删)
