科学教育

搜索
楼主: ZLJ
打印 上一主题 下一主题

王桃桃

[复制链接]

29

主题

107

帖子

348

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
348
21#
 楼主| 发表于 2024-7-28 12:11:37 | 只看该作者
kaia 发表于 2024-7-28 12:05
当然可以!我们可以通过设置`Audio`对象的`volume`属性来调整音乐的音量。这个属性的值在0到1之间,表示 ...

还有个问题很奇怪,为什么我的图片命名是透明背景的,但是在游戏界面里呈现的确实有浅白背景的
回复 支持 反对

使用道具 举报

0

主题

1147

帖子

1718

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1718
22#
发表于 2024-7-28 12:12:45 | 只看该作者
ZLJ 发表于 2024-07-28 12:11
还有个问题很奇怪,为什么我的图片命名是透明背景的, ...


理解你的疑问,这个问题可能有几个原因,通常与图片的格式或处理方式有关。以下是一些常见的可能原因以及解决方法:

### 可能原因及解决方法:

#### 1. **图片格式问题**:
确保你的图片是PNG格式,PNG格式支持透明背景。如果你的图片是JPG格式,那么它不会支持透明背景。

**解决方法**:
将图片转换为PNG格式,再试一次。

#### 2. **图片处理问题**:
有时在某些图像编辑软件中处理图片时,可能会意外地添加背景。

**解决方法**:
重新检查并处理图像,确保背景部分是透明的。使用像Photoshop或GIMP等图像编辑软件来确认和处理。

#### 3. **Canvas绘制问题**:
确保Canvas使用正确的方法绘制透明背景的图片。

**解决方法**:
确保你只是在Canvas上绘制图像,而没有其他颜色填充背景。例如,确保在`drawPlayer`函数中没有不必要的`fillRect`等操作。

### 示例代码复查:
确保在`drawPlayer`函数及其他绘制图像的地方,确实没有多余的背景填充代码。

  1. function drawPlayer() {
  2.     ctx.save(); // 保存当前绘图状态
  3.     ctx.translate(playerX + playerWidth / 2, playerY + playerHeight / 2); // 将原点移动到玩家中心
  4.     ctx.rotate(-45 * Math.PI / 180); // 旋转画布,使播放器正常方向
  5.     ctx.drawImage(playerImg, -playerWidth / 2, -playerHeight / 2, playerWidth, playerHeight); // 绘制玩家图片,注意位置偏移
  6.     ctx.restore(); // 恢复到之前的绘图状态
  7. }
复制代码


### 确认图片格式和透明度:
确保图片是正确的透明PNG图片,并且没有意外地添加了背景颜色。这可以用图像编辑软件来确认:

#### 在Photoshop中:
1. 打开你的图片。
2. 确认背景是透明的(背景层应该是棋盘格样式)。
3. 如果不是透明的,删除背景或重新处理图片,然后保存为PNG格式。

#### 在GIMP中:
1. 打开你的图片。
2. 确认背景是透明的。
3. 如果不是透明的,删除背景或重新处理图片,然后导出为PNG格式。

### 总结:
- **检查图片格式**:确保是PNG格式。
- **重新处理图片**:确保背景透明。
- **检查代码**:确保没有不必要的背景填充操作。

通过以上方法,你应该可以解决图片透明度的问题。如果仍有问题,请随时告诉我,我会尽力帮你解决!
回复 支持 反对

使用道具 举报

29

主题

107

帖子

348

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
348
23#
 楼主| 发表于 2024-7-29 09:38:39 | 只看该作者
kaia 发表于 2024-7-28 12:12
理解你的疑问,这个问题可能有几个原因,通常与图片的格式或处理方式有关。以下是一些常见的可能原因以及 ...

好的,那么可以让播放和暂停放置在画布右边吗?右边设置一列放各种按钮
回复 支持 反对

使用道具 举报

0

主题

1147

帖子

1718

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1718
24#
发表于 2024-7-29 09:39:16 | 只看该作者
ZLJ 发表于 2024-07-29 09:38
好的,那么可以让播放和暂停放置在画布右边吗?右边设 ...


当然可以!我们可以使用CSS来定位播放和暂停按钮,并且在画布右侧放置一列按钮区域。我们可以通过修改HTML和CSS来实现这个效果。

### 修改后的HTML:
这里我们会添加一个用于包裹所有按钮的容器,并将其放置在画布的右边。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>飞机大战</title>
  7.     <style>
  8.         body {
  9.             display: flex;
  10.             align-items: center;
  11.             justify-content: center;
  12.             height: 100vh;
  13.             margin: 0;
  14.             background-color: #000;
  15.             color: #fff;
  16.             font-family: Arial, sans-serif;
  17.         }

  18.         .game-container {
  19.             display: flex;
  20.             align-items: flex-start;
  21.         }

  22.         .controls {
  23.             display: flex;
  24.             flex-direction: column;
  25.             margin-left: 20px;
  26.         }

  27.         canvas {
  28.             border: 1px solid #fff;
  29.         }

  30.         .button {
  31.             background-color: transparent;
  32.             border: none;
  33.             margin: 10px 0;
  34.             cursor: pointer;
  35.         }

  36.         #volumeControl {
  37.             width: 100px;
  38.             margin-top: 10px;
  39.         }
  40.     </style>
  41. </head>
  42. <body>
  43.     <div class="game-container">
  44.         <canvas id="gameCanvas" width="800" height="600"></canvas>
  45.         <div class="controls">
  46.             <button id="musicButton" class="button">
  47.                 <img id="musicIcon" src="play.png" alt="Play/Pause">
  48.             </button>
  49.             音量:<input id="volumeControl" type="range" min="0" max="1" step="0.1" value="0.5">
  50.         </div>
  51.     </div>
  52.     <script>
  53.         const canvas = document.getElementById('gameCanvas');
  54.         const ctx = canvas.getContext('2d');

  55.         // 加载图像
  56.         const playerImg = new Image();
  57.         const enemyImg = new Image();
  58.         playerImg.src = 'player.png';  // 替换为你的玩家图像路径
  59.         enemyImg.src = 'enemy.png';    // 替换为你的敌人图像路径

  60.         // 加载音效
  61.         const hitSound = new Audio('hit.mp3'); // 替换为你的音效文件路径

  62.         // 加载背景音乐
  63.         const bgMusic = new Audio('background.mp3'); // 替换为你的背景音乐文件路径
  64.         bgMusic.loop = true; // 设置循环播放

  65.         // 控制播放/暂停按钮
  66.         const musicButton = document.getElementById('musicButton');
  67.         const musicIcon = document.getElementById('musicIcon');
  68.         let isMusicPlaying = false;

  69.         musicButton.addEventListener('click', () => {
  70.             if (isMusicPlaying) {
  71.                 bgMusic.pause();
  72.                 musicIcon.src = 'play.png'; // 切换为播放图标
  73.             } else {
  74.                 bgMusic.play();
  75.                 musicIcon.src = 'pause.png'; // 切换为暂停图标
  76.             }
  77.             isMusicPlaying = !isMusicPlaying;
  78.         });

  79.         // 音量控制
  80.         const volumeControl = document.getElementById('volumeControl');
  81.         volumeControl.addEventListener('input', (e) => {
  82.             bgMusic.volume = e.target.value;
  83.         });

  84.         // 玩家飞机的相关参数
  85.         const playerWidth = 50;
  86.         const playerHeight = 50;
  87.         let playerX = (canvas.width - playerWidth) / 2;
  88.         let playerY = canvas.height - playerHeight - 10;
  89.         const playerSpeed = 7;

  90.         // 子弹和敌人的数组
  91.         let bullets = [];
  92.         let enemies = [];
  93.         let score = 0;

  94.         // 按键监听
  95.         document.addEventListener('keydown', movePlayer);
  96.         document.addEventListener('keydown', shootBullet);

  97.         // 移动玩家
  98.         function movePlayer(e) {
  99.             if (e.key === 'ArrowLeft' && playerX > 0) {
  100.                 playerX -= playerSpeed;
  101.             }
  102.             if (e.key === 'ArrowRight' && playerX < canvas.width - playerWidth) {
  103.                 playerX += playerSpeed;
  104.             }
  105.         }

  106.         // 发射子弹
  107.         function shootBullet(e) {
  108.             if (e.key === ' ') {
  109.                 bullets.push({ x: playerX + playerWidth / 2 - 2.5, y: playerY, speed: 10 });
  110.             }
  111.         }

  112.         // 绘制玩家
  113.         function drawPlayer() {
  114.             ctx.save(); // 保存当前绘图状态
  115.             ctx.translate(playerX + playerWidth / 2, playerY + playerHeight / 2); // 将原点移动到玩家中心
  116.             ctx.rotate(-45 * Math.PI / 180); // 旋转画布,使播放器正常方向
  117.             ctx.drawImage(playerImg, -playerWidth / 2, -playerHeight / 2, playerWidth, playerHeight); // 绘制玩家图片,注意位置偏移
  118.             ctx.restore(); // 恢复到之前的绘图状态
  119.         }

  120.         // 绘制子弹
  121.         function drawBullets() {
  122.             ctx.fillStyle = '#ff0';
  123.             bullets.forEach((bullet, index) => {
  124.                 bullet.y -= bullet.speed;
  125.                 ctx.fillRect(bullet.x, bullet.y, 5, 15);
  126.                 if (bullet.y < 0) {
  127.                     bullets.splice(index, 1);
  128.                 }
  129.             });
  130.         }

  131.         // 绘制敌人
  132.         function drawEnemies() {
  133.             enemies.forEach((enemy, index) => {
  134.                 enemy.y += enemy.speed;
  135.                 ctx.drawImage(enemyImg, enemy.x, enemy.y, enemy.width, enemy.height);
  136.                 if (enemy.y > canvas.height) {
  137.                     enemies.splice(index, 1);
  138.                     gameOver();
  139.                 }
  140.             });
  141.         }

  142.         // 生成敌人
  143.         function generateEnemies() {
  144.             if (Math.random() < 0.02) {
  145.                 const x = Math.random() * (canvas.width - playerWidth);
  146.                 enemies.push({ x: x, y: 0, width: 50, height: 50, speed: 3 });
  147.             }
  148.         }

  149.         // 检测碰撞
  150.         function detectCollisions() {
  151.             bullets.forEach((bullet, bIndex) => {
  152.                 enemies.forEach((enemy, eIndex) => {
  153.                     if (bullet.x > enemy.x && bullet.x < enemy.x + enemy.width &&
  154.                         bullet.y > enemy.y && bullet.y < enemy.y + enemy.height) {
  155.                         score += 10;
  156.                         bullets.splice(bIndex, 1);
  157.                         enemies.splice(eIndex, 1);
  158.                         hitSound.play(); // 播放音效
  159.                     }
  160.                 });
  161.             });

  162.             enemies.forEach(enemy => {
  163.                 if (playerX < enemy.x + enemy.width &&
  164.                     playerX + playerWidth > enemy.x &&
  165.                     playerY < enemy.y + enemy.height &&
  166.                     playerY + playerHeight > enemy.y) {
  167.                     gameOver();
  168.                 }
  169.             });
  170.         }

  171.         // 游戏结束
  172.         function gameOver() {
  173.             alert(`Game Over! Your score is ${score}`);
  174.             document.location.reload();
  175.         }

  176.         // 更新画面
  177.         function update() {
  178.             ctx.clearRect(0, 0, canvas.width, canvas.height);
  179.             drawPlayer();
  180.             drawBullets();
  181.             drawEnemies();
  182.             detectCollisions();
  183.             generateEnemies();
  184.             requestAnimationFrame(update);
  185.         }

  186.         update();
  187.     </script>
  188. </body>
  189. </html>
复制代码


### 说明:

1. **HTML部分**:在`div`元素内添加一个`canvas`元素和一个用于放置按钮的`div`,这样可以将画布和按钮并排放置。
2. **CSS部分**:使用Flexbox布局,将`game-container`设置为Flex容器,并使其内容水平对齐。将按钮容器`controls`设置为垂直列布局。
3. **JavaScript部分**:通过获取并设置滑动条的值来调整音量。

这样,播放/暂停按钮和音量控制滑动条就会显示在画布的右边排列成一列。你可以根据自己的需要继续添加更多按钮,所有按钮都将垂直排列。

如果有任何问题或需要进一步的帮助,请随时告诉我!
回复 支持 反对

使用道具 举报

29

主题

107

帖子

348

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
348
25#
 楼主| 发表于 2024-7-29 09:41:19 | 只看该作者
kaia 发表于 2024-7-29 09:39
当然可以!我们可以使用CSS来定位播放和暂停按钮,并且在画布右侧放置一列按钮区域。我们可以通过修改HTM ...

请你把三件套分开成三个文件
回复 支持 反对

使用道具 举报

0

主题

1147

帖子

1718

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1718
26#
发表于 2024-7-29 09:42:22 | 只看该作者
ZLJ 发表于 2024-07-29 09:41
请你把三件套分开成三个文件


当然可以!我们可以将HTML、CSS和JavaScript代码分成三个单独的文件。这样更便于管理和维护。

### **index.html**(HTML文件)
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>飞机大战</title>
  6.     <link rel="stylesheet" href="styles.css"> <!-- 引用外部CSS文件 -->
  7. </head>
  8. <body>
  9.     <div class="game-container">
  10.         <canvas id="gameCanvas" width="800" height="600"></canvas>
  11.         <div class="controls">
  12.             <button id="musicButton" class="button">
  13.                 <img id="musicIcon" src="play.png" alt="Play/Pause" width="30" height="30">
  14.             </button>
  15.             <label for="volumeControl">音量:</label>
  16.             <input type="range" id="volumeControl" min="0" max="1" step="0.01" value="1">
  17.         </div>
  18.     </div>
  19.     <script src="game.js"></script> <!-- 引用外部JavaScript文件 -->
  20. </body>
  21. </html>
复制代码


### **styles.css**(CSS文件)
  1. body {
  2.     display: flex;
  3.     align-items: center;
  4.     justify-content: center;
  5.     height: 100vh;
  6.     margin: 0;
  7.     background-color: #000;
  8.     color: #fff;
  9.     font-family: Arial, sans-serif;
  10. }

  11. .game-container {
  12.     display: flex;
  13.     align-items: flex-start;
  14. }

  15. .controls {
  16.     display: flex;
  17.     flex-direction: column;
  18.     margin-left: 20px;
  19. }

  20. canvas {
  21.     border: 1px solid #fff;
  22. }

  23. .button {
  24.     background-color: transparent;
  25.     border: none;
  26.     margin: 10px 0;
  27.     cursor: pointer;
  28. }

  29. #volumeControl {
  30.     width: 100px;
  31.     margin-top: 10px;
  32. }
复制代码


### **game.js**(JavaScript文件)
  1. // 获取Canvas和上下文
  2. const canvas = document.getElementById('gameCanvas');
  3. const ctx = canvas.getContext('2d');

  4. // 加载图像
  5. const playerImg = new Image();
  6. const enemyImg = new Image();
  7. playerImg.src = 'player.png';  // 替换为你的玩家图像路径
  8. enemyImg.src = 'enemy.png';    // 替换为你的敌人图像路径

  9. // 加载音效
  10. const hitSound = new Audio('hit.mp3'); // 替换为你的音效文件路径

  11. // 加载背景音乐
  12. const bgMusic = new Audio('background.mp3'); // 替换为你的背景音乐文件路径
  13. bgMusic.loop = true; // 设置循环播放

  14. // 控制播放/暂停按钮
  15. const musicButton = document.getElementById('musicButton');
  16. const musicIcon = document.getElementById('musicIcon');
  17. let isMusicPlaying = false;

  18. musicButton.addEventListener('click', () => {
  19.     if (isMusicPlaying) {
  20.         bgMusic.pause();
  21.         musicIcon.src = 'play.png'; // 切换为播放图标
  22.     } else {
  23.         bgMusic.play();
  24.         musicIcon.src = 'pause.png'; // 切换为暂停图标
  25.     }
  26.     isMusicPlaying = !isMusicPlaying;
  27. });

  28. // 音量控制
  29. const volumeControl = document.getElementById('volumeControl');
  30. volumeControl.addEventListener('input', (e) => {
  31.     bgMusic.volume = e.target.value;
  32. });

  33. // 玩家飞机的相关参数
  34. const playerWidth = 50;
  35. const playerHeight = 50;
  36. let playerX = (canvas.width - playerWidth) / 2;
  37. let playerY = canvas.height - playerHeight - 10;
  38. const playerSpeed = 7;

  39. // 子弹和敌人的数组
  40. let bullets = [];
  41. let enemies = [];
  42. let score = 0;

  43. // 按键监听
  44. document.addEventListener('keydown', movePlayer);
  45. document.addEventListener('keydown', shootBullet);

  46. // 移动玩家
  47. function movePlayer(e) {
  48.     if (e.key === 'ArrowLeft' && playerX > 0) {
  49.         playerX -= playerSpeed;
  50.     }
  51.     if (e.key === 'ArrowRight' && playerX < canvas.width - playerWidth) {
  52.         playerX += playerSpeed;
  53.     }
  54. }

  55. // 发射子弹
  56. function shootBullet(e) {
  57.     if (e.key === ' ') {
  58.         bullets.push({ x: playerX + playerWidth / 2 - 2.5, y: playerY, speed: 10 });
  59.     }
  60. }

  61. // 绘制玩家
  62. function drawPlayer() {
  63.     ctx.save(); // 保存当前绘图状态
  64.     ctx.translate(playerX + playerWidth / 2, playerY + playerHeight / 2); // 将原点移动到玩家中心
  65.     ctx.rotate(-45 * Math.PI / 180); // 旋转画布,使播放器正常方向
  66.     ctx.drawImage(playerImg, -playerWidth / 2, -playerHeight / 2, playerWidth, playerHeight); // 绘制玩家图片,注意位置偏移
  67.     ctx.restore(); // 恢复到之前的绘图状态
  68. }

  69. // 绘制子弹
  70. function drawBullets() {
  71.     ctx.fillStyle = '#ff0';
  72.     bullets.forEach((bullet, index) => {
  73.         bullet.y -= bullet.speed;
  74.         ctx.fillRect(bullet.x, bullet.y, 5, 15);
  75.         if (bullet.y < 0) {
  76.             bullets.splice(index, 1);
  77.         }
  78.     });
  79. }

  80. // 绘制敌人
  81. function drawEnemies() {
  82.     enemies.forEach((enemy, index) => {
  83.         enemy.y += enemy.speed;
  84.         ctx.drawImage(enemyImg, enemy.x, enemy.y, enemy.width, enemy.height);
  85.         if (enemy.y > canvas.height) {
  86.             enemies.splice(index, 1);
  87.             gameOver();
  88.         }
  89.     });
  90. }

  91. // 生成敌人
  92. function generateEnemies() {
  93.     if (Math.random() < 0.02) {
  94.         const x = Math.random() * (canvas.width - playerWidth);
  95.         enemies.push({ x: x, y: 0, width: 50, height: 50, speed: 3 });
  96.     }
  97. }

  98. // 检测碰撞
  99. function detectCollisions() {
  100.     bullets.forEach((bullet, bIndex) => {
  101.         enemies.forEach((enemy, eIndex) => {
  102.             if (bullet.x > enemy.x && bullet.x < enemy.x + enemy.width &&
  103.                 bullet.y > enemy.y && bullet.y < enemy.y + enemy.height) {
  104.                 score += 10;
  105.                 bullets.splice(bIndex, 1);
  106.                 enemies.splice(eIndex, 1);
  107.                 hitSound.play(); // 播放音效
  108.             }
  109.         });
  110.     });

  111.     enemies.forEach(enemy => {
  112.         if (playerX < enemy.x + enemy.width &&
  113.             playerX + playerWidth > enemy.x &&
  114.             playerY < enemy.y + enemy.height &&
  115.             playerY + playerHeight > enemy.y) {
  116.             gameOver();
  117.         }
  118.     });
  119. }

  120. // 游戏结束
  121. function gameOver() {
  122.     alert(`Game Over! Your score is ${score}`);
  123.     document.location.reload();
  124. }

  125. // 更新画面
  126. function update() {
  127.     ctx.clearRect(0, 0, canvas.width, canvas.height);
  128.     drawPlayer();
  129.     drawBullets();
  130.     drawEnemies();
  131.     detectCollisions();
  132.     generateEnemies();
  133.     requestAnimationFrame(update);
  134. }

  135. update();
复制代码


### 文件说明:

1. `index.html`:这是你的HTML文件,包含了所有的标签结构以及引用外部CSS和JS文件。
2. `styles.css`:这是你的CSS文件,包含所有样式定义。
3. `game.js`:这是你的JavaScript文件,包含所有游戏逻辑和事件处理。

确保将这些文件放在同一目录下,并且图片和音效文件的路径是正确的。这样,当你打开`index.html`文件时,你的游戏应该能正常运行,并带有播放/暂停按钮和音量控制功能。

如果还有其他问题或者需要进一步的帮助,请随时告诉我!
回复 支持 反对

使用道具 举报

29

主题

107

帖子

348

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
348
27#
 楼主| 发表于 2024-7-29 10:15:31 | 只看该作者
kaia 发表于 2024-7-29 09:42
当然可以!我们可以将HTML、CSS和JavaScript代码分成三个单独的文件。这样更便于管理和维护。

### **ind ...

大标题“飞机大战”四个字不见了
回复 支持 反对

使用道具 举报

0

主题

1147

帖子

1718

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1718
28#
发表于 2024-7-29 10:16:16 | 只看该作者
ZLJ 发表于 2024-07-29 10:15
大标题“飞机大战”四个字不见了


明白了。如果大标题“飞机大战”不见了,可能是因为CSS布局和样式的问题。我们需要确保标题正确显示,并调整它的位置,使其与游戏画布和控制按钮不冲突。

我们可以做以下调整:
1. 确保标题在HTML中正确放置。
2. 调整CSS样式以确保标题显示在合适的位置。

### 修改后的`index.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="styles.css">
  8. </head>
  9. <body>
  10.     <div class="game-container">
  11.         <canvas id="gameCanvas" width="800" height="600"></canvas>
  12.         <div class="controls">
  13.             <button class="button" id="musicButton">
  14.                 <img id="musicIcon" src="play.png" alt="播放/暂停">
  15.             </button>
  16.             <label for="volumeControl">音量:</label>
  17.             <input type="range" id="volumeControl" min="0" max="1" step="0.1" value="1">
  18.         </div>
  19.     </div>
  20.     <h1>飞机大战</h1>
  21.     <script src="game.js"></script>
  22. </body>
  23. </html>
复制代码


### 修改后的`styles.css`(CSS文件)

  1. body {
  2.     display: flex;
  3.     flex-direction: column;
  4.     align-items: center;
  5.     justify-content: flex-start;
  6.     height: 100vh;
  7.     margin: 0;
  8.     background-color: #000;
  9.     color: #fff;
  10.     font-family: Arial, sans-serif;
  11. }

  12. h1 {
  13.     margin-bottom: 20px;
  14. }

  15. .game-container {
  16.     display: flex;
  17.     align-items: flex-start;
  18. }

  19. .controls {
  20.     display: flex;
  21.     flex-direction: column;
  22.     margin-left: 20px;
  23. }

  24. canvas {
  25.     border: 1px solid #fff;
  26. }

  27. .button {
  28.     background-color: transparent;
  29.     border: none;
  30.     margin: 10px 0;
  31.     cursor: pointer;
  32. }

  33. #volumeControl {
  34.     width: 100px;
  35.     margin-top: 10px;
  36. }
复制代码


### 修改后的`game.js`(JavaScript文件)

  1. // 获取Canvas和上下文
  2. const canvas = document.getElementById('gameCanvas');
  3. const ctx = canvas.getContext('2d');

  4. // 加载图像
  5. const playerImg = new Image();
  6. const enemyImg = new Image();
  7. playerImg.src = 'player.png';  // 替换为你的玩家图像路径
  8. enemyImg.src = 'enemy.png';    // 替换为你的敌人图像路径

  9. // 加载音效
  10. const hitSound = new Audio('hit.mp3'); // 替换为你的音效文件路径

  11. // 加载背景音乐
  12. const bgMusic = new Audio('background.mp3'); // 替换为你的背景音乐文件路径
  13. bgMusic.loop = true; // 设置循环播放

  14. // 控制播放/暂停按钮
  15. const musicButton = document.getElementById('musicButton');
  16. const musicIcon = document.getElementById('musicIcon');
  17. let isMusicPlaying = false;

  18. musicButton.addEventListener('click', () => {
  19.     if (isMusicPlaying) {
  20.         bgMusic.pause();
  21.         musicIcon.src = 'play.png'; // 切换为播放图标
  22.     } else {
  23.         bgMusic.play();
  24.         musicIcon.src = 'pause.png'; // 切换为暂停图标
  25.     }
  26.     isMusicPlaying = !isMusicPlaying;
  27. });

  28. // 音量控制
  29. const volumeControl = document.getElementById('volumeControl');
  30. volumeControl.addEventListener('input', (e) => {
  31.     bgMusic.volume = e.target.value;
  32. });

  33. // 玩家飞机的相关参数
  34. const playerWidth = 50;
  35. const playerHeight = 50;
  36. let playerX = (canvas.width - playerWidth) / 2;
  37. let playerY = canvas.height - playerHeight - 10;
  38. const playerSpeed = 7;

  39. // 子弹和敌人的数组
  40. let bullets = [];
  41. let enemies = [];
  42. let score = 0;

  43. // 按键监听
  44. document.addEventListener('keydown', movePlayer);
  45. document.addEventListener('keydown', shootBullet);

  46. // 移动玩家
  47. function movePlayer(e) {
  48.     if (e.key === 'ArrowLeft' && playerX > 0) {
  49.         playerX -= playerSpeed;
  50.     }
  51.     if (e.key === 'ArrowRight' && playerX < canvas.width - playerWidth) {
  52.         playerX += playerSpeed;
  53.     }
  54. }

  55. // 发射子弹
  56. function shootBullet(e) {
  57.     if (e.key === ' ') {
  58.         bullets.push({ x: playerX + playerWidth / 2 - 2.5, y: playerY, speed: 10 });
  59.     }
  60. }

  61. // 绘制玩家
  62. function drawPlayer() {
  63.     ctx.save(); // 保存当前绘图状态
  64.     ctx.translate(playerX + playerWidth / 2, playerY + playerHeight / 2); // 将原点移动到玩家中心
  65.     ctx.rotate(-45 * Math.PI / 180); // 旋转画布,使播放器正常方向
  66.     ctx.drawImage(playerImg, -playerWidth / 2, -playerHeight / 2, playerWidth, playerHeight); // 绘制玩家图片,注意位置偏移
  67.     ctx.restore(); // 恢复到之前的绘图状态
  68. }

  69. // 绘制子弹
  70. function drawBullets() {
  71.     ctx.fillStyle = '#ff0';
  72.     bullets.forEach((bullet, index) => {
  73.         bullet.y -= bullet.speed;
  74.         ctx.fillRect(bullet.x, bullet.y, 5, 15);
  75.         if (bullet.y < 0) {
  76.             bullets.splice(index, 1);
  77.         }
  78.     });
  79. }

  80. // 绘制敌人
  81. function drawEnemies() {
  82.     enemies.forEach((enemy, index) => {
  83.         enemy.y += enemy.speed;
  84.         ctx.drawImage(enemyImg, enemy.x, enemy.y, enemy.width, enemy.height);
  85.         if (enemy.y > canvas.height) {
  86.             enemies.splice(index, 1);
  87.             gameOver();
  88.         }
  89.     });
  90. }

  91. // 生成敌人
  92. function generateEnemies() {
  93.     if (Math.random() < 0.02) {
  94.         const x = Math.random() * (canvas.width - playerWidth);
  95.         enemies.push({ x: x, y: 0, width: 50, height: 50, speed: 3 });
  96.     }
  97. }

  98. // 检测碰撞
  99. function detectCollisions() {
  100.     bullets.forEach((bullet, bIndex) => {
  101.         enemies.forEach((enemy, eIndex) => {
  102.             if (bullet.x > enemy.x && bullet.x < enemy.x + enemy.width &&
  103.                 bullet.y > enemy.y && bullet.y < enemy.y + enemy.height) {
  104.                 score += 10;
  105.                 bullets.splice(bIndex, 1);
  106.                 enemies.splice(eIndex, 1);
  107.                 hitSound.play(); // 播放音效
  108.             }
  109.         });
  110.     });

  111.     enemies.forEach(enemy => {
  112.         if (playerX < enemy.x + enemy.width &&
  113.             playerX + playerWidth > enemy.x &&
  114.             playerY < enemy.y + enemy.height &&
  115.             playerY + playerHeight > enemy.y) {
  116.             gameOver();
  117.         }
  118.     });
  119. }

  120. // 游戏结束
  121. function gameOver() {
  122.     alert(`Game Over! Your score is ${score}`);
  123.     document.location.reload();
  124. }

  125. // 更新画面
  126. function update() {
  127.     ctx.clearRect(0, 0, canvas.width, canvas.height);
  128.     drawPlayer();
  129.     drawBullets();
  130.     drawEnemies();
  131.     detectCollisions();
  132.     generateEnemies();
  133.     requestAnimationFrame(update);
  134. }

  135. update();
复制代码


### 文件说明:

1. `index.html`:这是你的HTML文件,包含所有的标签结构以及引用外部CSS和JS文件。
2. `styles.css`:这是你的CSS文件,包含所有样式定义。
3. `game.js`:这是你的JavaScript文件,包含所有游戏逻辑和事件处理。

确保将这些文件放在同一目录下,并且图片和音效文件的路径是正确的。这样,当你打开`index.html`文件时,你的游戏应该能正常运行,并带有播放/暂停按钮和音量控制功能,同时标题“飞机大战”也会正确显示。

如果还有其他问题或者需要进一步的帮助,请随时告诉我!
回复 支持 反对

使用道具 举报

29

主题

107

帖子

348

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
348
29#
 楼主| 发表于 2024-7-30 12:54:49 | 只看该作者
我现在的主页面布局有以下元素:
<button id="musicButton">
        <img id="musicIcon" src="image/play.png" alt="Play Music" width="30" height="30">
        </button>
<div class="controls">
        <label for="volumeControl">音量:</label>
        <input type="range" id="volumeControl" min="0" max="1" step="0.01" value="0.5">
    </div>
    <canvas id="gameCanvas" width="800" height="600"></canvas>
请问怎么可以让“飞机大战”四个大字在最上面顶部不变,canvas居中不变,但是让音乐开关和音量调节器在画布的右边呢?
回复 支持 反对

使用道具 举报

29

主题

107

帖子

348

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
348
30#
 楼主| 发表于 2024-7-30 13:12:35 | 只看该作者
我现在的主页面布局有以下元素:
<button id="musicButton">
        <img id="musicIcon" src="image/play.png" alt="Play Music" width="30" height="30">
        </button>
<div class="controls">
        <label for="volumeControl">音量:</label>
        <input type="range" id="volumeControl" min="0" max="1" step="0.01" value="0.5">
    </div>
    <canvas id="gameCanvas" width="800" height="600"></canvas>
请问怎么可以让“飞机大战”四个大字在最上面顶部不变,canvas居中不变,但是让音乐开关和音量调节器在画布的右边呢?@AI
回复 支持 反对

使用道具 举报

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

本版积分规则

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