

源码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>贪吃蛇游戏</title>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
font-family: Arial, sans-serif;
}
#game-container {
position: relative;
}
#gameCanvas {
border: 2px solid #333;
background-color: #fff;
}
#score {
position: absolute;
top: -30px;
left: 0;
font-size: 20px;
font-weight: bold;
}
#game-over {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
background-color: rgba(0, 0, 0, 0.8);
color: white;
padding: 20px;
border-radius: 10px;
}
#restart-btn {
margin-top: 10px;
padding: 8px 16px;
font-size: 16px;
cursor: pointer;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
}
#restart-btn:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<div id="game-container">
<div id="score">分数: 0</div>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<div id="game-over">
<h2>游戏结束!</h2>
<p>最终分数: <span id="final-score">0</span></p>
<button id="restart-btn">重新开始</button>
</div>
</div>
<script src="game.js"></script>
</body>
</html>
// 游戏配置
const config = {
gridSize: 20,
initialSpeed: 200,
speedIncrease: 5
};
// 游戏状态
let snake = [];
let food = null;
let direction = 'right';
let nextDirection = 'right';
let score = 0;
let gameLoop = null;
let currentSpeed = config.initialSpeed;
// 获取DOM元素
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreElement = document.getElementById('score');
const gameOverElement = document.getElementById('game-over');
const finalScoreElement = document.getElementById('final-score');
const restartButton = document.getElementById('restart-btn');
// 计算网格大小
const cellSize = canvas.width / config.gridSize;
// 初始化游戏
function initGame() {
// 初始化蛇
snake = [
{ x: 5, y: 5 },
{ x: 4, y: 5 },
{ x: 3, y: 5 }
];
// 重置游戏状态
direction = 'right';
nextDirection = 'right';
score = 0;
currentSpeed = config.initialSpeed;
scoreElement.textContent = `分数: ${score}`;
gameOverElement.style.display = 'none';
// 生成第一个食物
generateFood();
// 开始游戏循环
if (gameLoop) clearInterval(gameLoop);
gameLoop = setInterval(gameStep, currentSpeed);
}
// 生成食物
function generateFood() {
let newFood;
do {
newFood = {
x: Math.floor(Math.random() * config.gridSize),
y: Math.floor(Math.random() * config.gridSize)
};
} while (snake.some(segment => segment.x === newFood.x && segment.y === newFood.y));
food = newFood;
}
// 游戏步骤
function gameStep() {
// 更新方向
direction = nextDirection;
// 获取蛇头
const head = { ...snake[0] };
// 根据方向移动蛇头
switch (direction) {
case 'up': head.y--; break;
case 'down': head.y++; break;
case 'left': head.x--; break;
case 'right': head.x++; break;
}
// 检查碰撞
if (isCollision(head)) {
gameOver();
return;
}
// 移动蛇
snake.unshift(head);
// 检查是否吃到食物
if (head.x === food.x && head.y === food.y) {
score += 10;
scoreElement.textContent = `分数: ${score}`;
generateFood();
// 加快游戏速度
currentSpeed = Math.max(50, currentSpeed - config.speedIncrease);
clearInterval(gameLoop);
gameLoop = setInterval(gameStep, currentSpeed);
} else {
snake.pop();
}
// 绘制游戏
draw();
}
// 碰撞检测
function isCollision(head) {
// 检查是否撞墙
if (head.x < 0 || head.x >= config.gridSize || head.y < 0 || head.y >= config.gridSize) {
return true;
}
// 检查是否撞到自己
return snake.some(segment => segment.x === head.x && segment.y === head.y);
}
// 绘制游戏
function draw() {
// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制蛇
snake.forEach((segment, index) => {
ctx.fillStyle = index === 0 ? '#2ecc71' : '#27ae60';
ctx.fillRect(segment.x * cellSize, segment.y * cellSize, cellSize - 1, cellSize - 1);
});
// 绘制食物
ctx.fillStyle = '#e74c3c';
ctx.fillRect(food.x * cellSize, food.y * cellSize, cellSize - 1, cellSize - 1);
}
// 游戏结束
function gameOver() {
clearInterval(gameLoop);
gameOverElement.style.display = 'block';
finalScoreElement.textContent = score;
}
// 键盘控制
document.addEventListener('keydown', (event) => {
switch (event.key) {
case 'ArrowUp':
if (direction !== 'down') nextDirection = 'up';
break;
case 'ArrowDown':
if (direction !== 'up') nextDirection = 'down';
break;
case 'ArrowLeft':
if (direction !== 'right') nextDirection = 'left';
break;
case 'ArrowRight':
if (direction !== 'left') nextDirection = 'right';
break;
}
});
// 重启按钮事件
restartButton.addEventListener('click', initGame);
// 开始游戏
initGame();