<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>贪吃蛇游戏</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
#gameContainer {
position: relative;
}
#gameCanvas {
border: 2px solid #333;
background-color: #fff;
}
.button {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 15px 30px;
font-size: 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
display: none;
}
#score {
position: absolute;
top: 10px;
right: 10px;
font-size: 24px;
font-weight: bold;
}
</style>
</head>
<body>
<div id="gameContainer">
<canvas id="gameCanvas" width="600" height="600"></canvas>
<div id="score">0</div>
<button id="startBtn" class="button">开始游戏</button>
<button id="restartBtn" class="button">重新开始</button>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const startBtn = document.getElementById('startBtn');
const restartBtn = document.getElementById('restartBtn');
const scoreElement = document.getElementById('score');
const GRID_SIZE = 50;
const CELL_SIZE = canvas.width / GRID_SIZE;
let snake = [];
let food = {};
let direction = 'right';
let gameLoop;
let score = 0;
let gameStarted = false;
function initGame() {
snake = [{x: 25, y: 25}];
direction = 'right';
score = 0;
scoreElement.textContent = score;
generateFood();
draw();
}
function generateFood() {
food = {
x: Math.floor(Math.random() * GRID_SIZE),
y: Math.floor(Math.random() * GRID_SIZE)
};
while(snake.some(segment => segment.x === food.x && segment.y === food.y)) {
food = {
x: Math.floor(Math.random() * GRID_SIZE),
y: Math.floor(Math.random() * GRID_SIZE)
};
}
}
function drawGrid() {
ctx.strokeStyle = '#ddd';
for(let i = 0; i <= GRID_SIZE; i++) {
ctx.beginPath();
ctx.moveTo(i * CELL_SIZE, 0);
ctx.lineTo(i * CELL_SIZE, canvas.height);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, i * CELL_SIZE);
ctx.lineTo(canvas.width, i * CELL_SIZE);
ctx.stroke();
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawGrid();
snake.forEach((segment, index) => {
ctx.fillStyle = index === 0 ? '#4CAF50' : '#8BC34A';
ctx.fillRect(segment.x * CELL_SIZE, segment.y * CELL_SIZE, CELL_SIZE - 1, CELL_SIZE - 1);
});
ctx.fillStyle = '#FF5722';
ctx.fillRect(food.x * CELL_SIZE, food.y * CELL_SIZE, CELL_SIZE - 1, CELL_SIZE - 1);
}
function move() {
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(head.x < 0 || head.x >= GRID_SIZE || head.y < 0 || head.y >= GRID_SIZE ||
snake.some(segment => segment.x === head.x && segment.y === head.y)) {
gameOver();
return;
}
snake.unshift(head);
if(head.x === food.x && head.y === food.y) {
score += 10;
scoreElement.textContent = score;
generateFood();
} else {
snake.pop();
}
draw();
}
function gameOver() {
clearInterval(gameLoop);
gameStarted = false;
restartBtn.style.display = 'block';
restartBtn.textContent = `重新开始 (得分: ${score})`;
}
startBtn.addEventListener('click', () => {
startBtn.style.display = 'none';
restartBtn.style.display = 'none';
gameStarted = true;
initGame();
gameLoop = setInterval(move, 200); // 每秒5格
});
restartBtn.addEventListener('click', () => {
restartBtn.style.display = 'none';
gameStarted = true;
initGame();
gameLoop = setInterval(move, 200);
});
document.addEventListener('keydown', (e) => {
if(!gameStarted) return;
const key = e.key;
const oldDirection = direction;
if(key === 'ArrowUp' && oldDirection !== 'down') direction = 'up';
if(key === 'ArrowDown' && oldDirection !== 'up') direction = 'down';
if(key === 'ArrowLeft' && oldDirection !== 'right') direction = 'left';
if(key === 'ArrowRight' && oldDirection !== 'left') direction = 'right';
});
startBtn.style.display = 'block';