|
|
<!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 {
font-family: 'Arial', sans-serif;
display: flex;
flex-direction: column;
align-items: center;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
margin: 0;
padding: 20px;
}
#game-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
#game-board {
display: grid;
grid-template-columns: repeat(20, 20px);
grid-template-rows: repeat(20, 20px);
gap: 1px;
background-color: #333;
border: 3px solid #444;
border-radius: 5px;
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}
.cell {
width: 20px;
height: 20px;
background-color: #444;
}
.snake {
background-color: #4CAF50;
border-radius: 2px;
}
.food {
background-color: #f44336;
border-radius: 50%;
}
#score-panel {
display: flex;
justify-content: space-between;
width: 100%;
max-width: 400px;
background-color: white;
padding: 15px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
#controls {
display: flex;
gap: 10px;
}
button {
padding: 8px 15px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #45a049;
}
#game-over {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0,0,0,0.8);
color: white;
padding: 20px;
border-radius: 8px;
text-align: center;
display: none;
}
</style>
</head>
<body>
<div id="game-container">
<h1>贪吃蛇游戏</h1>
<div id="score-panel">
<div>得分: <span id="score">0</span></div>
<div>最高分: <span id="high-score">0</span></div>
<div id="controls">
<button id="start-btn">开始游戏</button>
<button id="pause-btn">暂停</button>
</div>
</div>
<div id="game-board"></div>
</div>
<div id="game-over">
<h2>游戏结束!</h2>
<p>你的得分: <span id="final-score">0</span></p>
<button id="restart-btn">重新开始</button>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const GRID_SIZE = 20;
const CELL_SIZE = 20;
const board = document.getElementById('game-board');
const scoreDisplay = document.getElementById('score');
const highScoreDisplay = document.getElementById('high-score');
const startBtn = document.getElementById('start-btn');
const pauseBtn = document.getElementById('pause-btn');
const restartBtn = document.getElementById('restart-btn');
const gameOverDisplay = document.getElementById('game-over');
const finalScoreDisplay = document.getElementById('final-score');
let snake = [{x: 10, y: 10}];
let food = generateFood();
let direction = 'RIGHT';
let nextDirection = 'RIGHT';
let gameInterval;
let speed = 150;
let score = 0;
let highScore = localStorage.getItem('snakeHighScore') || 0;
let isPaused = false;
let isGameRunning = false;
highScoreDisplay.textContent = highScore;
function initBoard() {
board.innerHTML = '';
for (let i = 0; i < GRID_SIZE * GRID_SIZE; i++) {
const cell = document.createElement('div');
cell.classList.add('cell');
board.appendChild(cell);
}
}
function generateFood() {
let newFood;
do {
newFood = {
x: Math.floor(Math.random() * GRID_SIZE),
y: Math.floor(Math.random() * GRID_SIZE)
};
} while (snake.some(segment => segment.x === newFood.x && segment.y === newFood.y));
return newFood;
}
function draw() {
const cells = document.querySelectorAll('.cell');
cells.forEach(cell => {
cell.classList.remove('snake', 'food');
});
snake.forEach(segment => {
const index = segment.y * GRID_SIZE + segment.x;
if (index >= 0 && index < cells.length) {
cells[index].classList.add('snake');
}
});
const foodIndex = food.y * GRID_SIZE + food.x;
if (foodIndex >= 0 && foodIndex < cells.length) {
cells[foodIndex].classList.add('food');
}
}
function update() {
if (isPaused) return;
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 (
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;
scoreDisplay.textContent = score;
food = generateFood();
// 每得100分加速
if (score % 100 === 0 && speed > 50) {
speed -= 10;
clearInterval(gameInterval);
gameInterval = setInterval(update, speed);
}
} else {
snake.pop();
}
draw();
}
function startGame() {
if (isGameRunning) return;
initBoard();
snake = [{x: 10, y: 10}];
food = generateFood();
direction = 'RIGHT';
nextDirection = 'RIGHT';
score = 0;
scoreDisplay.textContent = score;
speed = 150;
isPaused = false;
isGameRunning = true;
gameOverDisplay.style.display = 'none';
draw();
gameInterval = setInterval(update, speed);
}
function togglePause() {
isPaused = !isPaused;
pauseBtn.textContent = isPaused ? '继续' : '暂停';
}
function gameOver() {
clearInterval(gameInterval);
isGameRunning = false;
if (score > highScore) {
highScore = score;
localStorage.setItem('snakeHighScore', highScore);
highScoreDisplay.textContent = highScore;
}
finalScoreDisplay.textContent = score;
gameOverDisplay.style.display = 'block';
}
startBtn.addEventListener('click', startGame);
pauseBtn.addEventListener('click', togglePause);
restartBtn.addEventListener('click', startGame);
document.addEventListener('keydown', e => {
if (!isGameRunning) return;
switch (e.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;
case ' ':
togglePause();
break;
}
});
initBoard();
});
</script>
</body>
</html>
|
|
|