|
|
了解了你的需求。我们可以通过使用`flexbox`布局来实现这种复杂的布局需求。
下面是一个完整的解决方案,包括HTML、CSS和JavaScript部分:
### HTML部分(index.html)
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <title>飞机大战</title>
- <link rel="stylesheet" href="styles.css">
- </head>
- <body>
- <div class="container">
- <h1>飞机大战</h1>
- <div class="game-container">
- <canvas id="gameCanvas" width="800" height="600"></canvas>
- <div class="controls">
- <button id="musicButton" class="button">
- <img id="musicIcon" src="play.png" alt="播放/暂停">
- </button>
- <label for="volumeControl">音量:</label>
- <input id="volumeControl" type="range" min="0" max="1" step="0.01" value="0.5">
- </div>
- </div>
- </div>
- <script src="game.js"></script>
- </body>
- </html>
复制代码
### CSS部分(styles.css)
- body {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: flex-start;
- height: 100vh;
- margin: 0;
- background-color: #000;
- color: #fff;
- font-family: Arial, sans-serif;
- }
- h1 {
- margin-top: 20px;
- margin-bottom: 20px;
- }
- .container {
- display: flex;
- flex-direction: column;
- align-items: center;
- }
- .game-container {
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .controls {
- display: flex;
- flex-direction: column;
- margin-left: 20px;
- }
- canvas {
- border: 1px solid #fff;
- }
- .button {
- background-color: transparent;
- border: none;
- margin: 10px 0;
- cursor: pointer;
- }
- #volumeControl {
- width: 100px;
- margin-top: 10px;
- }
复制代码
### JavaScript部分(game.js)
- // 获取Canvas和上下文
- const canvas = document.getElementById('gameCanvas');
- const ctx = canvas.getContext('2d');
- // 加载图像
- const playerImg = new Image();
- const enemyImg = new Image();
- playerImg.src = 'player.png'; // 替换为你的玩家图像路径
- enemyImg.src = 'enemy.png'; // 替换为你的敌人图像路径
- // 加载音效
- const hitSound = new Audio('hit.mp3'); // 替换为你的音效文件路径
- // 加载背景音乐
- const bgMusic = new Audio('background.mp3'); // 替换为你的背景音乐文件路径
- bgMusic.loop = true; // 设置循环播放
- // 控制播放/暂停按钮
- const musicButton = document.getElementById('musicButton');
- const musicIcon = document.getElementById('musicIcon');
- let isMusicPlaying = false;
- musicButton.addEventListener('click', () => {
- if (isMusicPlaying) {
- bgMusic.pause();
- musicIcon.src = 'play.png'; // 切换为播放图标
- } else {
- bgMusic.play();
- musicIcon.src = 'pause.png'; // 切换为暂停图标
- }
- isMusicPlaying = !isMusicPlaying;
- });
- // 音量控制
- const volumeControl = document.getElementById('volumeControl');
- volumeControl.addEventListener('input', (e) => {
- bgMusic.volume = e.target.value;
- });
- // 玩家飞机的相关参数
- const playerWidth = 50;
- const playerHeight = 50;
- let playerX = (canvas.width - playerWidth) / 2;
- let playerY = canvas.height - playerHeight - 10;
- const playerSpeed = 7;
- // 子弹和敌人的数组
- let bullets = [];
- let enemies = [];
- let score = 0;
- // 按键监听
- document.addEventListener('keydown', movePlayer);
- document.addEventListener('keydown', shootBullet);
- // 移动玩家
- function movePlayer(e) {
- if (e.key === 'ArrowLeft' && playerX > 0) {
- playerX -= playerSpeed;
- }
- if (e.key === 'ArrowRight' && playerX < canvas.width - playerWidth) {
- playerX += playerSpeed;
- }
- }
- // 发射子弹
- function shootBullet(e) {
- if (e.key === ' ') {
- bullets.push({ x: playerX + playerWidth / 2 - 2.5, y: playerY, speed: 10 });
- }
- }
- // 绘制玩家
- function drawPlayer() {
- ctx.save(); // 保存当前绘图状态
- ctx.translate(playerX + playerWidth / 2, playerY + playerHeight / 2); // 将原点移动到玩家中心
- ctx.rotate(-45 * Math.PI / 180); // 旋转画布,使播放器正常方向
- ctx.drawImage(playerImg, -playerWidth / 2, -playerHeight / 2, playerWidth, playerHeight); // 绘制玩家图片,注意位置偏移
- ctx.restore(); // 恢复到之前的绘图状态
- }
- // 绘制子弹
- function drawBullets() {
- ctx.fillStyle = '#ff0';
- bullets.forEach((bullet, index) => {
- bullet.y -= bullet.speed;
- ctx.fillRect(bullet.x, bullet.y, 5, 15);
- if (bullet.y < 0) {
- bullets.splice(index, 1);
- }
- });
- }
- // 绘制敌人
- function drawEnemies() {
- enemies.forEach((enemy, index) => {
- enemy.y += enemy.speed;
- ctx.drawImage(enemyImg, enemy.x, enemy.y, enemy.width, enemy.height);
- if (enemy.y > canvas.height) {
- enemies.splice(index, 1);
- gameOver();
- }
- });
- }
- // 生成敌人
- function generateEnemies() {
- if (Math.random() < 0.02) {
- const x = Math.random() * (canvas.width - playerWidth);
- enemies.push({ x: x, y: 0, width: 50, height: 50, speed: 3 });
- }
- }
- // 检测碰撞
- function detectCollisions() {
- bullets.forEach((bullet, bIndex) => {
- enemies.forEach((enemy, eIndex) => {
- if (bullet.x > enemy.x && bullet.x < enemy.x + enemy.width &&
- bullet.y > enemy.y && bullet.y < enemy.y + enemy.height) {
- score += 10;
- bullets.splice(bIndex, 1);
- enemies.splice(eIndex, 1);
- hitSound.play(); // 播放音效
- }
- });
- });
- enemies.forEach(enemy => {
- if (playerX < enemy.x + enemy.width &&
- playerX + playerWidth > enemy.x &&
- playerY < enemy.y + enemy.height &&
- playerY + playerHeight > enemy.y) {
- gameOver();
- }
- });
- }
- // 游戏结束
- function gameOver() {
- alert(`Game Over! Your score is ${score}`);
- document.location.reload();
- }
- // 更新画面
- function update() {
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- drawPlayer();
- drawBullets();
- drawEnemies();
- detectCollisions();
- generateEnemies();
- requestAnimationFrame(update);
- }
- update();
复制代码
### 总结
1. **HTML**:确保标题在最顶部,然后使用`div`包裹`canvas`和控制按钮。
2. **CSS**:使用`flexbox`布局将`canvas`居中,控制按钮放在右侧。
3. **JavaScript**:保持现有逻辑不变,新增功能如音量控制。
这样,当你打开`index.html`文件时,标题“飞机大战”会固定在顶部,游戏画布居中,播放/暂停按钮和音量控制器会显示在画布的右边。
如果有任何其他问题或需要进一步的帮助,请随时告诉我! |
|