<!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;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background: linear-gradient(135deg, #667eea, #764ba2);
font-family: Arial, sans-serif;
}
#game-container {
text-align: center;
background: rgba(255, 255, 255, 0.1);
padding: 20px;
border-radius: 15px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
}
#score {
font-size: 24px;
color: #fff;
margin-bottom: 10px;
text-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
}
#game-over {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.8);
color: #fff;
padding: 20px;
border-radius: 10px;
font-size: 24px;
z-index: 10;
}
canvas {
background: #1a1a1a;
border: 2px solid #fff;
border-radius: 10px;
box-shadow: 0 0 15px rgba(255, 255, 255, 0.3);
}
</style>
</head>
<body>
<div id="game-container">
<div id="score">得分: 0</div>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<div id="game-over">游戏结束!<br>按空格键重新开始</div>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const gridSize = 20;
const tileCount = canvas.width / gridSize;
let snake = [
{ x: 10, y: 10 },
];
let food = { x: 15, y: 15 };
let dx = 0;
let dy = 0;
let score = 0;
let gameLoop;
let gameOver = false;
// 初始化游戏
function initGame() {
snake = [{ x: 10, y: 10 }];
food = generateFood();
dx = 0;
dy = 0;
score = 0;
gameOver = false;
document.getElementById('score').textContent = `得分: ${score}`;
document.getElementById('game-over').style.display = 'none';
clearInterval(gameLoop);
gameLoop = setInterval(draw, 100);
}
// 绘制游戏
function draw() {
if (gameOver) return;
// 移动蛇
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 += 1;
document.getElementById('score').textContent = `得分: ${score}`;
food = generateFood();
} else {
snake.pop();
}
// 碰撞检测
if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount || collision(head)) {
gameOver = true;
document.getElementById('game-over').style.display = 'block';
return;
}
// 清空画布
ctx.fillStyle = '#1a1a1a';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制蛇
snake.forEach((segment, index) => {
ctx.fillStyle = index === 0 ? '#ff6b6b' : '#4ecdc4';
ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize - 2, gridSize - 2);
ctx.strokeStyle = '#fff';
ctx.strokeRect(segment.x * gridSize, segment.y * gridSize, gridSize - 2, gridSize - 2);
});
// 绘制食物
ctx.fillStyle = '#ffe66d';
ctx.beginPath();
ctx.arc(food.x * gridSize + gridSize / 2, food.y * gridSize + gridSize / 2, gridSize / 2 - 2, 0, Math.PI * 2);
ctx.fill();
}
// 生成食物
function generateFood() {
const foodPos = {
x: Math.floor(Math.random() * tileCount),
y: Math.floor(Math.random() * tileCount),
};
return snake.some(segment => segment.x === foodPos.x && segment.y === foodPos.y) ? generateFood() : foodPos;
}
// 碰撞检测
function collision(head) {
return snake.slice(1).some(segment => segment.x === head.x && segment.y === head.y);
}
// 键盘控制
document.addEventListener('keydown', (e) => {
switch (e.key) {
case 'ArrowUp': if (dy === 0) { dx = 0; dy = -1; } break;
case 'ArrowDown': if (dy === 0) { dx = 0; dy = 1; } break;
case 'ArrowLeft': if (dx === 0) { dx = -1; dy = 0; } break;
case 'ArrowRight': if (dx === 0) { dx = 1; dy = 0; } break;
case ' ': if (gameOver) initGame(); break;
}
});
// 开始游戏
initGame();
</script>
</body>
</html>
index.html