科学教育

搜索
查看: 459|回复: 5
打印 上一主题 下一主题

赵月圆

[复制链接]

6

主题

16

帖子

48

积分

新手上路

Rank: 1

积分
48
跳转到指定楼层
楼主
发表于 2025-12-2 13:58:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
帮我生成飞机大战网页代码html,js,css
回复

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
沙发
发表于 2025-12-2 13:59:30 | 只看该作者
你好!我帮你写一个简单版的“飞机大战”网页游戏,里面有小飞机可以左右移动,能发射子弹打掉敌机。代码分三部分:HTML负责页面结构,CSS负责样式,JS负责游戏逻辑。你可以把它们全部复制到一个文件里,比如叫`plane_game.html`,然后用浏览器打开就能玩啦!

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4.   <meta charset="UTF-8" />
  5.   <title>简易飞机大战</title>
  6.   <style>
  7.     /* 设置游戏区域 */
  8.     body {
  9.       background: #000;
  10.       margin: 0;
  11.       overflow: hidden;
  12.       font-family: "微软雅黑", sans-serif;
  13.     }
  14.     #game {
  15.       position: relative;
  16.       margin: 20px auto;
  17.       width: 400px;
  18.       height: 600px;
  19.       background: linear-gradient(to bottom, #003366, #000);
  20.       border: 3px solid #fff;
  21.       overflow: hidden;
  22.     }
  23.     /* 我的飞机 */
  24.     #player {
  25.       position: absolute;
  26.       width: 40px;
  27.       height: 40px;
  28.       background: url('https://i.imgur.com/QaP1b6D.png') no-repeat center/contain;
  29.       bottom: 20px;
  30.       left: 180px;
  31.     }
  32.     /* 子弹 */
  33.     .bullet {
  34.       position: absolute;
  35.       width: 6px;
  36.       height: 14px;
  37.       background: yellow;
  38.       border-radius: 3px;
  39.     }
  40.     /* 敌机 */
  41.     .enemy {
  42.       position: absolute;
  43.       width: 40px;
  44.       height: 40px;
  45.       background: url('https://i.imgur.com/qj1d4Ss.png') no-repeat center/contain;
  46.     }
  47.     /* 分数显示 */
  48.     #scoreBoard {
  49.       color: white;
  50.       text-align: center;
  51.       margin-top: 10px;
  52.       font-size: 18px;
  53.     }
  54.   </style>
  55. </head>
  56. <body>
  57.   <div id="game">
  58.     <div id="player"></div>
  59.   </div>
  60.   <div id="scoreBoard">得分: 0</div>

  61.   <script>
  62.     const game = document.getElementById('game');
  63.     const player = document.getElementById('player');
  64.     const scoreBoard = document.getElementById('scoreBoard');

  65.     const gameWidth = game.clientWidth;
  66.     const gameHeight = game.clientHeight;

  67.     let playerX = 180; // 初始位置
  68.     const playerWidth = 40;

  69.     let bullets = []; // 存放所有子弹元素和数据
  70.     let enemies = []; // 存放所有敌机元素和数据

  71.     let score = 0;
  72.     let isGameOver = false;

  73.     // 控制飞机左右移动
  74.     document.addEventListener('keydown', (e) => {
  75.       if (isGameOver) return;

  76.       if (e.key === 'ArrowLeft' || e.key === 'a') {
  77.         playerX -= 15;
  78.         if (playerX < 0) playerX = 0;
  79.         player.style.left = playerX + 'px';
  80.       } else if (e.key === 'ArrowRight' || e.key === 'd') {
  81.         playerX += 15;
  82.         if (playerX > gameWidth - playerWidth) playerX = gameWidth - playerWidth;
  83.         player.style.left = playerX + 'px';
  84.       } else if (e.key === ' ' || e.key === 'Spacebar') {
  85.         // 发射子弹
  86.         shootBullet();
  87.       }
  88.     });

  89.     // 创建子弹
  90.     function shootBullet() {
  91.       if (isGameOver) return;

  92.       const bullet = document.createElement('div');
  93.       bullet.classList.add('bullet');
  94.       bullet.style.left = playerX + playerWidth/2 - 3 + 'px'; // 居中
  95.       bullet.style.bottom = '60px'; // 从飞机上方开始
  96.       game.appendChild(bullet);

  97.       bullets.push({
  98.         el: bullet,
  99.         x: playerX + playerWidth/2 - 3,
  100.         y: 60,
  101.         height: 14,
  102.         width: 6,
  103.       });
  104.     }

  105.     // 创建敌机(随机横向位置)
  106.     function createEnemy() {
  107.       if (isGameOver) return;

  108.       const enemy = document.createElement('div');
  109.       enemy.classList.add('enemy');
  110.       const x = Math.floor(Math.random() * (gameWidth - 40));
  111.       enemy.style.left = x + 'px';
  112.       enemy.style.top = '-40px'; // 从顶部之外开始
  113.       game.appendChild(enemy);

  114.       enemies.push({
  115.         el: enemy,
  116.         x: x,
  117.         y: -40,
  118.         width: 40,
  119.         height: 40,
  120.         speed: 2 + Math.random() * 1.5 // 不同速度
  121.       });
  122.     }

  123.     // 每50毫秒刷新游戏画面
  124.     function gameLoop() {
  125.       if (isGameOver) return;

  126.       // 移动子弹
  127.       for (let i = bullets.length -1; i >= 0; i--) {
  128.         let b = bullets[i];
  129.         b.y += 7; // 要向上移动,所以y增加(因为bottom定位,y为底部距离)
  130.         if (b.y > gameHeight) {
  131.           // 子弹飞出屏幕,删除
  132.           game.removeChild(b.el);
  133.           bullets.splice(i, 1);
  134.           continue;
  135.         }
  136.         b.el.style.bottom = b.y + 'px';
  137.       }

  138.       // 移动敌机
  139.       for (let i = enemies.length -1; i >= 0; i--) {
  140.         let en = enemies[i];
  141.         en.y += en.speed;
  142.         if (en.y > gameHeight) {
  143.           // 敌机到底部了,游戏结束
  144.           endGame();
  145.           return;
  146.         }
  147.         en.el.style.top = en.y + 'px';
  148.       }

  149.       // 检测子弹和敌机碰撞
  150.       for (let i = enemies.length -1; i >= 0; i--) {
  151.         const en = enemies[i];
  152.         const ex = en.x;
  153.         const ey = en.y;
  154.         const ew = en.width;
  155.         const eh = en.height;

  156.         for (let j = bullets.length -1; j >= 0; j--) {
  157.           const b = bullets[j];
  158.           const bx = b.x;
  159.           const by = gameHeight - b.y; // 转成top坐标
  160.           const bw = b.width;
  161.           const bh = b.height;

  162.           // 判断矩形是否重叠(简单碰撞检测)
  163.           if (!(bx > ex + ew || bx + bw < ex || by > ey + eh || by + bh < ey)) {
  164.             // 碰撞了
  165.             game.removeChild(en.el);
  166.             game.removeChild(b.el);
  167.             enemies.splice(i, 1);
  168.             bullets.splice(j, 1);

  169.             // 增加分数
  170.             score++;
  171.             scoreBoard.textContent = '得分: ' + score;
  172.             break;
  173.           }
  174.         }
  175.       }

  176.       requestAnimationFrame(gameLoop);
  177.     }

  178.     // 游戏结束
  179.     function endGame() {
  180.       isGameOver = true;
  181.       alert('游戏结束!你的得分是:' + score);
  182.       window.location.reload(); // 重新加载页面,重置游戏
  183.     }

  184.     // 定时产生敌机
  185.     setInterval(() => {
  186.       if (!isGameOver) createEnemy();
  187.     }, 1500);

  188.     // 启动游戏循环
  189.     requestAnimationFrame(gameLoop);
  190.   </script>
  191. </body>
  192. </html>
复制代码


---

### 游戏玩法说明:

- 用键盘左右箭头(或者A、D键)控制你的飞机左右移动。
- 按空格键发射子弹,子弹会向上飞。
- 敌机会从上方出现并往下飞,碰到你的飞机底部游戏结束。
- 击落敌机会得分。
- 游戏结束后会弹窗告诉你得分,并自动刷新页面重新开始。

希望你喜欢这个小游戏!如果想让飞机和敌机图更漂亮,可以换链接里的图片地址。有什么不懂问我,帮你解释哦!????✈️
回复 支持 反对

使用道具 举报

6

主题

16

帖子

48

积分

新手上路

Rank: 1

积分
48
板凳
 楼主| 发表于 2025-12-2 14:14:37 | 只看该作者
将图片变得更漂亮,游戏更刺激
回复 支持 反对

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
地板
发表于 2025-12-2 14:16:09 | 只看该作者
yue 发表于 2025-12-02 14:14
将图片变得更漂亮,游戏更刺激


好的!我帮你升级一下:

1. **图片更漂亮** —— 我用更精致的PNG飞机和敌机图片,并且加了背景星空动画。
2. **游戏更刺激** —— 敌机速度逐渐加快,出现更多!还有生命值,敌机撞到飞机会掉血,不是一碰就结束,更有挑战性。
3. **增加爆炸效果和声音提示**(简单的网页音效),让战斗感觉更嗨!

你可以直接把下面代码保存成`plane_game.html`打开玩哈~

---

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4.   <meta charset="UTF-8" />
  5.   <title>升级版飞机大战⚔️</title>
  6.   <style>
  7.     /* 背景星空动画 */
  8.     body, html {
  9.       margin: 0; padding: 0; overflow: hidden;
  10.       background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%);
  11.       height: 100%;
  12.       font-family: "微软雅黑", sans-serif;
  13.       user-select: none;
  14.     }
  15.     #starfield {
  16.       position: fixed;
  17.       width: 100%; height: 100%;
  18.       z-index: 0;
  19.       background: transparent;
  20.     }

  21.     #game {
  22.       position: relative;
  23.       margin: 20px auto;
  24.       width: 400px;
  25.       height: 600px;
  26.       background: #0B132B;
  27.       border-radius: 12px;
  28.       overflow: hidden;
  29.       box-shadow: 0 0 30px #00FFFC;
  30.       z-index: 1;
  31.     }

  32.     /* 飞机 */
  33.     #player {
  34.       position: absolute;
  35.       width: 48px;
  36.       height: 48px;
  37.       bottom: 20px;
  38.       left: 176px;
  39.       background: url('https://cdn-icons-png.flaticon.com/512/744/744465.png') no-repeat center / contain;
  40.       filter: drop-shadow(0 0 3px #0ef);
  41.       transition: filter 0.1s;
  42.     }
  43.     #player.damaged {
  44.       filter: drop-shadow(0 0 10px red);
  45.     }

  46.     /* 子弹 */
  47.     .bullet {
  48.       position: absolute;
  49.       width: 8px;
  50.       height: 16px;
  51.       background: linear-gradient(90deg, #00faff, #005f7f);
  52.       border-radius: 4px;
  53.       filter: drop-shadow(0 0 5px #00faff);
  54.     }

  55.     /* 敌机 */
  56.     .enemy {
  57.       position: absolute;
  58.       width: 48px;
  59.       height: 48px;
  60.       background: url('https://cdn-icons-png.flaticon.com/512/616/616490.png') no-repeat center / contain;
  61.       filter: drop-shadow(0 0 5px #f00);
  62.       transition: transform 0.1s;
  63.     }
  64.     .enemy.damaged {
  65.       transform: scale(1.2);
  66.     }

  67.     /* 爆炸效果 */
  68.     .explosion {
  69.       position: absolute;
  70.       width: 48px;
  71.       height: 48px;
  72.       background: url('https://i.ibb.co/1rvdWgF/explosion.png') no-repeat center / contain;
  73.       pointer-events: none;
  74.       animation: explode 0.5s ease forwards;
  75.       z-index: 10;
  76.     }
  77.     @keyframes explode {
  78.       0% {opacity:1; transform: scale(1);}
  79.       100% {opacity:0; transform: scale(1.8);}
  80.     }

  81.     /* 分数和生命 */
  82.     #infoBar {
  83.       color: #0ff;
  84.       text-align: center;
  85.       font-size: 20px;
  86.       margin-top: 10px;
  87.       letter-spacing: 1.5px;
  88.       user-select:none;
  89.     }
  90.     #hp {
  91.       color: #f44;
  92.       font-weight: bold;
  93.       margin-left: 20px;
  94.     }
  95.   </style>
  96. </head>
  97. <body>
  98.   <canvas id="starfield"></canvas>

  99.   <div id="game" tabindex="0">
  100.     <div id="player"></div>
  101.   </div>
  102.   <div id="infoBar">得分: 0 <span id="hp">❤❤❤</span></div>

  103. <script>
  104.   const game = document.getElementById("game");
  105.   const player = document.getElementById("player");
  106.   const scoreBoard = document.querySelector("#infoBar");
  107.   const hpDisplay = document.getElementById("hp");

  108.   const gameWidth = game.clientWidth;
  109.   const gameHeight = game.clientHeight;
  110.   
  111.   let playerX = (gameWidth - player.clientWidth) / 2;
  112.   const playerWidth = player.clientWidth;
  113.   const playerHeight = player.clientHeight;

  114.   // 子弹和敌机数据结构,存元素和位置等属性
  115.   let bullets = [];
  116.   let enemies = [];

  117.   let score = 0;
  118.   let hp = 3;
  119.   let isGameOver = false;

  120.   // 配置敌机初始速度和生成频率,随着分数提升会加快
  121.   let enemySpeedBase = 2.5;
  122.   let enemySpawnInterval = 1300;

  123.   // 星星背景动画
  124.   const starCanvas = document.getElementById("starfield");
  125.   const ctx = starCanvas.getContext("2d");
  126.   let stars = [];
  127.   resizeStarField();
  128.   window.addEventListener("resize", resizeStarField);

  129.   function resizeStarField() {
  130.     starCanvas.width = window.innerWidth;
  131.     starCanvas.height = window.innerHeight;
  132.     stars = [];
  133.     let count = 150;
  134.     for(let i=0; i<count; i++) {
  135.       stars.push({
  136.         x: Math.random()*starCanvas.width,
  137.         y: Math.random()*starCanvas.height,
  138.         size: Math.random()*1.5 + 0.5,
  139.         speed: Math.random()*0.2 + 0.05,
  140.         opacity: Math.random()*0.8 + 0.2,
  141.       });
  142.     }
  143.   }

  144.   function drawStars(){
  145.     ctx.clearRect(0, 0, starCanvas.width, starCanvas.height);
  146.     ctx.fillStyle = "white";
  147.     stars.forEach(s=>{
  148.       ctx.globalAlpha = s.opacity;
  149.       ctx.beginPath();
  150.       ctx.arc(s.x, s.y, s.size, 0, Math.PI*2);
  151.       ctx.fill();
  152.       s.y += s.speed;
  153.       if(s.y > starCanvas.height) s.y = 0;
  154.     });
  155.     ctx.globalAlpha = 1;
  156.   }
  157.   setInterval(drawStars, 33);


  158.   // 控制飞机左右移动(键盘)
  159.   let keysPressed = {};
  160.   game.focus();
  161.   game.addEventListener("keydown", (e) => {
  162.     keysPressed[e.key.toLowerCase()] = true;
  163.     // 发射子弹空格键
  164.     if(e.key === " " || e.code === "Space") {
  165.       shootBullet();
  166.       e.preventDefault();
  167.     }
  168.   });

  169.   game.addEventListener("keyup", (e) => {
  170.     keysPressed[e.key.toLowerCase()] = false;
  171.   });

  172.   // 游戏操作循环检测按键并移动飞机
  173.   function handlePlayerMovement() {
  174.     if(isGameOver) return;

  175.     if(keysPressed["arrowleft"] || keysPressed["a"]) {
  176.       playerX -= 6;
  177.       if(playerX < 0) playerX = 0;
  178.     } else if(keysPressed["arrowright"] || keysPressed["d"]) {
  179.       playerX += 6;
  180.       if(playerX > gameWidth - playerWidth) playerX = gameWidth - playerWidth;
  181.     }
  182.     player.style.left = playerX + "px";
  183.   }

  184.   // 发射子弹,限制发射频率
  185.   let lastShootTime = 0;
  186.   function shootBullet() {
  187.     if(isGameOver) return;
  188.     let now = Date.now();
  189.     if(now - lastShootTime < 250) return;
  190.     lastShootTime = now;

  191.     const bullet = document.createElement("div");
  192.     bullet.classList.add("bullet");
  193.     bullet.style.left = (playerX + playerWidth / 2 - 4) + "px";
  194.     bullet.style.bottom = (playerHeight + 20) + "px";
  195.     game.appendChild(bullet);

  196.     bullets.push({
  197.       el: bullet,
  198.       x: playerX + playerWidth / 2 - 4,
  199.       y: playerHeight + 20,
  200.       width: 8,
  201.       height: 16,
  202.       speed: 9
  203.     });

  204.     playSound(shootSound);
  205.   }

  206.   // 创建敌机,速度和频率随着时间调整
  207.   function createEnemy() {
  208.     if(isGameOver) return;
  209.     const enemy = document.createElement("div");
  210.     enemy.classList.add("enemy");
  211.     const x = Math.random() * (gameWidth - 48);
  212.     enemy.style.left = x + "px";
  213.     enemy.style.top = "-48px";
  214.     game.appendChild(enemy);

  215.     enemies.push({
  216.       el: enemy,
  217.       x: x,
  218.       y: -48,
  219.       width: 48,
  220.       height: 48,
  221.       speed: enemySpeedBase + Math.random() * 1.5
  222.     });
  223.   }

  224.   // 爆炸特效动画
  225.   function showExplosion(x, y) {
  226.     const exp = document.createElement("div");
  227.     exp.classList.add("explosion");
  228.     exp.style.left = x + "px";
  229.     exp.style.top = y + "px";
  230.     game.appendChild(exp);

  231.     setTimeout(() => {
  232.       exp.remove();
  233.     }, 500);
  234.     playSound(explosionSound);
  235.   }

  236.   // 游戏主循环
  237.   function gameLoop() {
  238.     if(isGameOver) return;

  239.     handlePlayerMovement();

  240.     // 移动子弹
  241.     for(let i=bullets.length-1; i>=0; i--) {
  242.       let b = bullets[i];
  243.       b.y += b.speed;
  244.       if(b.y > gameHeight) {
  245.         // 超出屏幕移除
  246.         b.el.remove();
  247.         bullets.splice(i, 1);
  248.         continue;
  249.       }
  250.       b.el.style.bottom = b.y + "px";
  251.     }

  252.     // 移动敌机
  253.     for(let i=enemies.length-1; i>=0; i--) {
  254.       let en = enemies[i];
  255.       en.y += en.speed;
  256.       if(en.y > gameHeight) {
  257.         // 敌机到底部造成伤害
  258.         enemiesDamagePlayer(en);
  259.         en.el.remove();
  260.         enemies.splice(i, 1);
  261.         continue;
  262.       }
  263.       en.el.style.top = en.y + "px";
  264.     }

  265.     // 碰撞检测:子弹 & 敌机
  266.     for(let i=enemies.length-1; i>=0; i--) {
  267.       const en = enemies[i];
  268.       for(let j=bullets.length-1; j>=0; j--) {
  269.         const b = bullets[j];
  270.         if(rectCollision(en, b)) {
  271.           // 撞击爆炸,移除敌机和子弹
  272.           showExplosion(en.x, en.y);
  273.           en.el.remove();
  274.           b.el.remove();
  275.           enemies.splice(i, 1);
  276.           bullets.splice(j, 1);
  277.           addScore(1);
  278.           break;
  279.         }
  280.       }
  281.     }

  282.     // 碰撞检测:敌机 & 玩家
  283.     for(let i=enemies.length-1; i>=0; i--) {
  284.       const en = enemies[i];
  285.       if(rectCollision(en, {
  286.         x: playerX,
  287.         y: gameHeight - playerHeight - 20,
  288.         width: playerWidth,
  289.         height: playerHeight
  290.       })) {
  291.         // 敌机撞到飞机
  292.         enemiesDamagePlayer(en);
  293.         showExplosion(en.x, en.y);
  294.         en.el.remove();
  295.         enemies.splice(i, 1);
  296.       }
  297.     }

  298.     requestAnimationFrame(gameLoop);
  299.   }

  300.   // 矩形碰撞检测函数
  301.   function rectCollision(a, b) {
  302.     return !(
  303.       a.x > b.x + b.width ||
  304.       a.x + a.width < b.x ||
  305.       a.y > b.y + b.height ||
  306.       a.y + a.height < b.y
  307.     );
  308.   }

  309.   // 玩家受伤:扣血与状态闪烁
  310.   let damageCooldown = false;
  311.   function enemiesDamagePlayer(enemy) {
  312.     if(damageCooldown) return;
  313.     hp--;
  314.     hpDisplay.textContent = "❤".repeat(hp) + "♡".repeat(3 - hp);
  315.     player.classList.add("damaged");

  316.     playSound(hitSound);

  317.     setTimeout(() => {
  318.       player.classList.remove("damaged");
  319.       damageCooldown = false;
  320.     }, 300);
  321.     damageCooldown = true;

  322.     if(hp <= 0) {
  323.       endGame();
  324.     }
  325.   }

  326.   // 得分增加,同时提升难度
  327.   function addScore(amount) {
  328.     score += amount;
  329.     scoreBoard.innerHTML = `得分: ${score} <span id="hp">${"❤".repeat(hp) + "♡".repeat(3 - hp)}</span>`;

  330.     // 随着得分提高,提高敌机速度,降低刷新间隔,最高速和最大密度有限制
  331.     enemySpeedBase = Math.min(5, 2.5 + score * 0.1);
  332.     enemySpawnInterval = Math.max(500, 1300 - score * 20);

  333.     clearInterval(enemySpawner);
  334.     enemySpawner = setInterval(createEnemy, enemySpawnInterval);
  335.   }

  336.   // 游戏结束函数
  337.   function endGame() {
  338.     isGameOver = true;
  339.     alert(`游戏结束!你的最终得分是:${score}。感谢挑战!`);
  340.     window.location.reload();
  341.   }

  342.   // 初始启动创建敌机定时器
  343.   let enemySpawner = setInterval(createEnemy, enemySpawnInterval);

  344.   // 启动游戏循环
  345.   requestAnimationFrame(gameLoop);

  346.   // 声音相关
  347.   // 简单用Web Audio API做发声
  348.   const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

  349.   function playSound(buffer) {
  350.     if(!buffer) return;
  351.     const source = audioCtx.createBufferSource();
  352.     source.buffer = buffer;
  353.     source.connect(audioCtx.destination);
  354.     source.start(0);
  355.   }

  356.   // 使用fetch加载音效
  357.   let shootSound, explosionSound, hitSound;

  358.   function loadSounds() {
  359.     loadSound('https://cdn.jsdelivr.net/gh/fawazahmed0/cdn/sound/shoot.wav').then(b=>{
  360.       shootSound = b;
  361.     });
  362.     loadSound('https://cdn.jsdelivr.net/gh/fawazahmed0/cdn/sound/explosion.wav').then(b=>{
  363.       explosionSound = b;
  364.     });
  365.     loadSound('https://cdn.jsdelivr.net/gh/fawazahmed0/cdn/sound/hit.wav').then(b=>{
  366.       hitSound = b;
  367.     });
  368.   }
  369.   function loadSound(url) {
  370.     return fetch(url)
  371.       .then(r => r.arrayBuffer())
  372.       .then(arrayBuffer => audioCtx.decodeAudioData(arrayBuffer));
  373.   }
  374.   loadSounds();

  375. </script>
  376. </body>
  377. </html>
复制代码


---

### 说明:

- **漂亮图标**用的是免费的PNG图标链接,清晰而且有光影效果。
- **星空背景**用canvas画了小星星往下闪动,好像飞行在太空。
- **子弹、敌机、飞机**都加了发光和阴影,视觉更炫酷。
- **生命值**用3颗心表示,撞一次敌机扣一颗,还能继续战斗。
- **敌机速度和数量**会根据你得分慢慢增加,越打越刺激!
- **爆炸特效**是放一个帧动画图形,看上去炸掉敌机很爽。
- **音效**:开火、爆炸和受伤都有声音哦,要先点击页面一次激活声音。

---

试试看这个版本玩得怎么样!如果要改成手机触屏操作或加关卡,也可以告诉我,我帮你写~祝你游戏开心✈️????
回复 支持 反对

使用道具 举报

6

主题

16

帖子

48

积分

新手上路

Rank: 1

积分
48
5#
 楼主| 发表于 2025-12-2 14:20:54 | 只看该作者
将图片变得更漂亮,游戏更刺激,可以计分,会排名
回复 支持 反对

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
6#
发表于 2025-12-2 14:26:58 | 只看该作者
yue 发表于 2025-12-02 14:20
将图片变得更漂亮,游戏更刺激,可以计分,会排名 ...


你好!我帮你写了一个更漂亮、更刺激的飞机大战小游戏,支持计分和排名(排行榜会保存在浏览器里),这样你每次玩都能看到自己的分数排第几哦。下面是完整代码,你可以直接保存为`plane_game.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" />
  6. <title>超级飞机大战 - 带排行榜</title>
  7. <style>
  8.   /* 背景渐变和中心游戏区 */
  9.   body, html {
  10.     margin: 0; padding: 0; height: 100%;
  11.     background: linear-gradient(to bottom, #00111f, #000);
  12.     font-family: "微软雅黑", sans-serif;
  13.     overflow: hidden;
  14.     user-select: none;
  15.   }
  16.   #game {
  17.     position: relative;
  18.     width: 400px;
  19.     height: 600px;
  20.     margin: 20px auto;
  21.     background: linear-gradient(to bottom, #002240, #000010);
  22.     border-radius: 15px;
  23.     box-shadow: 0 0 20px #0af;
  24.     overflow: hidden;
  25.   }

  26.   /* 飞机 */
  27.   #player {
  28.     position: absolute;
  29.     width: 50px;
  30.     height: 50px;
  31.     bottom: 15px;
  32.     left: 175px;
  33.     background: url('https://cdn-icons-png.flaticon.com/512/6326/6326193.png') no-repeat center / contain;
  34.     filter: drop-shadow(0 0 5px #0ff);
  35.     transition: filter 0.2s;
  36.     z-index: 10;
  37.   }
  38.   #player.damaged {
  39.     filter: drop-shadow(0 0 13px red);
  40.   }

  41.   /* 子弹 */
  42.   .bullet {
  43.     position: absolute;
  44.     width: 10px;
  45.     height: 20px;
  46.     background: linear-gradient(90deg, #00ffff, #006677);
  47.     border-radius: 5px;
  48.     filter: drop-shadow(0 0 6px #0ff);
  49.     z-index: 9;
  50.   }

  51.   /* 敌机 */
  52.   .enemy {
  53.     position: absolute;
  54.     width: 50px;
  55.     height: 50px;
  56.     background: url('https://cdn-icons-png.flaticon.com/512/616/616489.png') no-repeat center / contain;
  57.     filter: drop-shadow(0 0 7px #f44);
  58.     transition: transform 0.15s ease;
  59.     z-index: 8;
  60.   }
  61.   .enemy.damaged {
  62.     transform: scale(1.2);
  63.   }

  64.   /* 爆炸动画 */
  65.   .explosion {
  66.     position: absolute;
  67.     width: 60px;
  68.     height: 60px;
  69.     background: url('https://i.ibb.co/1rvdWgF/explosion.png') no-repeat center / contain;
  70.     animation: explode 0.5s ease forwards;
  71.     pointer-events: none;
  72.     z-index: 20;
  73.   }
  74.   @keyframes explode {
  75.     0% {opacity: 1; transform: scale(1);}
  76.     100% {opacity: 0; transform: scale(1.8);}
  77.   }

  78.   /* 顶部状态栏 */
  79.   #infoBar {
  80.     color: #0ff;
  81.     text-align: center;
  82.     font-size: 20px;
  83.     letter-spacing: 2px;
  84.     margin-top: 10px;
  85.     user-select:none;
  86.   }
  87.   #hp {
  88.     color: #f44;
  89.     font-weight: bold;
  90.     margin-left: 20px;
  91.   }

  92.   /* 排行榜弹窗 */
  93.   #rankOverlay {
  94.     display: none;
  95.     position: fixed;
  96.     top: 0; left: 0; right: 0; bottom: 0;
  97.     background: rgba(0,0,0,0.75);
  98.     z-index: 50;
  99.     justify-content: center;
  100.     align-items: center;
  101.   }
  102.   #rankBox {
  103.     background: #002a4e;
  104.     padding: 20px 30px;
  105.     border-radius: 12px;
  106.     width: 320px;
  107.     max-height: 80vh;
  108.     overflow-y: auto;
  109.     color: #0ff;
  110.   }
  111.   #rankBox h2 {
  112.     margin-top: 0;
  113.     text-align: center;
  114.   }
  115.   #rankList {
  116.     margin-top: 10px;
  117.   }
  118.   #rankList li {
  119.     line-height: 1.6em;
  120.     font-size: 18px;
  121.   }
  122.   #closeRankBtn {
  123.     display: block;
  124.     margin: 15px auto 0;
  125.     background: #0ff;
  126.     border: none;
  127.     padding: 10px 20px;
  128.     border-radius: 8px;
  129.     cursor: pointer;
  130.     font-weight: bold;
  131.     color: #002a4e;
  132.     transition: background-color 0.3s;
  133.   }
  134.   #closeRankBtn:hover {
  135.     background: #06e;
  136.     color: white;
  137.   }

  138.   /* 提示文字 */
  139.   #tip {
  140.     text-align: center;
  141.     color: #08f;
  142.     font-size: 14px;
  143.     margin-bottom: 4px;
  144.   }
  145. </style>
  146. </head>
  147. <body>

  148. <div id="tip">左右方向键或A/D移动,空格发射子弹</div>
  149. <div id="game" tabindex="0">
  150.   <div id="player"></div>
  151. </div>
  152. <div id="infoBar">得分: 0 <span id="hp">❤❤❤</span></div>

  153. <!-- 排行榜弹窗 -->
  154. <div id="rankOverlay">
  155.   <div id="rankBox">
  156.     <h2>排行榜 Top 10</h2>
  157.     <ol id="rankList"></ol>
  158.     <button id="closeRankBtn">关闭</button>
  159.   </div>
  160. </div>

  161. <script>
  162. (() => {
  163.   const game = document.getElementById('game');
  164.   const player = document.getElementById('player');
  165.   const scoreBoard = document.getElementById('infoBar');
  166.   const hpDisplay = document.getElementById('hp');
  167.   const rankOverlay = document.getElementById('rankOverlay');
  168.   const rankList = document.getElementById('rankList');
  169.   const closeRankBtn = document.getElementById('closeRankBtn');

  170.   const gameWidth = game.clientWidth;
  171.   const gameHeight = game.clientHeight;

  172.   let playerX = (gameWidth - player.clientWidth) / 2;
  173.   const playerWidth = player.clientWidth;
  174.   const playerHeight = player.clientHeight;

  175.   let bullets = [];
  176.   let enemies = [];

  177.   let score = 0;
  178.   let hp = 3;
  179.   let isGameOver = false;

  180.   // 敌机速度和生成间隔随分数增长
  181.   let enemySpeedBase = 2.5;
  182.   let enemySpawnInterval = 1300;

  183.   // 控制发射频率,避免按着空格连发太快
  184.   let lastShootTime = 0;
  185.   const shootCooldown = 250;

  186.   // 控制玩家移动状态
  187.   let movingLeft = false;
  188.   let movingRight = false;

  189.   // 初始化位置
  190.   player.style.left = playerX + 'px';

  191.   // 键盘事件监听
  192.   window.addEventListener('keydown', (e) => {
  193.     if (isGameOver) return;
  194.     if (e.code === "ArrowLeft" || e.key.toLowerCase() === 'a') {
  195.       movingLeft = true;
  196.     } else if (e.code === "ArrowRight" || e.key.toLowerCase() === 'd') {
  197.       movingRight = true;
  198.     } else if (e.code === "Space") {
  199.       e.preventDefault();
  200.       shootBullet();
  201.     }
  202.   });
  203.   window.addEventListener('keyup', (e) => {
  204.     if (e.code === "ArrowLeft" || e.key.toLowerCase() === 'a') {
  205.       movingLeft = false;
  206.     } else if (e.code === "ArrowRight" || e.key.toLowerCase() === 'd') {
  207.       movingRight = false;
  208.     }
  209.   });

  210.   // 发射子弹
  211.   function shootBullet(){
  212.     if(isGameOver) return;
  213.     const now = Date.now();
  214.     if(now - lastShootTime < shootCooldown) return;
  215.     lastShootTime = now;

  216.     const bullet = document.createElement('div');
  217.     bullet.className = 'bullet';
  218.     const startX = playerX + playerWidth/2 - 5;
  219.     const startY = playerHeight + 15;
  220.     bullet.style.left = startX + 'px';
  221.     bullet.style.bottom = startY + 'px';
  222.     game.appendChild(bullet);

  223.     bullets.push({
  224.       el: bullet,
  225.       x: startX,
  226.       y: startY,
  227.       width: 10,
  228.       height: 20,
  229.       speed: 10
  230.     });
  231.   }

  232.   // 创建敌机,随机横向
  233.   function createEnemy() {
  234.     if(isGameOver) return;
  235.     const enemy = document.createElement('div');
  236.     enemy.className = 'enemy';
  237.     const x = Math.random() * (gameWidth - 50);
  238.     enemy.style.left = x + 'px';
  239.     enemy.style.top = '-50px';
  240.     game.appendChild(enemy);

  241.     enemies.push({
  242.       el: enemy,
  243.       x: x,
  244.       y: -50,
  245.       width: 50,
  246.       height: 50,
  247.       speed: enemySpeedBase + Math.random() * 1.5
  248.     });
  249.   }

  250.   // 爆炸动画效果
  251.   function showExplosion(x, y) {
  252.     const exp = document.createElement('div');
  253.     exp.className = 'explosion';
  254.     exp.style.left = (x - 5) + 'px';
  255.     exp.style.top = (y - 5) + 'px';
  256.     game.appendChild(exp);
  257.     setTimeout(() => {
  258.       exp.remove();
  259.     }, 500);
  260.   }

  261.   // 分数增加后调整敌机速度和生成频率
  262.   function levelUp() {
  263.     enemySpeedBase = 2.5 + score*0.1;
  264.     enemySpawnInterval = Math.max(600, 1300 - score*15);
  265.   }

  266.   // 矩形碰撞检测
  267.   function rectCollide(a, b){
  268.     return !(
  269.       a.x > b.x + b.width ||
  270.       a.x + a.width < b.x ||
  271.       a.y > b.y + b.height ||
  272.       a.y + a.height < b.y
  273.     );
  274.   }

  275.   // 玩家受伤处理
  276.   function playerHit() {
  277.     if (isGameOver) return;
  278.     hp--;
  279.     updateHpDisplay();
  280.     // 加个红色闪烁提示
  281.     player.classList.add('damaged');
  282.     setTimeout(() => player.classList.remove('damaged'), 300);

  283.     if (hp <= 0) {
  284.       gameOver();
  285.     }
  286.   }

  287.   // 更新生命显示
  288.   function updateHpDisplay(){
  289.     hpDisplay.textContent = '❤'.repeat(hp) + '♡'.repeat(3 - hp);
  290.   }

  291.   // 游戏结束:弹出输入名字界面并展示排行榜
  292.   function gameOver(){
  293.     isGameOver = true;
  294.     setTimeout(() => {
  295.       const name = prompt("游戏结束!你的得分:" + score + "\n请输入你的名字(不超过10字):", "玩家");
  296.       if(name!==null){
  297.         saveScore(name.trim().substring(0,10), score);
  298.       }
  299.       showRanking();
  300.     }, 100);
  301.   }

  302.   // 保存分数到本地localStorage里
  303.   function saveScore(name, score){
  304.     const rankData = JSON.parse(localStorage.getItem('planeRank') || '[]');
  305.     rankData.push({name, score});
  306.     // 按分数倒序排序
  307.     rankData.sort((a,b) => b.score - a.score);
  308.     // 只保留前20条
  309.     localStorage.setItem('planeRank', JSON.stringify(rankData.slice(0,20)));
  310.   }

  311.   // 显示排行榜弹窗
  312.   function showRanking(){
  313.     rankList.innerHTML = '';
  314.     const rankData = JSON.parse(localStorage.getItem('planeRank') || '[]');
  315.     const len = Math.min(10, rankData.length);
  316.     if(len === 0){
  317.       rankList.innerHTML = '<li>暂无排名数据</li>';
  318.     } else {
  319.       for(let i=0; i<len; i++){
  320.         const r = rankData[i];
  321.         const li = document.createElement('li');
  322.         li.textContent = `${i+1}. ${r.name} — ${r.score}分`;
  323.         rankList.appendChild(li);
  324.       }
  325.     }
  326.     rankOverlay.style.display = 'flex';
  327.   }
  328.   closeRankBtn.addEventListener('click', () => {
  329.     rankOverlay.style.display = 'none';
  330.     restartGame();
  331.   });

  332.   // 重置游戏数据,重新开始
  333.   function restartGame(){
  334.     // 清除所有敌机和子弹
  335.     bullets.forEach(b => b.el.remove());
  336.     enemies.forEach(e => e.el.remove());
  337.     bullets = [];
  338.     enemies = [];
  339.     score = 0;
  340.     hp = 3;
  341.     isGameOver = false;
  342.     updateHpDisplay();
  343.     updateScoreDisplay();
  344.     playerX = (gameWidth - playerWidth)/2;
  345.     player.style.left = playerX + 'px';
  346.     enemySpeedBase = 2.5;
  347.     enemySpawnInterval = 1300;
  348.   }

  349.   // 更新分数显示
  350.   function updateScoreDisplay(){
  351.     scoreBoard.childNodes[0].textContent = '得分: ' + score + ' ';
  352.   }

  353.   // 游戏主循环
  354.   let lastSpawnTime = 0;
  355.   function gameLoop(time=0){
  356.     if(isGameOver){
  357.       requestAnimationFrame(gameLoop);
  358.       return;
  359.     }

  360.     // 移动玩家
  361.     if(movingLeft){
  362.       playerX -= 6;
  363.       if(playerX < 0) playerX = 0;
  364.     }
  365.     if(movingRight){
  366.       playerX += 6;
  367.       if(playerX > gameWidth - playerWidth) playerX = gameWidth - playerWidth;
  368.     }
  369.     player.style.left = playerX + 'px';

  370.     // 移动子弹
  371.     for(let i=bullets.length-1; i>=0; i--){
  372.       let b = bullets[i];
  373.       b.y += b.speed;
  374.       if(b.y > gameHeight){
  375.         b.el.remove();
  376.         bullets.splice(i, 1);
  377.         continue;
  378.       }
  379.       b.el.style.bottom = b.y + 'px';
  380.     }

  381.     // 移动敌机
  382.     for(let i=enemies.length-1; i>=0; i--){
  383.       let en = enemies[i];
  384.       en.y += en.speed;
  385.       if(en.y > gameHeight){
  386.         // 到底部后对玩家造成伤害
  387.         playerHit();
  388.         en.el.remove();
  389.         enemies.splice(i, 1);
  390.         continue;
  391.       }
  392.       en.el.style.top = en.y + 'px';
  393.     }

  394.     // 碰撞检测:子弹和敌机
  395.     for(let i=enemies.length-1; i>=0; i--){
  396.       const en = enemies[i];
  397.       for(let j=bullets.length-1; j>=0; j--){
  398.         const b = bullets[j];
  399.         // 注意坐标系:敌机用top定位,y是距离上边;子弹用bottom定位,y是距离底部
  400.         // 为了简化,我们用相对于容器顶端的坐标计算,子弹y换算:
  401.         const bulletTop = gameHeight - b.y - b.height;
  402.         if(rectCollide(
  403.           {x: en.x, y: en.y, width: en.width, height: en.height},
  404.           {x: b.x, y: bulletTop, width: b.width, height: b.height}
  405.         )){
  406.           // 击中敌机
  407.           showExplosion(en.x, en.y);
  408.           en.el.remove();
  409.           b.el.remove();
  410.           enemies.splice(i, 1);
  411.           bullets.splice(j, 1);
  412.           score++;
  413.           updateScoreDisplay();
  414.           levelUp();
  415.           break;
  416.         }
  417.       }
  418.     }

  419.     // 碰撞检测:敌机和玩家
  420.     for(let i=enemies.length-1; i>=0; i--){
  421.       const en = enemies[i];
  422.       const playerTop = gameHeight - playerHeight - 15;
  423.       if(rectCollide(
  424.         {x: en.x, y: en.y, width: en.width, height: en.height},
  425.         {x: playerX, y: playerTop, width: playerWidth, height: playerHeight}
  426.       )){
  427.         playerHit();
  428.         showExplosion(en.x, en.y);
  429.         en.el.remove();
  430.         enemies.splice(i, 1);
  431.         break;
  432.       }
  433.     }

  434.     // 生成新敌机
  435.     if(time - lastSpawnTime > enemySpawnInterval){
  436.       createEnemy();
  437.       lastSpawnTime = time;
  438.     }

  439.     requestAnimationFrame(gameLoop);
  440.   }

  441.   // 入口:开始游戏
  442.   updateHpDisplay();
  443.   updateScoreDisplay();
  444.   game.focus();
  445.   requestAnimationFrame(gameLoop);

  446. })();
  447. </script>
  448. </body>
  449. </html>
复制代码


---

### 玩法说明:

- 用 **左右箭头** 或者 **A、D 键** 控制飞机左右移动。
- 按空格键发射子弹。
- 敌机会从顶部出现,往下飞。
- 子弹击中敌机得分,得分越高,敌机飞得越快,出现越频繁。
- 敌机撞到飞机或到达底部会扣一颗❤,生命值耗尽游戏结束。
- 游戏结束时会弹出输入框让你输名字保存分数,并显示排行榜前十名。
- 你可以关闭排行榜继续游戏,或者刷新页面重新开始。

---

### 图片说明:

- 飞机和敌机用的是高清PNG图标,带光影和投影效果,看起来更立体好看。
- 爆炸是一个小动画图片,让战斗过程更有感觉。

---

这个程序纯前端,不需要服务器,可以保存多次游戏分数,用浏览器本地存储保持排行榜。如果打开沙盒限制导致无法保存,可以换成Chrome或其他现代浏览器试试看。

有什么想改进的,随时告诉我,帮你优化!祝你游戏开心,打败所有敌机吧!✈️????????
回复 支持 反对

使用道具 举报

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

本版积分规则

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