🐵指尖猴全新升级
第22课:飞机大战
🛸

飞机大战

两个列表撑起一片枪林弹雨

📖知识引入

🛸敌机从天而降
每隔一段时间,在顶部随机位置「刷」出一架敌机,让它往下飞。飞出屏幕底部就删掉——这就是敌机的生老病死。
🔫子弹也是列表
按空格生成一颗子弹往上飞。游戏里同时存在几十颗子弹?那就是列表里有几十个坐标,每帧各自+速度往上挪,完全不怕。
🌊波次让玩家喘气
好游戏不是敌人无限刷新:第一波3架慢敌机,清完歇两秒,第二波5架快敌机……张弛有度,比一直狂轰滥炸好玩十倍。
💥命中三连击
子弹碰到敌机:敌机爆炸(换爆炸图+音效)、分数入账、子弹消失。碰撞检测(子弹列表×敌机列表)一秒跑60遍,弹幕全靠它。
🤖AI实战节奏
先要「一架敌机+一颗子弹」的最小版本跑通,再让AI加:敌机列表、波次系统、Boss、道具。小步快跑,每步都能玩。
💡
射击游戏的心脏:一个装子弹的列表 × 一个装敌机的列表!

🔍弹幕背后的真相

// 飞机大战核心:两个列表的战斗
let enemies = [];   // 敌机列表
let bullets = [];   // 子弹列表

// 定时刷新敌机:顶部随机位置
setInterval(() => {
  enemies.push({ x: Math.random() * 360, y: -30 });
}, 800);

function update() {
  // 子弹上飞、敌机下飞
  bullets.forEach(b => b.y -= 8);
  enemies.forEach(e => e.y += 2);

  // 两两配对做碰撞检测
  for (let e of enemies) {
    for (let b of bullets) {
      if (isCrash(e, b)) {
        e.dead = true;          // 敌机爆炸
        b.dead = true;          // 子弹消失
        score += 10;            // 分数入账
        playSound('轰!');       // 音效反馈
      }
    }
  }

  // 清理阵亡的和飞出屏幕的
  enemies = enemies.filter(e => !e.dead && e.y < 520);
  bullets = bullets.filter(b => !b.dead && b.y > -20);
}

屏幕上热闹的空战, 数据里只有两个列表在跳舞:

敌机列表                子弹列表
┌──────────┐          ┌──────────┐
│ (120, 40) │          │ (150,300) │
│ (260, 80) │   ✈️     │ (150,250) │
│ ( 60,150) │   ↑碰撞↑ │ ( 90,200) │
│ (300, 30) │          │ (210,180) │
└──────────┘          └──────────┘
每帧发生的事:
1. 每架敌机 y += 2 (往下飞)
2. 每颗子弹 y -= 8 (往上飞)
3. 双重循环两两配对做碰撞检测
4. 撞上了:敌机爆、子弹删、加分
5. 飞出屏幕的统统删掉

波次设计示意:

第1波 ▷▷▷ 3架慢速 (清空)休息2秒 第2波 ▷▷▷▷▷ 5架中速 (清空)休息2秒 第3波 👾 Boss登场!

给AI的启动提示词:

「用网页JS做飞机大战:
方向键移动,空格发射子弹,
敌机从顶部随机出现往下飞,
子弹击中敌机+10分,
敌机撞到飞机扣1条命,
共3条命。」

🎯小测验

第1题:游戏里几十颗子弹同时飞,程序里其实是?

第2题:「打完一波休息两秒再来下一波」这种设计叫?

第3题:让AI做飞机大战,明智的顺序是?

📝本课知识点

  • ✓敌机与子弹都是列表管理
  • ✓随机刷新+出界清理
  • ✓波次设计:张弛有度
  • ✓命中三连:爆炸+加分+消弹
  • ✓AI实战:最小版本先跑通
第22课完成!继续探索下一课吧 🚀