<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>经典贪吃蛇</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Microsoft YaHei", sans-serif;
}
body {
background-color: #1a1a1a;
display: flex;
flex-direction: column;
align-items: center;
padding-top: 30px;
color: white;
}
.game-box {
border: 3px solid #4CAF50;
background-color: #000;
}
.score {
font-size: 24px;
margin-bottom: 15px;
color: #ffeb3b;
}
.tips {
margin-top: 15px;
font-size: 16px;
color: #ccc;
}
</style>
</head>
<body>
<div class="score">得分:<span id="score">0</span></div>
<canvas id="game" width="400" height="400" class="game-box"></canvas>
<div class="tips">操作:↑↓←→ 控制方向 | 吃到食物得分 | 撞墙/撞自己游戏结束</div>
<script>
// 获取画布和上下文
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
const scoreEl = document.getElementById('score');
// 游戏基础配置
const gridSize = 20; // 格子大小
const tileCount = canvas.width / gridSize; // 总格子数
// 蛇的初始属性
let snake = [
{ x: 10, y: 10 } // 蛇头初始位置
];
let dx = 0; // X轴移动速度
let dy = 0; // Y轴移动速度
// 食物属性
let food = { x: 15, y: 15 };
let score = 0;
// 游戏循环定时器
let gameLoop;
// 键盘控制方向
document.addEventListener('keydown', changeDirection);
// 开始游戏
startGame();
// 游戏启动函数
function startGame() {
gameLoop = setInterval(updateGame, 100); // 每100ms刷新一次
}
// 游戏更新逻辑
function updateGame() {
// 碰撞检测
if (checkCollision()) {
clearInterval(gameLoop);
alert(`游戏结束!最终得分:${score}`);
return;
}
// 清空画布
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 移动蛇
moveSnake();
// 吃食物检测
if (snake[0].x === food.x && snake[0].y === food.y) {
score += 10;
scoreEl.textContent = score;
createFood(); // 生成新食物
} else {
snake.pop(); // 没吃到食物就删除尾部
}
// 绘制蛇和食物
drawSnake();
drawFood();
}
// 蛇移动
function moveSnake() {
const head = { x: snake[0].x + dx, y: snake[0].y + dy };
snake.unshift(head); // 新头部添加到前面
}
// 绘制蛇
function drawSnake() {
ctx.fillStyle = '#4CAF50';
snake.forEach(segment => {
ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize - 2, gridSize - 2);
});
}
// 绘制食物
function drawFood() {
ctx.fillStyle = '#ff5722';
ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize - 2, gridSize - 2);
}
// 生成随机食物
function createFood() {
food.x = Math.floor(Math.random() * tileCount);
food.y = Math.floor(Math.random() * tileCount);
// 避免食物生成在蛇身上
snake.forEach(segment => {
if (segment.x === food.x && segment.y === food.y) {
createFood();
}
});
}
// 方向控制
function changeDirection(e) {
// 防止反向移动(比如向上时不能直接向下)
const up = 38;
const down = 40;
const left = 37;
const right = 39;
if (e.keyCode === up && dy !== 1) {
dx = 0;
dy = -1;
}
if (e.keyCode === down && dy !== -1) {
dx = 0;
dy = 1;
}
if (e.keyCode === left && dx !== 1) {
dx = -1;
dy = 0;
}
if (e.keyCode === right && dx !== -1) {
dx = 1;
dy = 0;
}
}
// 碰撞检测
function checkCollision() {
// 撞墙
if (snake[0].x < 0 || snake[0].x >= tileCount ||
snake[0].y < 0 || snake[0].y >= tileCount) {
return true;
}
// 撞自己
for (let i = 1; i < snake.length; i++) {
if (snake[0].x === snake[i].x && snake[0].y === snake[i].y) {
return true;
}
}
return false;
}
</script>
</body>
</html>
使用方法
- 把上面所有代码复制下来
- 新建一个文本文档,粘贴代码
- 将文件后缀名改为
.html(比如snake.html) - 双击文件,用浏览器打开即可开始游戏
游戏操作说明
- 方向键 ↑↓←→ 控制蛇的移动方向
- 吃到红色食物得分 + 10,蛇自动变长
- 撞墙或者撞到自己的身体,游戏结束
- 界面实时显示当前得分
核心功能
- 流畅的蛇身移动动画
- 随机生成食物(不会生成在蛇身上)
- 严格的碰撞检测(墙 + 自身)
- 实时分数统计
- 防反向移动 bug(不会直接掉头撞死)
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END





暂无评论内容