|
|
好的,让我们来一步一步实现这些功能,最终形成一个完整的贪吃蛇游戏。
### 增加边界穿越
我们首先实现边界穿越功能。蛇在画布边缘移动时,不是撞墙结束游戏,而是从对面的边界出来。
### 实现障碍物
在游戏中添加一些障碍物,当蛇撞到障碍物时,游戏结束。
### 增加积分排行榜
保存玩家的得分,并展示排行榜。
### 完整游戏代码
#### HTML结构
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>贪吃蛇游戏</title>
- <style>
- body {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- height: 100vh;
- margin: 0;
- font-family: Arial, sans-serif;
- background-color: #f0f0f0;
- }
- #gameCanvas {
- border: 2px solid #000;
- background-color: #fff;
- }
- .controls {
- margin-bottom: 20px;
- }
- button {
- padding: 10px 20px;
- font-size: 16px;
- margin: 5px;
- cursor: pointer;
- }
- </style>
- </head>
- <body>
- <div class="controls">
- <button id="startButton">开始游戏</button>
- <button id="pauseButton" style="display: none;">暂停</button>
- 难度:
- <select id="difficulty">
- <option value="easy">简单</option>
- <option value="normal" selected>普通</option>
- <option value="hard">困难</option>
- </select>
- </div>
- 最高得分: <span id="highScore">0</span><br>
- 时间: <span id="time">0</span> 秒<br>
- <canvas id="gameCanvas" width="400" height="400" style="display: none;"></canvas>
- <!-- 添加音效资源 -->
- <audio id="eatSound" src="eat.mp3"></audio>
- <audio id="crashSound" src="crash.mp3"></audio>
- <script src="snake.js"></script>
- </body>
- </html>
复制代码
#### JavaScript代码(snake.js)
- const canvas = document.getElementById('gameCanvas');
- const context = canvas.getContext('2d');
- const box = 20;
- let snake, food, direction, score, game, gameInterval, timeCounter;
- let highScore = 0;
- let timeElapsed = 0;
- const difficultySettings = {
- easy: 150,
- normal: 100,
- hard: 50
- };
- const obstacles = []; // 存储障碍物的位置
- document.getElementById('startButton').addEventListener('click', startGame);
- document.getElementById('pauseButton').addEventListener('click', pauseGame);
- function startGame() {
- document.getElementById('startButton').style.display = 'none';
- document.getElementById('pauseButton').style.display = 'block';
- document.getElementById('gameCanvas').style.display = 'block';
- resetGame();
- const difficulty = document.getElementById('difficulty').value;
- gameInterval = difficultySettings[difficulty];
- game = setInterval(drawGame, gameInterval);
- timeCounter = setInterval(updateTime, 1000); // 每秒更新一次时间
- }
- function pauseGame() {
- if (game) {
- clearInterval(game);
- clearInterval(timeCounter);
- game = null;
- timeCounter = null;
- document.getElementById('pauseButton').innerText = '继续';
- } else {
- game = setInterval(drawGame, gameInterval);
- timeCounter = setInterval(updateTime, 1000); // 每秒更新一次时间
- document.getElementById('pauseButton').innerText = '暂停';
- }
- }
- function resetGame() {
- snake = [{ x: 9 * box, y: 10 * box }];
- food = {
- x: Math.floor(Math.random() * 19 + 1) * box,
- y: Math.floor(Math.random() * 19 + 1) * box
- };
- score = 0;
- direction = undefined;
- timeElapsed = 0;
- document.getElementById('time').innerText = timeElapsed;
- generateObstacles(); // 生成障碍物
- }
- document.addEventListener('keydown', changeDirection);
- function changeDirection(event) {
- const keyPressed = event.keyCode;
- if (keyPressed === 37 && direction !== 'RIGHT') direction = 'LEFT';
- if (keyPressed === 38 && direction !== 'DOWN') direction = 'UP';
- if (keyPressed === 39 && direction !== 'LEFT') direction = 'RIGHT';
- if (keyPressed === 40 && direction !== 'UP') direction = 'DOWN';
- }
- function drawGame() {
- context.clearRect(0, 0, canvas.width, canvas.height);
- for (let i = 0; i < snake.length; i++) {
- context.fillStyle = i === 0 ? 'green' : 'black';
- context.fillRect(snake[i].x, snake[i].y, box, box);
- }
-
- context.fillStyle = 'red';
- context.fillRect(food.x, food.y, box, box);
-
- drawObstacles();
- let snakeX = snake[0].x;
- let snakeY = snake[0].y;
- if (direction === 'LEFT') snakeX -= box;
- if (direction === 'UP') snakeY -= box;
- if (direction === 'RIGHT') snakeX += box;
- if (direction === 'DOWN') snakeY += box;
- if (snakeX === food.x && snakeY === food.y) {
- score++;
- updateHighScore();
- document.getElementById('eatSound').play(); // 播放吃声音
- food = {
- x: Math.floor(Math.random() * 19 + 1) * box,
- y: Math.floor(Math.random() * 19 + 1) * box
- };
- } else {
- snake.pop();
- }
- let newHead = { x: snakeX, y: snakeY };
- if (snakeX < 0) snakeX = canvas.width - box;
- if (snakeY < 0) snakeY = canvas.height - box;
- if (snakeX >= canvas.width) snakeX = 0;
- if (snakeY >= canvas.height) snakeY = 0;
- if (collision(newHead, snake) || collision(newHead, obstacles)) {
- clearInterval(game);
- clearInterval(timeCounter);
- document.getElementById('crashSound').play(); // 播放撞墙声音
- alert('游戏结束');
- return;
- }
- snake.unshift(newHead);
- context.fillStyle = 'black';
- context.font = '20px Arial';
- context.fillText('得分: ' + score, 5, canvas.height - 5);
- }
- function collision(head, array) {
- for (let i = 0; i < array.length; i++) {
- if (head.x === array[i].x && head.y === array[i].y) {
- return true;
- }
- }
- return false;
- }
- function updateHighScore() {
- if (score > highScore) {
- highScore = score;
- document.getElementById('highScore').innerText = highScore;
- }
- }
- function updateTime() {
- timeElapsed++;
- document.getElementById('time').innerText = timeElapsed;
- }
- function generateObstacles() {
- obstacles.length = 0;
- // 生成 5 个随机障碍物
- for (let i = 0; i < 5; i++) {
- let obstacle = {
- x: Math.floor(Math.random() * 19 + 1) * box,
- y: Math.floor(Math.random() * 19 + 1) * box
- };
- obstacles.push(obstacle);
- }
- }
- function drawObstacles() {
- context.fillStyle = 'grey';
- for (let i = 0; i < obstacles.length; i++) {
- context.fillRect(obstacles[i].x, obstacles[i].y, box, box);
- }
- }
复制代码
### 总结
通过以上步骤,我们逐步实现了以下功能:
1. 边界穿越:蛇可以从一个边界穿越到另一个边界。
2. 障碍物:在游戏中随机生成障碍物,蛇撞到障碍物即游戏结束。
3. 积分和计时器:记录玩家得分和游戏时间。
4. 音效:在吃到食物或撞墙时播放声音。
5. 难度设置和暂停功能:玩家可以选择难度并在游戏中暂停。
你可以根据自己的需求继续扩展,比如设计多个地图、增加皮肤、更丰富的音效等。如果有任何问题,请随时告诉我!希望你享受编程和游戏的乐趣! |
|