소스 검색

关卡优化 初版本 v1.0.1

wenxianchao 1 개월 전
부모
커밋
223067cd20
2개의 변경된 파일46개의 추가작업 그리고 11개의 파일을 삭제
  1. 43 8
      assets/scripts/SteelAssaultGame.ts
  2. 3 3
      profiles/v2/packages/builder.json

+ 43 - 8
assets/scripts/SteelAssaultGame.ts

@@ -138,6 +138,8 @@ export class SteelAssaultGame extends Component {
   private score = 0;
   private state: 'playing' | 'win' | 'next' | 'lose' = 'playing';
   private bossTime = 0;
+  private bossEnrageAnnounced = false;
+  private bossRoarTimer = 0;
   private elapsed = 0;
   private spritesReady = false;
   private heroSprite: Sprite | null = null;
@@ -271,7 +273,7 @@ export class SteelAssaultGame extends Component {
     this.node.addChild(musicNode);
     this.musicSource = musicNode.addComponent(AudioSource);
     this.musicSource.loop = true;
-    this.musicSource.volume = 0.22;
+    this.musicSource.volume = 0.34;
 
     const sfxNode = new Node('RuntimeSfx');
     sfxNode.layer = Layers.Enum.UI_2D;
@@ -653,7 +655,7 @@ if (!this.backgroundSprite) return;
     if (!clip) return;
     this.musicSource.clip = clip;
     this.musicSource.loop = true;
-    this.musicSource.volume = 0.22;
+    this.musicSource.volume = 0.34;
     this.musicSource.play();
     this.musicStarted = true;
   }
@@ -664,6 +666,25 @@ if (!this.backgroundSprite) return;
     this.sfxSource.playOneShot(clip, volume);
   }
 
+  private updateBossEnrageAudio(enraged: boolean, dt: number) {
+    if (!enraged) {
+      this.bossEnrageAnnounced = false;
+      this.bossRoarTimer = 0;
+      return;
+    }
+    if (!this.bossEnrageAnnounced) {
+      this.playSfx('boss_alert', 1.0);
+      this.bossEnrageAnnounced = true;
+      this.bossRoarTimer = 1.8;
+      return;
+    }
+    this.bossRoarTimer -= dt;
+    if (this.bossRoarTimer <= 0) {
+      this.playSfx('boss_alert', 0.86);
+      this.bossRoarTimer = 2.4;
+    }
+  }
+
   private updatePlayer(dt: number) {
     this.previousPlayerY = this.player.y;
     const left = this.keys.has(KeyCode.KEY_A) || this.keys.has(KeyCode.ARROW_LEFT);
@@ -770,6 +791,7 @@ if (!this.backgroundSprite) return;
         enemy.y = BOSS_Y + Math.sin(this.bossTime * 1.1) * U(10);
         const hpRatio = enemy.hp / enemy.maxHp;
         const phase = hpRatio <= BOSS_ENRAGE_RATIO ? 3 : hpRatio <= BOSS_PHASE_TWO_RATIO ? 2 : 1;
+        this.updateBossEnrageAudio(phase >= 3, dt);
         if (enemy.cd <= 0 && this.canEnemyShoot(enemy, U(980))) {
           const shotX = enemy.x - U(115);
           const targetX = this.player.x;
@@ -1249,7 +1271,10 @@ if (!this.backgroundSprite) return;
       const face = enemy.type === 'spore'
         ? (enemy.x > this.player.x ? 1 : -1)
         : (enemy.x > this.player.x ? -1 : 1);
-      const scale = enemy.type === 'boss' ? US(1.06) : enemy.type === 'turret' ? US(0.44) : enemy.type === 'wing' ? US(0.41) : US(0.51);
+      const bossEnraged = enemy.type === 'boss' && enemy.hp <= enemy.maxHp * BOSS_ENRAGE_RATIO;
+      const scale = enemy.type === 'boss'
+        ? (bossEnraged ? US(1.42) : US(1.24))
+        : enemy.type === 'turret' ? US(0.44) : enemy.type === 'wing' ? US(0.41) : US(0.51);
       sprite.node.setScale(new Vec3(scale * face, scale, 1));
       sprite.node.active = true;
     }
@@ -1477,26 +1502,30 @@ if (!this.backgroundSprite) return;
   }
 
   private handleOutcomeAction(event: EventTouch | EventMouse) {
-    const { x, y } = this.pointerToWorldPoint(event);
+    const points = this.pointerWorldPointCandidates(event);
     if (this.state === 'win') {
-      if (this.pointInRect(x, y, this.outcomeNextRect())) {
+      if (this.anyPointInRect(points, this.outcomeNextRect())) {
         this.state = 'next';
         this.clearMobileControls();
         return true;
       }
-      if (this.pointInRect(x, y, this.outcomeRestartRect())) {
+      if (this.anyPointInRect(points, this.outcomeRestartRect())) {
         this.reset();
         return true;
       }
       return false;
     }
-    if ((this.state === 'lose' || this.state === 'next') && this.pointInRect(x, y, this.outcomeSingleRestartRect())) {
+    if ((this.state === 'lose' || this.state === 'next') && this.anyPointInRect(points, this.outcomeSingleRestartRect())) {
       this.reset();
       return true;
     }
     return false;
   }
 
+  private anyPointInRect(points: Array<{ x: number; y: number }>, rect: UiRect) {
+    return points.some((point) => this.pointInRect(point.x, point.y, rect));
+  }
+
   private pointInRect(x: number, y: number, rect: UiRect) {
     return x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height;
   }
@@ -1793,8 +1822,12 @@ if (!this.backgroundSprite) return;
 
   private onMouseDown(event: EventMouse) {
     if (event.getButton() !== EventMouse.BUTTON_LEFT) return;
-    if (this.state !== 'playing') return;
     this.unlockAudio();
+    if (this.isOutcomeState()) {
+      if (this.handleOutcomeAction(event)) this.stopTouchEvent(event);
+      return;
+    }
+    if (this.state !== 'playing') return;
     this.handlePointerStart(-1, event);
   }
 
@@ -2040,6 +2073,8 @@ private switchButtonCenter() {
     this.score = 0;
     this.state = 'playing';
     this.bossTime = 0;
+    this.bossEnrageAnnounced = false;
+    this.bossRoarTimer = 0;
     this.elapsed = 0;
     for (const sprite of this.enemySprites.values()) sprite.node.destroy();
     for (const sprite of this.bulletSprites.values()) sprite.node.destroy();

+ 3 - 3
profiles/v2/packages/builder.json

@@ -24,8 +24,8 @@
         "progress": 1,
         "state": "success",
         "stage": "build",
-        "message": "2026-5-21 15:58:46 build success in 12 s!",
-        "detailMessage": "// ---- build task 整理静态模板文件 ----\r",
+        "message": "2026-5-21 16:36:37 build success in 21 s!",
+        "detailMessage": "// ---- build task wechatgame:onAfterBuild ----\r",
         "options": {
           "name": "steel-assault-rift",
           "server": "",
@@ -90,7 +90,7 @@
           "__version__": "1.3.9",
           "logDest": "project://temp/builder/log/wechatgame2026-5-21 15-58.log"
         },
-        "time": "2026-5-21 15:58:34",
+        "time": "2026-5-21 16:36:15",
         "dirty": false
       }
     }