<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>贪吃蛇游戏</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
background-color: #f0f0f0;
margin: 0;
padding: 20px;
}
h1 {
color: #333;
margin-bottom: 10px;
}
.game-container {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20px;
}
.controls {
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 20px;
}
.speed-control {
display: flex;
align-items: center;
gap: 10px;
}
#game-canvas {
border: 2px solid #333;
background-color: #fff;
}
button {
padding: 8px 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #45a049;
}
.score-display {
font-size: 20px;
margin-top: 10px;
font-weight: bold;
}
.instructions {
margin-top: 20px;
background-color: #e9e9e9;
padding: 15px;
border-radius: 5px;
max-width: 500px;
text-align: center;
}
</style>
</head>
<body>
<h1>贪吃蛇游戏</h1>
<div>
<div>
<button id="start-btn">开始游戏</button>
<button id="pause-btn">暂停</button>
<button id="restart-btn">重新开始</button>
<div>
<label for="speed-slider">速度:</label>
<input type="range" id="speed-slider" min="1" max="20" value="10">
<span id="speed-value">10</span>
</div>
</div>
<canvas id="game-canvas" width="400" height="400"></canvas>
<div>
得分: <span id="score">0</span>
</div>
</div>
<div>
<h3>操作说明</h3>
<p>使用键盘方向键 (↑ ↓ ← →) 或 WASD 控制蛇的移动方向</p>
<p>点击"开始游戏"开始,点击"暂停"暂停游戏</p>
<p>滑动滑块调整游戏速度</p>
</div>
<script>
// 获取DOM元素
const canvas = document.getElementById('game-canvas');
const ctx = canvas.getContext('2d');
const startBtn = document.getElementById('start-btn');
const pauseBtn = document.getElementById('pause-btn');
const restartBtn = document.getElementById('restart-btn');
const speedSlider = document.getElementById('speed-slider');
const speedValue = document.getElementById('speed-value');
const scoreDisplay = document.getElementById('score');
// 游戏参数
const gridSize = 20;
const gridWidth = canvas.width / gridSize;
const gridHeight = canvas.height / gridSize;
// 游戏状态
let snake = [];
let food = {};
let direction = 'right';
let nextDirection = 'right';
let gameSpeed = 10;
let gameInterval;
let score = 0;
let isPaused = false;
let isGameOver = false;
// 初始化游戏
function initGame() {
// 初始化蛇
snake = [
{x: 5, y: 10},
{x: 4, y: 10},
{x: 3, y: 10}
];
// 初始化食物
generateFood();
// 重置方向和分数
direction = 'right';
nextDirection = 'right';
score = 0;
scoreDisplay.textContent = score;
isGameOver = false;
// 绘制游戏
drawGame();
}
// 生成食物
function generateFood() {
// 随机生成食物位置
food = {
x: Math.floor(Math.random() * gridWidth),
y: Math.floor(Math.random() * gridHeight)
};
// 确保食物不会出现在蛇身上
for (let segment of snake) {
if (segment.x === food.x && segment.y === food.y) {
return generateFood();
}
}
}
// 绘制游戏
function drawGame() {
// 清空画布
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制蛇
for (let i = 0; i < snake.length; i++) {
const segment = snake[i];
// 蛇头用不同颜色
if (i === 0) {
ctx.fillStyle = '#4CAF50';
} else {
ctx.fillStyle = '#8BC34A';
}
ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
// 绘制边框
ctx.strokeStyle = '#fff';
ctx.strokeRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
}
// 绘制食物
ctx.fillStyle = '#FF5722';
ctx.beginPath();
const centerX = food.x * gridSize + gridSize / 2;
const centerY = food.y * gridSize + gridSize / 2;
const radius = gridSize / 2;
ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
ctx.fill();
}
// 更新游戏状态
function updateGame() {
if (isPaused || isGameOver) return;
// 更新方向
direction = nextDirection;
// 获取蛇头
const head = {x: snake[0].x, y: snake[0].y};
// 根据方向移动蛇头
switch (direction) {
case 'up':
head.y -= 1;
break;
case 'down':
head.y += 1;
break;
case 'left':
head.x -= 1;
break;
case 'right':
head.x += 1;
break;
}
// 检查游戏结束条件
// 撞墙
if (head.x < 0 || head.x >= gridWidth || head.y < 0 || head.y >= gridHeight) {
gameOver();
return;
}
// 撞到自己
for (let segment of snake) {
if (segment.x === head.x && segment.y === head.y) {
gameOver();
return;
}
}
// 移动蛇
snake.unshift(head);
// 检查是否吃到食物
if (head.x === food.x && head.y === food.y) {
// 增加分数
score += 1;
scoreDisplay.textContent = score;
// 生成新食物
generateFood();
} else {
// 如果没有吃到食物,移除尾部
snake.pop();
}
// 绘制游戏
drawGame();
}
// 游戏结束
function gameOver() {
isGameOver = true;
clearInterval(gameInterval);
alert(`游戏结束! 你的得分是: ${score}`);
}
// 开始游戏
function startGame() {
if (!gameInterval) {
initGame();
gameInterval = setInterval(updateGame, 1000 / gameSpeed);
isPaused = false;
} else if (isPaused) {
isPaused = false;
}
}
// 暂停游戏
function pauseGame() {
isPaused = true;
}
// 重新开始游戏
function restartGame() {
clearInterval(gameInterval);
gameInterval = null;
startGame();
}
// 更新速度
function updateSpeed() {
gameSpeed = speedSlider.value;
speedValue.textContent = gameSpeed;
if (gameInterval) {
clearInterval(gameInterval);
gameInterval = setInterval(updateGame, 1000 / gameSpeed);
}
}
// 事件监听
startBtn.addEventListener('click', startGame);
pauseBtn.addEventListener('click', pauseGame);
restartBtn.addEventListener('click', restartGame);
speedSlider.addEventListener('input', updateSpeed);
// 键盘控制
document.addEventListener('keydown', function(e) {
// 防止按键重复触发
if (e.repeat) return;
switch(e.key) {
case 'ArrowUp':
case 'w':
case 'W':
if (direction !== 'down') nextDirection = 'up';
break;
case 'ArrowDown':
case 's':
case 'S':
if (direction !== 'up') nextDirection = 'down';
break;
case 'ArrowLeft':
case 'a':
case 'A':
if (direction !== 'right') nextDirection = 'left';
break;
case 'ArrowRight':
case 'd':
case 'D':
if (direction !== 'left') nextDirection = 'right';
break;
case ' ':
// 空格键暂停/继续
if (isPaused) {
startGame();
} else {
pauseGame();
}
break;
}
});
// 初始化显示
initGame();
</script>
</body>
</html>