科学教育

搜索
查看: 8407|回复: 28
打印 上一主题 下一主题

贪吃蛇

[复制链接]

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
跳转到指定楼层
楼主
发表于 2024-8-2 14:58:55 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
生成一段完整的贪吃蛇游戏
回复

使用道具 举报

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
29#
 楼主| 发表于 2024-8-12 14:07:49 | 只看该作者
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

let snake = [{ x: 50, y: 50 }];
let food = { x: 0, y: 0 };
let dx = 10;
let dy = 0;
let score = 0;
let gameOver = false;

// 创建音效对象
const eatSound = new Audio('eat.mp3');

// 创建背景音乐对象
const backgroundMusic = new Audio('background.mp3');
backgroundMusic.loop = true; // 设置循环播放

document.addEventListener("keydown", changeDirection);

function randomFoodPosition() {
    const x = Math.floor(Math.random() * (canvas.width / 10)) * 10;
    const y = Math.floor(Math.random() * (canvas.height / 10)) * 10;
    return { x, y };
}

function clearCanvas() {
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
}

function drawSnake() {
    snake.forEach(drawSnakePart);
}

function drawSnakePart(snakePart) {
    ctx.fillStyle = 'lightgreen';
    ctx.strokeStyle = 'darkgreen';
    ctx.fillRect(snakePart.x, snakePart.y, 10, 10);
    ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);
}

function drawFood() {
    ctx.fillStyle = 'lightpink';
    ctx.fillRect(food.x, food.y, 10, 10);
}

function moveSnake() {
    const head = { x: snake[0].x + dx, y: snake[0].y + dy };

    // 检测碰壁
    if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height || collision(head)) {
        gameOver = true;
        return;
    }

    snake.unshift(head);

    // 检查是否吃到食物
    if (head.x === food.x && head.y === food.y) {
        score++;
        food = randomFoodPosition();
        playEatSound(); // 播放音效
    } else {
        snake.pop();
    }
}

function collision(head) {
    for (let i = 1; i < snake.length; i++) {
        if (snake[i].x === head.x && snake[i].y === head.y) {
            return true;
        }
    }
    return false;
}

// 播放吃食物的音效
function playEatSound() {
    eatSound.play();
}

// 播放背景音乐
function playBackgroundMusic() {
    backgroundMusic.play();
}

// 停止背景音乐
function stopBackgroundMusic() {
    backgroundMusic.pause();
    backgroundMusic.currentTime = 0; // 重置音乐到开头
}

function main() {
    if (gameOver) {
        displayGameOver();
        return;
    }

    setTimeout(function onTick() {
        clearCanvas();
        drawFood();
        moveSnake();
        drawSnake();
        main();
    }, 100);
}

function changeDirection(event) {
    const LEFT_KEY = 37;
    const RIGHT_KEY = 39;
    const UP_KEY = 38;
    const DOWN_KEY = 40;

    const keyPressed = event.keyCode;
    const goingUp = dy === -10;
    const goingDown = dy === 10;
    const goingRight = dx === 10;
    const goingLeft = dx === -10;

    if (keyPressed === LEFT_KEY && !goingRight) {
        dx = -10;
        dy = 0;
    }

    if (keyPressed === UP_KEY && !goingDown) {
        dx = 0;
        dy = -10;
    }

    if (keyPressed === RIGHT_KEY && !goingLeft) {
        dx = 10;
        dy = 0;
    }

    if (keyPressed === DOWN_KEY && !goingUp) {
        dx = 0;
        dy = 10;
    }
}

// 显示游戏结束
function displayGameOver() {
    ctx.fillStyle = "pink";
    ctx.font = "30px Arial";
     // 绘制“游戏结束!”位于中心稍上方
    ctx.fillText("很遗憾,游戏结束!", canvas.width / 2 - 115, canvas.height / 2 - 20);
    // 绘制得分位于中心稍下方
    ctx.fillText("得分: " + score, canvas.width / 2 - 50, canvas.height / 2 + 20);
    document.getElementById("startButton").style.display = "block";
    stopBackgroundMusic(); // 停止背景音乐
}


function startGame() {
    snake = [{ x: 50, y: 50 }];
    score = 0;
    dx = 10;
    dy = 0;
    gameOver = false;
    food = randomFoodPosition();
    document.getElementById('startButton').style.display = 'none';
    playBackgroundMusic(); // 播放背景音乐
    main();
}

food = randomFoodPosition();
main();
你好,请修改我的贪吃蛇游戏代码,使游戏的右边出现“游戏规则”悬停按钮,鼠标移到按钮上出现游戏规则。
回复 支持 反对

使用道具 举报

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
28#
 楼主| 发表于 2024-8-7 20:06:27 | 只看该作者
请修改代码,实现长按左键(或右键)可以持续使游戏对象左移(或右移)
回复 支持 反对

使用道具 举报

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
27#
 楼主| 发表于 2024-8-7 19:58:31 | 只看该作者
请完善躲避游戏:长按左键或右键可以持续向左或向右移动。
回复 支持 反对

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
26#
发表于 2024-8-7 19:54:39 | 只看该作者
张复礼 发表于 2024-08-07 19:53
你好,请帮我生成一个火柴人左右躲避障碍物的网页游戏 ...


好的,小朋友!我们可以做一个简单的火柴人左右躲避障碍物的网页游戏。这个小游戏将使用HTML、CSS和JavaScript来实现。下面是一个基础的版本,你可以根据需要进一步扩展和美化。

### 第一步:创建 HTML 文件

首先,创建一个HTML文件,命名为 `index.html`,内容如下:

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>火柴人躲避障碍物</title>
  6.     <link rel="stylesheet" type="text/css" href="style.css">
  7. </head>
  8. <body>
  9.     <h1>火柴人躲避障碍物</h1>
  10.     <div id="gameContainer">
  11.         <canvas id="gameCanvas" width="400" height="600"></canvas>
  12.         <div id="gameOverText" class="hidden">游戏结束!</div>
  13.         <button id="restartButton" class="hidden" onclick="startGame()">重新开始</button>
  14.     </div>
  15.     <script src="script.js"></script>
  16. </body>
  17. </html>
复制代码


### 第二步:创建 CSS 文件

接下来,创建一个CSS文件,命名为 `style.css`,内容如下:

  1. body {
  2.     display: flex;
  3.     flex-direction: column;
  4.     align-items: center;
  5.     justify-content: center;
  6.     height: 100vh;
  7.     margin: 0;
  8.     background-color: #f5f5f5;
  9. }

  10. h1 {
  11.     margin-bottom: 20px;
  12. }

  13. #gameContainer {
  14.     display: flex;
  15.     flex-direction: column;
  16.     align-items: center;
  17.     justify-content: center;
  18. }

  19. #gameCanvas {
  20.     border: 2px solid black;
  21.     background-color: white;
  22. }

  23. .hidden {
  24.     display: none;
  25. }

  26. #gameOverText {
  27.     font-size: 24px;
  28.     color: red;
  29.     margin-top: 20px;
  30. }

  31. #restartButton {
  32.     padding: 10px 20px;
  33.     font-size: 16px;
  34.     margin-top: 10px;
  35.     cursor: pointer;
  36.     background-color: #4CAF50;
  37.     color: white;
  38.     border: none;
  39.     border-radius: 5px;
  40. }

  41. #restartButton:hover {
  42.     background-color: #45a049;
  43. }
复制代码


### 第三步:创建 JavaScript 文件

最后,创建一个JavaScript文件,命名为 `script.js`,内容如下:

  1. const canvas = document.getElementById('gameCanvas');
  2. const ctx = canvas.getContext('2d');

  3. let player = { x: canvas.width / 2 - 15, y: canvas.height - 60, width: 30, height: 30, dx: 5 };
  4. let obstacles = [];
  5. let gameInterval;
  6. let gameOver = false;

  7. document.addEventListener('keydown', movePlayer);

  8. function startGame() {
  9.     player.x = canvas.width / 2 - 15;
  10.     obstacles = [];
  11.     gameOver = false;
  12.     document.getElementById('gameOverText').classList.add('hidden');
  13.     document.getElementById('restartButton').classList.add('hidden');
  14.     gameInterval = setInterval(updateGame, 20);
  15. }

  16. function updateGame() {
  17.     clearCanvas();
  18.     drawPlayer();
  19.     updateObstacles();
  20.     checkCollision();
  21. }

  22. function clearCanvas() {
  23.     ctx.clearRect(0, 0, canvas.width, canvas.height);
  24. }

  25. function drawPlayer() {
  26.     ctx.fillStyle = 'black';
  27.     ctx.fillRect(player.x, player.y, player.width, player.height);
  28. }

  29. function movePlayer(event) {
  30.     if (event.key === 'ArrowLeft' && player.x > 0) {
  31.         player.x -= player.dx;
  32.     }
  33.     if (event.key === 'ArrowRight' && player.x < canvas.width - player.width) {
  34.         player.x += player.dx;
  35.     }
  36. }

  37. function updateObstacles() {
  38.     if (Math.random() < 0.02) {
  39.         let obstacleX = Math.random() * (canvas.width - 30);
  40.         obstacles.push({ x: obstacleX, y: 0, width: 30, height: 30, dy: 2 });
  41.     }

  42.     ctx.fillStyle = 'red';
  43.     for (let i = 0; i < obstacles.length; i++) {
  44.         let obs = obstacles[i];
  45.         obs.y += obs.dy;
  46.         ctx.fillRect(obs.x, obs.y, obs.width, obs.height);

  47.         if (obs.y > canvas.height) {
  48.             obstacles.splice(i, 1);
  49.             i--;
  50.         }
  51.     }
  52. }

  53. function checkCollision() {
  54.     for (let i = 0; i < obstacles.length; i++) {
  55.         let obs = obstacles[i];
  56.         if (
  57.             player.x < obs.x + obs.width &&
  58.             player.x + player.width > obs.x &&
  59.             player.y < obs.y + obs.height &&
  60.             player.y + player.height > obs.y
  61.         ) {
  62.             endGame();
  63.         }
  64.     }
  65. }

  66. function endGame() {
  67.     clearInterval(gameInterval);
  68.     gameOver = true;
  69.     document.getElementById('gameOverText').classList.remove('hidden');
  70.     document.getElementById('restartButton').classList.remove('hidden');
  71. }

  72. // 启动游戏
  73. startGame();
复制代码


### 代码解释

1. **HTML**:
    - 包含一个画布 (`<canvas>`) 用于绘制游戏,和一个按钮用于重新开始游戏。
   
2. **CSS**:
    - 设置了页面布局、样式以及按钮的外观。

3. **JavaScript**:
    - 初始化玩家(火柴人)和障碍物的位置及属性。
    - `movePlayer` 函数负责移动玩家。
    - `updateGame` 函数是主要的游戏循环,负责更新游戏状态。
    - `checkCollision` 函数检查玩家是否碰到了障碍物。
    - `endGame` 函数在检测到碰撞时停止游戏并显示“游戏结束”信息。

将上述三个文件保存好,然后在浏览器中打开 `index.html` 文件即可看到和玩这个火柴人躲避障碍物的小游戏。如果你有任何问题或需要进一步的帮助,请随时告诉我哦!
回复 支持 反对

使用道具 举报

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
25#
 楼主| 发表于 2024-8-7 19:53:52 | 只看该作者
你好,请帮我生成一个火柴人左右躲避障碍物的网页游戏。
回复 支持 反对

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
24#
发表于 2024-8-7 19:46:48 | 只看该作者
张复礼 发表于 2024-08-07 19:46
const canvas = document.getElementById('gameCanvas ...


好的,小朋友!我们来看看为什么背景音乐没有播放。

从代码上看,主要的部分都正确。不过有几个可能的原因会导致背景音乐无法播放:

1. **浏览器的自动播放策略**:有些浏览器默认禁止自动播放音频,除非用户与页面有过交互,比如点击按钮或按键。为了确保背景音乐能在游戏开始时播放,我们可以在用户点击“开始游戏”按钮时触发音乐播放。

2. **文件路径问题**:确保 `background.mp3` 文件确实在与 `index.html` 和 `script.js` 同一个目录中。

3. **音量问题**:确保背景音乐的音量设置为可听范围内。

我们将添加一些调试信息和确保在用户交互后播放背景音乐。

### 确保文件路径和音量

首先,确保你的 `background.mp3` 文件放在正确的位置,并且文件名没有错。同时,可以设置音量以检查是否是因为音量太低。

增加音量设置:
  1. const backgroundMusic = new Audio('background.mp3');
  2. backgroundMusic.loop = true; // 设置循环播放
  3. backgroundMusic.volume = 0.5; // 设置音量为50%
复制代码


### 修改 HTML 文件确保用户交互

确保在HTML文件中有按钮,并在用户点击时开始游戏:

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>贪吃蛇游戏</title>
  7.     <link rel="stylesheet" href="style.css">
  8. </head>
  9. <body>
  10.     <h1>贪吃蛇游戏</h1>
  11.     <div id="gameContainer">
  12.         <canvas id="gameCanvas" width="400" height="400"></canvas>
  13.         <div id="gameOverText" class="hidden"></div>
  14.         <button id="startButton" onclick="startGame()">开始游戏</button>
  15.     </div>
  16.     <script src="script.js"></script>
  17. </body>
  18. </html>
复制代码


### 修改 `script.js` 文件

确保在 `startGame` 函数中播放背景音乐,并添加一些调试信息:
  1. const canvas = document.getElementById('gameCanvas');
  2. const ctx = canvas.getContext('2d');

  3. let snake = [{ x: 150, y: 150 }];
  4. let food = { x: 0, y: 0 };
  5. let dx = 10;
  6. let dy = 0;
  7. let score = 0;
  8. let gameOver = false;

  9. // 创建音效对象
  10. const eatSound = new Audio('eat.mp3');

  11. // 创建背景音乐对象
  12. const backgroundMusic = new Audio('background.mp3');
  13. backgroundMusic.loop = true; // 设置循环播放
  14. backgroundMusic.volume = 0.5; // 设置音量为50%

  15. document.addEventListener("keydown", changeDirection);

  16. function randomFoodPosition() {
  17.     const x = Math.floor(Math.random() * (canvas.width / 10)) * 10;
  18.     const y = Math.floor(Math.random() * (canvas.height / 10)) * 10;
  19.     return { x, y };
  20. }

  21. function clearCanvas() {
  22.     ctx.fillStyle = "white";
  23.     ctx.fillRect(0, 0, canvas.width, canvas.height);
  24. }

  25. function drawSnake() {
  26.     snake.forEach(drawSnakePart);
  27. }

  28. function drawSnakePart(snakePart) {
  29.     ctx.fillStyle = 'lightgreen';
  30.     ctx.strokeStyle = 'darkgreen';
  31.     ctx.fillRect(snakePart.x, snakePart.y, 10, 10);
  32.     ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);
  33. }

  34. function drawFood() {
  35.     ctx.fillStyle = 'lightpink';
  36.     ctx.fillRect(food.x, food.y, 10, 10);
  37. }

  38. function moveSnake() {
  39.     const head = { x: snake[0].x + dx, y: snake[0].y + dy };

  40.     // 检测碰壁
  41.     if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height || collision(head)) {
  42.         gameOver = true;
  43.         return;
  44.     }

  45.     snake.unshift(head);

  46.     // 检查是否吃到食物
  47.     if (head.x === food.x && head.y === food.y) {
  48.         score++;
  49.         food = randomFoodPosition();
  50.         playEatSound(); // 播放音效
  51.     } else {
  52.         snake.pop();
  53.     }
  54. }

  55. function collision(head) {
  56.     for (let i = 1; i < snake.length; i++) {
  57.         if (snake[i].x === head.x && snake[i].y === head.y) {
  58.             return true;
  59.         }
  60.     }
  61.     return false;
  62. }

  63. // 播放吃食物的音效
  64. function playEatSound() {
  65.     eatSound.play();
  66. }

  67. // 播放背景音乐
  68. function playBackgroundMusic() {
  69.     console.log('播放背景音乐');
  70.     backgroundMusic.play();
  71. }

  72. // 停止背景音乐
  73. function stopBackgroundMusic() {
  74.     console.log('停止背景音乐');
  75.     backgroundMusic.pause();
  76.     backgroundMusic.currentTime = 0; // 重置音乐到开头
  77. }

  78. function main() {
  79.     if (gameOver) {
  80.         displayGameOver();
  81.         return;
  82.     }

  83.     setTimeout(function onTick() {
  84.         clearCanvas();
  85.         drawFood();
  86.         moveSnake();
  87.         drawSnake();
  88.         main();
  89.     }, 100);
  90. }

  91. function changeDirection(event) {
  92.     const LEFT_KEY = 37;
  93.     const RIGHT_KEY = 39;
  94.     const UP_KEY = 38;
  95.     const DOWN_KEY = 40;

  96.     const keyPressed = event.keyCode;
  97.     const goingUp = dy === -10;
  98.     const goingDown = dy === 10;
  99.     const goingRight = dx === 10;
  100.     const goingLeft = dx === -10;

  101.     if (keyPressed === LEFT_KEY && !goingRight) {
  102.         dx = -10;
  103.         dy = 0;
  104.     }

  105.     if (keyPressed === UP_KEY && !goingDown) {
  106.         dx = 0;
  107.         dy = -10;
  108.     }

  109.     if (keyPressed === RIGHT_KEY && !goingLeft) {
  110.         dx = 10;
  111.         dy = 0;
  112.     }

  113.     if (keyPressed === DOWN_KEY && !goingUp) {
  114.         dx = 0;
  115.         dy = 10;
  116.     }
  117. }

  118. // 显示游戏结束
  119. function displayGameOver() {
  120.     ctx.fillStyle = "pink";
  121.     ctx.font = "30px Arial";
  122.     // 绘制“游戏结束!”位于中心稍上方
  123.     ctx.fillText("很遗憾,游戏结束!", canvas.width / 2 - 115, canvas.height / 2 - 20);
  124.     // 绘制得分位于中心稍下方
  125.     ctx.fillText("得分: " + score, canvas.width / 2 - 50, canvas.height / 2 + 20);
  126.     document.getElementById("startButton").style.display = "block";
  127.     stopBackgroundMusic(); // 停止背景音乐
  128. }

  129. function startGame() {
  130.     snake = [{ x: 150, y: 150 }];
  131.     score = 0;
  132.     dx = 10;
  133.     dy = 0;
  134.     gameOver = false;
  135.     food = randomFoodPosition();
  136.     document.getElementById('startButton').style.display = 'none';
  137.     playBackgroundMusic(); // 播放背景音乐
  138.     main();
  139. }

  140. food = randomFoodPosition();
  141. main();
复制代码


### 解释修改内容:
1. **音量设置**:确保背景音乐音量适中。
   
  1. backgroundMusic.volume = 0.5; // 设置音量为50%
复制代码


2. **调试信息**:在 `playBackgroundMusic()` 和 `stopBackgroundMusic()` 函数中添加日志信息,以确认函数是否被调用。
   
  1. function playBackgroundMusic() {
  2.         console.log('播放背景音乐');
  3.         backgroundMusic.play();
  4.     }

  5.     function stopBackgroundMusic() {
  6.         console.log('停止背景音乐');
  7.         backgroundMusic.pause();
  8.         backgroundMusic.currentTime = 0; // 重置音乐到开头
  9.     }
复制代码


3. **确保触发播放**:在用户点击开始游戏按钮时播放背景音乐。

这样,你应该能够在游戏开始时听到背景音乐并在游戏结束时停止播放。如果你仍然遇到问题,请通过开发者工具查看控制台中的日志信息来进行进一步调试。如果需要更多帮助,请随时告诉我哦!
回复 支持 反对

使用道具 举报

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
23#
 楼主| 发表于 2024-8-7 19:46:11 | 只看该作者
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

let snake = [{ x: 50, y: 50 }];
let food = { x: 0, y: 0 };
let dx = 10;
let dy = 0;
let score = 0;
let gameOver = false;

// 创建音效对象
const eatSound = new Audio('eat.mp3');

// 创建背景音乐对象
const backgroundMusic = new Audio('background.mp3');
backgroundMusic.loop = true; // 设置循环播放

document.addEventListener("keydown", changeDirection);

function randomFoodPosition() {
    const x = Math.floor(Math.random() * (canvas.width / 10)) * 10;
    const y = Math.floor(Math.random() * (canvas.height / 10)) * 10;
    return { x, y };
}

function clearCanvas() {
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
}

function drawSnake() {
    snake.forEach(drawSnakePart);
}

function drawSnakePart(snakePart) {
    ctx.fillStyle = 'lightgreen';
    ctx.strokeStyle = 'darkgreen';
    ctx.fillRect(snakePart.x, snakePart.y, 10, 10);
    ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);
}

function drawFood() {
    ctx.fillStyle = 'lightpink';
    ctx.fillRect(food.x, food.y, 10, 10);
}

function moveSnake() {
    const head = { x: snake[0].x + dx, y: snake[0].y + dy };

    // 检测碰壁
    if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height || collision(head)) {
        gameOver = true;
        return;
    }

    snake.unshift(head);

    // 检查是否吃到食物
    if (head.x === food.x && head.y === food.y) {
        score++;
        food = randomFoodPosition();
        playEatSound(); // 播放音效
    } else {
        snake.pop();
    }
}

function collision(head) {
    for (let i = 1; i < snake.length; i++) {
        if (snake[i].x === head.x && snake[i].y === head.y) {
            return true;
        }
    }
    return false;
}

// 播放吃食物的音效
function playEatSound() {
    eatSound.play();
}

// 播放背景音乐
function playBackgroundMusic() {
    backgroundMusic.play();
}

// 停止背景音乐
function stopBackgroundMusic() {
    backgroundMusic.pause();
    backgroundMusic.currentTime = 0; // 重置音乐到开头
}

function main() {
    if (gameOver) {
        displayGameOver();
        return;
    }

    setTimeout(function onTick() {
        clearCanvas();
        drawFood();
        moveSnake();
        drawSnake();
        main();
    }, 100);
}

function changeDirection(event) {
    const LEFT_KEY = 37;
    const RIGHT_KEY = 39;
    const UP_KEY = 38;
    const DOWN_KEY = 40;

    const keyPressed = event.keyCode;
    const goingUp = dy === -10;
    const goingDown = dy === 10;
    const goingRight = dx === 10;
    const goingLeft = dx === -10;

    if (keyPressed === LEFT_KEY && !goingRight) {
        dx = -10;
        dy = 0;
    }

    if (keyPressed === UP_KEY && !goingDown) {
        dx = 0;
        dy = -10;
    }

    if (keyPressed === RIGHT_KEY && !goingLeft) {
        dx = 10;
        dy = 0;
    }

    if (keyPressed === DOWN_KEY && !goingUp) {
        dx = 0;
        dy = 10;
    }
}

// 显示游戏结束
function displayGameOver() {
    ctx.fillStyle = "pink";
    ctx.font = "30px Arial";
     // 绘制“游戏结束!”位于中心稍上方
    ctx.fillText("很遗憾,游戏结束!", canvas.width / 2 - 115, canvas.height / 2 - 20);
    // 绘制得分位于中心稍下方
    ctx.fillText("得分: " + score, canvas.width / 2 - 50, canvas.height / 2 + 20);
    document.getElementById("startButton").style.display = "block";
    stopBackgroundMusic(); // 停止背景音乐
}


function startGame() {
    snake = [{ x: 50, y: 50 }];
    score = 0;
    dx = 10;
    dy = 0;
    gameOver = false;
    food = randomFoodPosition();
    document.getElementById('startButton').style.display = 'none';
    playBackgroundMusic(); // 播放背景音乐
    main();
}

food = randomFoodPosition();
main();

以上是`script.js` 文件,请找一下无法播放背景音乐的原因是什么?
回复 支持 反对

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
22#
发表于 2024-8-7 19:25:28 | 只看该作者
张复礼 发表于 2024-08-07 19:24
你好,可以用函数来帮我实现游戏过程中持续出现背景音 ...


好的,小朋友!我们可以在游戏过程中添加背景音乐,让你的贪吃蛇游戏更有趣。我们将使用一个音频文件来作为背景音乐,并在游戏开始时播放它,游戏结束时暂停它。

假设你有一个叫做 `background.mp3` 的背景音乐文件,可以将其放置在与 `index.html` 和 `script.js` 同一个目录中。接下来,我们将使用一个函数来播放和控制这个背景音乐。

### 第一步:准备背景音乐文件

确保 `background.mp3` 文件放置在项目目录中。

### 第二步:修改 JavaScript 代码

在你的 `script.js` 文件中,添加一个函数来播放背景音乐,并在游戏开始和结束时进行相应的操作。

#### 修改后的 `script.js` 文件:

  1. const canvas = document.getElementById('gameCanvas');
  2. const ctx = canvas.getContext('2d');

  3. let snake = [{x: 150, y: 150}, {x: 140, y: 150}, {x: 130, y: 150}];
  4. let food = { x: 0, y: 0 };
  5. let dx = 10;
  6. let dy = 0;
  7. let score = 0;
  8. let gameOver = false;

  9. // 创建音效对象
  10. const eatSound = new Audio('eat.mp3');

  11. // 创建背景音乐对象
  12. const backgroundMusic = new Audio('background.mp3');
  13. backgroundMusic.loop = true; // 设置循环播放

  14. document.addEventListener("keydown", changeDirection);

  15. function randomFoodPosition() {
  16.     const x = Math.floor(Math.random() * (canvas.width / 10)) * 10;
  17.     const y = Math.floor(Math.random() * (canvas.height / 10)) * 10;
  18.     return { x, y };
  19. }

  20. function clearCanvas() {
  21.     ctx.fillStyle = "white";
  22.     ctx.fillRect(0, 0, canvas.width, canvas.height);
  23. }

  24. function drawSnake() {
  25.     snake.forEach(drawSnakePart);
  26. }

  27. function drawSnakePart(snakePart) {
  28.     ctx.fillStyle = 'lightgreen';
  29.     ctx.strokeStyle = 'darkgreen';
  30.     ctx.fillRect(snakePart.x, snakePart.y, 10, 10);
  31.     ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);
  32. }

  33. function drawFood() {
  34.     ctx.fillStyle = 'red';
  35.     ctx.fillRect(food.x, food.y, 10, 10);
  36. }

  37. function moveSnake() {
  38.     const head = { x: snake[0].x + dx, y: snake[0].y + dy };

  39.     if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height || collision(head)) {
  40.         gameOver = true;
  41.         return;
  42.     }

  43.     snake.unshift(head);

  44.     if (head.x === food.x && head.y === food.y) {
  45.         score++;
  46.         food = randomFoodPosition();
  47.         playEatSound(); // 播放音效
  48.     } else {
  49.         snake.pop();
  50.     }
  51. }

  52. function collision(head) {
  53.     for (let i = 1; i < snake.length; i++) {
  54.         if (snake[i].x === head.x && snake[i].y === head.y) {
  55.             return true;
  56.         }
  57.     }
  58.     return false;
  59. }

  60. // 播放吃食物的音效
  61. function playEatSound() {
  62.     eatSound.play();
  63. }

  64. // 播放背景音乐
  65. function playBackgroundMusic() {
  66.     backgroundMusic.play();
  67. }

  68. // 停止背景音乐
  69. function stopBackgroundMusic() {
  70.     backgroundMusic.pause();
  71.     backgroundMusic.currentTime = 0; // 重置音乐到开头
  72. }

  73. function main() {
  74.     if (gameOver) {
  75.         displayGameOver();
  76.         return;
  77.     }

  78.     setTimeout(function onTick() {
  79.         clearCanvas();
  80.         drawFood();
  81.         moveSnake();
  82.         drawSnake();
  83.         main();
  84.     }, 100);
  85. }

  86. function changeDirection(event) {
  87.     const LEFT_KEY = 37;
  88.     const RIGHT_KEY = 39;
  89.     const UP_KEY = 38;
  90.     const DOWN_KEY = 40;

  91.     const keyPressed = event.keyCode;
  92.     const goingUp = dy === -10;
  93.     const goingDown = dy === 10;
  94.     const goingRight = dx === 10;
  95.     const goingLeft = dx === -10;

  96.     if (keyPressed === LEFT_KEY && !goingRight) {
  97.         dx = -10;
  98.         dy = 0;
  99.     }

  100.     if (keyPressed === UP_KEY && !goingDown) {
  101.         dx = 0;
  102.         dy = -10;
  103.     }

  104.     if (keyPressed === RIGHT_KEY && !goingLeft) {
  105.         dx = 10;
  106.         dy = 0;
  107.     }

  108.     if (keyPressed === DOWN_KEY && !goingUp) {
  109.         dx = 0;
  110.         dy = 10;
  111.     }
  112. }

  113. function displayGameOver() {
  114.     ctx.fillStyle = "black";
  115.     ctx.font = "30px Arial";
  116.     ctx.fillText("游戏结束!", canvas.width / 2 - 75, canvas.height / 2 - 20);
  117.     ctx.fillText("得分: " + score, canvas.width / 2 - 50, canvas.height / 2 + 20);
  118.     document.getElementById('startButton').style.display = 'block';
  119.     stopBackgroundMusic(); // 停止背景音乐
  120. }

  121. function startGame() {
  122.     snake = [{x: 150, y: 150}, {x: 140, y: 150}, {x: 130, y: 150}];
  123.     score = 0;
  124.     dx = 10;
  125.     dy = 0;
  126.     gameOver = false;
  127.     food = randomFoodPosition();
  128.     document.getElementById('startButton').style.display = 'none';
  129.     playBackgroundMusic(); // 播放背景音乐
  130.     main();
  131. }

  132. food = randomFoodPosition();
  133. main();
复制代码


### 第三步:修改 HTML 代码

如果你还没有一个 "开始游戏" 按钮,请确保在 `index.html` 中添加它:

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>贪吃蛇游戏</title>
  6.     <style>
  7.         body {
  8.             display: flex;
  9.             flex-direction: column;
  10.             align-items: center;
  11.             justify-content: center;
  12.             height: 100vh;
  13.             background-color: #e0e0e0;
  14.             margin: 0;
  15.         }
  16.         h1 {
  17.             margin-bottom: 20px;
  18.         }
  19.         #gameContainer {
  20.             display: flex;
  21.             flex-direction: column;
  22.             align-items: center;
  23.         }
  24.         canvas {
  25.             border: 1px solid black;
  26.             background-color: #f5f5f5;
  27.         }
  28.         #startButton {
  29.             display: none; /* 默认隐藏 */
  30.             padding: 10px 20px;
  31.             font-size: 20px;
  32.             margin-top: 20px;
  33.             cursor: pointer;
  34.             background-color: #4CAF50; /* 绿色按钮 */
  35.             color: white;
  36.             border: none;
  37.             border-radius: 5px;
  38.         }
  39.         #startButton:hover {
  40.             background-color: #ADD8E6; /* 浅蓝色 */
  41.         }
  42.         #gameOverText {
  43.             font-size: 24px;
  44.             color: red;
  45.             text-align: center;
  46.             margin-top: 20px;
  47.             display: none; /* 默认隐藏 */
  48.         }
  49.         .hidden {
  50.             display: none;
  51.         }
  52.     </style>
  53. </head>
  54. <body>
  55.     <h1>贪吃蛇游戏</h1>
  56.     <div id="gameContainer">
  57.         <canvas id="gameCanvas" width="400" height="400"></canvas>
  58.         <div id="gameOverText" class="hidden">
  59.             <p>很遗憾!游戏结束</p>
  60.             <p>得分: <span id="score">0</span></p>
  61.         </div>
  62.         <button id="startButton" onclick="startGame()">开始游戏</button>
  63.     </div>
  64.     <script src="script.js"></script>
  65. </body>
  66. </html>
复制代码


### 解释修改内容:

1. **创建背景音乐对象**:
  
  1. const backgroundMusic = new Audio('background.mp3');
  2.    backgroundMusic.loop = true; // 设置循环播放
复制代码

   这行代码创建了一个新的音频对象,并载入 `background.mp3` 文件,同时设置了循环播放。

2. **播放背景音乐函数**:
  
  1. function playBackgroundMusic() {
  2.        backgroundMusic.play();
  3.    }
复制代码


3. **停止背景音乐函数**:
  
  1. function stopBackgroundMusic() {
  2.        backgroundMusic.pause();
  3.        backgroundMusic.currentTime = 0; // 重置音乐到开头
  4.    }
复制代码


4. **在游戏开始时播放背景音乐**:
  
  1. function startGame() {
  2.        // ... 其他代码
  3.        playBackgroundMusic(); // 播放背景音乐
  4.        main();
  5.    }
复制代码


5. **在游戏结束时停止背景音乐**:
  
  1. function displayGameOver() {
  2.        // ... 其他代码
  3.        stopBackgroundMusic(); // 停止背景音乐
  4.    }
复制代码


通过这些修改,你的游戏在开始时会播放背景音乐,并在游戏结束时停止。如果有任何问题或需要进一步帮助,请随时告诉我哦!
回复 支持 反对

使用道具 举报

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
21#
 楼主| 发表于 2024-8-7 19:24:53 | 只看该作者
你好,可以用函数来帮我实现游戏过程中持续出现背景音乐吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表