<!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>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); font-family: Arial, sans-serif; }
.game-container { text-align: center; }
h1 { color: white; margin-bottom: 20px; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); }
.score-board { color: white; font-size: 24px; margin-bottom: 15px; }
#gameCanvas { border: 4px solid white; border-radius: 10px; background-color: #2c3e50; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); }
.controls { margin-top: 20px; }
button { padding: 12px 30px; font-size: 18px; background-color: #f39c12; color: white; border: none; border-radius: 25px; cursor: pointer; }
.instructions { color: white; margin-top: 20px; font-size: 14px; }
</style>
</head>
<body>
<div class="game-container">
<h1>🐍 贪吃蛇游戏</h1>
<div class="score-board">得分:<span id="score">0</span> | 最高分:<span id="highScore">0</span></div>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<div class="controls"><button id="startBtn">开始游戏</button></div>
<div class="instructions">使用方向键 ↑ ↓ ← → 或 WASD 控制蛇的移动</div>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreEl = document.getElementById('score');
const highScoreEl = document.getElementById('highScore');
const startBtn = document.getElementById('startBtn');
const gridSize = 20;
const tileCount = 20;
let snake = [];
let food = {x:0, y:0};
let dx = 0, dy = 0;
let score = 0, highScore = 0;
let gameInterval, isRunning = false;
highScoreEl.textContent = 0;
function initGame() {
snake = [{x:10, y:10}, {x:9, y:10}, {x:8, y:10}];
dx = 1; dy = 0; score = 0; scoreEl.textContent = '0';
placeFood();
}
function placeFood() {
food = {x: Math.floor(Math.random()*20), y: Math.floor(Math.random()*20)};
}
function drawGame() {
ctx.fillStyle = '#2c3e50'; ctx.fillRect(0, 0, 400, 400);
ctx.strokeStyle = '#34495e';
for (let i = 0; i <= 20; i++) {
ctx.beginPath(); ctx.moveTo(i*20, 0); ctx.lineTo(i*20, 400); ctx.stroke();
ctx.beginPath(); ctx.moveTo(0, i*20); ctx.lineTo(400, i*20); ctx.stroke();
}
ctx.fillStyle = '#e74c3c';
ctx.beginPath();
ctx.arc(food.x*20+10, food.y*20+10, 8, 0, Math.PI*2);
ctx.fill();
snake.forEach((seg, idx) => {
ctx.fillStyle = idx === 0 ? '#2ecc71' : 'rgba(46,204,113,'+(1-idx/(snake.length+2))+')';
ctx.fillRect(seg.x*20+1, seg.y*20+1, 18, 18);
});
}
function updateGame() {
const head = {x: snake[0].x + dx, y: snake[0].y + dy};
if (head.x < 0 || head.x >= 20 || head.y < 0 || head.y >= 20 || snake.some(s => s.x === head.x && s.y === head.y)) {
clearInterval(gameInterval); isRunning = false;
ctx.fillStyle = 'rgba(0,0,0,0.7)'; ctx.fillRect(0, 0, 400, 400);
ctx.fillStyle = '#fff'; ctx.font = '40px Arial'; ctx.textAlign = 'center';
ctx.fillText('游戏结束!', 200, 180); ctx.font = '24px Arial';
ctx.fillText('最终得分:' + score, 200, 220); startBtn.textContent = '重新开始';
return;
}
snake.unshift(head);
if (head.x === food.x && head.y === food.y) {
score += 10; scoreEl.textContent = score; placeFood();
} else { snake.pop(); }
drawGame();
}
function startGame() {
if (isRunning) clearInterval(gameInterval);
initGame(); drawGame(); isRunning = true; startBtn.textContent = '重新开始';
gameInterval = setInterval(updateGame, 150);
}
document.addEventListener('keydown', (e) => {
if (!isRunning) return;
if (e.key === 'ArrowUp' || e.key === 'w' || e.key === 'W') { if (dy !== 1) { dx = 0; dy = -1; } }
else if (e.key === 'ArrowDown' || e.key === 's' || e.key === 'S') { if (dy !== -1) { dx = 0; dy = 1; } }
else if (e.key === 'ArrowLeft' || e.key === 'a' || e.key === 'A') { if (dx !== 1) { dx = -1; dy = 0; } }
else if (e.key === 'ArrowRight' || e.key === 'd' || e.key === 'D') { if (dx !== -1) { dx = 1; dy = 0; } }
});
startBtn.addEventListener('click', startGame);
drawGame();
</script>
</body>
</html>
index.html
style.css
index.js
md
README.md
index.html