|
|
const canvas = document.getElementById('game-board');
const ctx = canvas.getContext('2d');
const scoreElement = document.getElementById('score');
const highScoreElement = document.getElementById('high-score');
const finalScoreElement = document.getElementById('final-score');
const gameOverElement = document.getElementById('game-over');
const startBtn = document.getElementById('start-btn');
const pauseBtn = document.getElementById('pause-btn');
const restartBtn = document.getElementById('restart-btn');
const gridSize = 20;
const tileCount = canvas.width / gridSize;
let snake = [{x: 200, y: 200}];
let food = {x: 15, y: 15};
let direction = {x: 0, y: 0};
let lastDirection = {x: 0, y: 0};
let score = 0;
let highScore = localStorage.getItem('highScore') || 0;
let gameSpeed = 150;
let gameRunning = false;
let gamePaused = false;
let gameLoop;
highScoreElement.textContent = highScore;
function drawGame() {
// 清空画布
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制蛇
snake.forEach((segment, index) => {
ctx.fillStyle = index === 0 ? '#4CAF50' : '#8BC34A';
ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize - 2, gridSize - 2);
});
// 绘制食物
ctx.fillStyle = '#FF5722';
ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize - 2, gridSize - 2);
}
function moveSnake() {
const head = {x: snake[0].x + direction.x, y: snake[0].y + direction.y};
lastDirection = {...direction};
// 检查是否撞墙
if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) {
gameOver();
return;
}
// 检查是否撞到自己
if (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();
// 随着分数增加加快游戏速度
if (score % 50 === 0 && gameSpeed > 50) {
gameSpeed -= 10;
clearInterval(gameLoop);
gameLoop = setInterval(updateGame, gameSpeed);
}
} else {
snake.pop();
}
}
function generateFood() {
let newFoodPosition;
do {
newFoodPosition = {
x: Math.floor(Math.random() * tileCount),
y: Math.floor(Math.random() * tileCount)
};
} while (snake.some(segment =>
segment.x === newFoodPosition.x && segment.y === newFoodPosition.y
));
food = newFoodPosition;
}
function updateGame() {
if (gamePaused) return;
moveSnake();
drawGame();
}
function gameOver() {
clearInterval(gameLoop);
gameRunning = false;
gamePaused = false;
finalScoreElement.textContent = score;
gameOverElement.style.display = 'block';
if (score > highScore) {
highScore = score;
highScoreElement.textContent = highScore;
localStorage.setItem('highScore', highScore);
}
}
function startGame() {
if (gameRunning) return;
snake = [{x: 10, y: 10}];
direction = {x: 0, y: 0};
lastDirection = {x: 0, y: 0};
score = 0;
scoreElement.textContent = score;
gameSpeed = 150;
gameOverElement.style.display = 'none';
generateFood();
gameRunning = true;
gamePaused = false;
gameLoop = setInterval(updateGame, gameSpeed);
}
function togglePause() {
if (!gameRunning) return;
gamePaused = !gamePaused;
pauseBtn.textContent = gamePaused ? '继续' : '暂停';
}
// 事件监听
document.addEventListener('keydown', e => {
if (!gameRunning || gamePaused) return;
switch(e.key) {
case 'ArrowUp':
case 'w':
case 'W':
if (lastDirection.y === 0) direction = {x: 0, y: -1};
break;
case 'ArrowDown':
case 's':
case 'S':
if (lastDirection.y === 0) direction = {x: 0, y: 1};
break;
case 'ArrowLeft':
case 'a':
case 'A':
if (lastDirection.x === 0) direction = {x: -1, y: 0};
break;
case 'ArrowRight':
case 'd':
case 'D':
if (lastDirection.x === 0) direction = {x: 1, y: 0};
break;
}
});
startBtn.addEventListener('click', startGame);
pauseBtn.addEventListener('click', togglePause);
restartBtn.addEventListener('click', startGame);
// 初始绘制
drawGame(); |
|