|
|
@@ -1,11 +1,12 @@
|
|
|
-import { _decorator, Node, Label, Vec3, Prefab, instantiate, find, UITransform, resources } from 'cc';
|
|
|
+import { _decorator, Node, Label, Vec3, Prefab, instantiate, find, UITransform, resources, RigidBody2D } from 'cc';
|
|
|
import { sp } from 'cc';
|
|
|
import { ConfigManager, EnemyConfig } from '../Core/ConfigManager';
|
|
|
import { EnemyComponent } from '../CombatSystem/EnemyComponent';
|
|
|
import { EnemyInstance } from './EnemyInstance';
|
|
|
import { BaseSingleton } from '../Core/BaseSingleton';
|
|
|
import { SaveDataManager } from '../LevelSystem/SaveDataManager';
|
|
|
-import { GameManager } from '../LevelSystem/GameManager';
|
|
|
+import { GamePause } from './GamePause';
|
|
|
+import EventBus, { GameEvents } from '../Core/EventBus';
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
|
|
// 前向声明EnemyInstance类型,避免循环引用
|
|
|
@@ -79,9 +80,6 @@ export class EnemyController extends BaseSingleton {
|
|
|
// 墙体节点
|
|
|
private wallNodes: Node[] = [];
|
|
|
|
|
|
- // 私有属性
|
|
|
- private gameManager: any = null;
|
|
|
-
|
|
|
// 配置管理器
|
|
|
private configManager: ConfigManager = null;
|
|
|
|
|
|
@@ -108,6 +106,14 @@ export class EnemyController extends BaseSingleton {
|
|
|
private currentWaveTotalEnemies: number = 0;
|
|
|
private currentWaveEnemiesKilled: number = 0;
|
|
|
|
|
|
+ // 暂停前保存的敌人状态
|
|
|
+ private pausedEnemyStates: Map<Node, {
|
|
|
+ velocity: any,
|
|
|
+ angularVelocity: number,
|
|
|
+ isMoving: boolean,
|
|
|
+ attackTimer: number
|
|
|
+ }> = new Map();
|
|
|
+
|
|
|
/**
|
|
|
* BaseSingleton 首次实例化回调
|
|
|
*/
|
|
|
@@ -139,9 +145,6 @@ export class EnemyController extends BaseSingleton {
|
|
|
|
|
|
// 确保enemyContainer节点存在
|
|
|
this.ensureEnemyContainer();
|
|
|
-
|
|
|
- // 查找GameManager
|
|
|
- this.findGameManager();
|
|
|
|
|
|
// 如果没有指定enemyCountLabelNode,尝试找到它
|
|
|
if (!this.enemyCountLabelNode) {
|
|
|
@@ -155,6 +158,133 @@ export class EnemyController extends BaseSingleton {
|
|
|
}
|
|
|
// 初始化敌人数量显示
|
|
|
this.updateEnemyCountLabel();
|
|
|
+
|
|
|
+ // 监听游戏事件
|
|
|
+ this.setupEventListeners();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置事件监听器
|
|
|
+ */
|
|
|
+ private setupEventListeners() {
|
|
|
+ const eventBus = EventBus.getInstance();
|
|
|
+
|
|
|
+ // 监听暂停事件
|
|
|
+ eventBus.on(GameEvents.GAME_PAUSE, this.onGamePauseEvent, this);
|
|
|
+
|
|
|
+ // 监听恢复事件
|
|
|
+ eventBus.on(GameEvents.GAME_RESUME, this.onGameResumeEvent, this);
|
|
|
+
|
|
|
+ // 监听游戏成功/失败事件
|
|
|
+ eventBus.on(GameEvents.GAME_SUCCESS, this.onGameEndEvent, this);
|
|
|
+ eventBus.on(GameEvents.GAME_DEFEAT, this.onGameEndEvent, this);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理游戏暂停事件
|
|
|
+ */
|
|
|
+ private onGamePauseEvent() {
|
|
|
+ console.log('[EnemyController] 接收到游戏暂停事件,暂停所有敌人');
|
|
|
+ this.pauseAllEnemies();
|
|
|
+ this.pauseSpawning();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理游戏恢复事件
|
|
|
+ */
|
|
|
+ private onGameResumeEvent() {
|
|
|
+ console.log('[EnemyController] 接收到游戏恢复事件,恢复所有敌人');
|
|
|
+ this.resumeAllEnemies();
|
|
|
+
|
|
|
+ // 检查游戏是否已经结束,如果结束则不恢复敌人生成
|
|
|
+ const gamePause = GamePause.getInstance();
|
|
|
+ if (!gamePause.isGameOver()) {
|
|
|
+ this.resumeSpawning();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理游戏结束事件
|
|
|
+ */
|
|
|
+ private onGameEndEvent() {
|
|
|
+ console.log('[EnemyController] 接收到游戏结束事件,停止敌人生成');
|
|
|
+ this.stopGame(false); // 停止游戏但不清除敌人
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 暂停所有敌人
|
|
|
+ */
|
|
|
+ private pauseAllEnemies(): void {
|
|
|
+ const activeEnemies = this.getActiveEnemies();
|
|
|
+
|
|
|
+ for (const enemy of activeEnemies) {
|
|
|
+ if (!enemy || !enemy.isValid) continue;
|
|
|
+
|
|
|
+ // 保存敌人状态
|
|
|
+ const rigidBody = enemy.getComponent(RigidBody2D);
|
|
|
+ if (rigidBody) {
|
|
|
+ this.pausedEnemyStates.set(enemy, {
|
|
|
+ velocity: rigidBody.linearVelocity.clone(),
|
|
|
+ angularVelocity: rigidBody.angularVelocity,
|
|
|
+ isMoving: true,
|
|
|
+ attackTimer: 0 // 可以扩展保存攻击计时器
|
|
|
+ });
|
|
|
+
|
|
|
+ // 停止敌人运动
|
|
|
+ rigidBody.linearVelocity.set(0, 0);
|
|
|
+ rigidBody.angularVelocity = 0;
|
|
|
+ rigidBody.sleep();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 暂停敌人AI组件(如果有的话)
|
|
|
+ const enemyAI = enemy.getComponent('EnemyAI');
|
|
|
+ if (enemyAI && typeof (enemyAI as any).pause === 'function') {
|
|
|
+ (enemyAI as any).pause();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 暂停敌人动画(如果有的话)
|
|
|
+ const animation = enemy.getComponent('Animation');
|
|
|
+ if (animation && typeof (animation as any).pause === 'function') {
|
|
|
+ (animation as any).pause();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 恢复所有敌人
|
|
|
+ */
|
|
|
+ private resumeAllEnemies(): void {
|
|
|
+ const activeEnemies = this.getActiveEnemies();
|
|
|
+
|
|
|
+ for (const enemy of activeEnemies) {
|
|
|
+ if (!enemy || !enemy.isValid) continue;
|
|
|
+
|
|
|
+ const savedState = this.pausedEnemyStates.get(enemy);
|
|
|
+ if (savedState) {
|
|
|
+ const rigidBody = enemy.getComponent(RigidBody2D);
|
|
|
+ if (rigidBody) {
|
|
|
+ // 恢复敌人运动
|
|
|
+ rigidBody.wakeUp();
|
|
|
+ rigidBody.linearVelocity = savedState.velocity;
|
|
|
+ rigidBody.angularVelocity = savedState.angularVelocity;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 恢复敌人AI组件
|
|
|
+ const enemyAI = enemy.getComponent('EnemyAI');
|
|
|
+ if (enemyAI && typeof (enemyAI as any).resume === 'function') {
|
|
|
+ (enemyAI as any).resume();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 恢复敌人动画
|
|
|
+ const animation = enemy.getComponent('Animation');
|
|
|
+ if (animation && typeof (animation as any).resume === 'function') {
|
|
|
+ (animation as any).resume();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清空保存的状态
|
|
|
+ this.pausedEnemyStates.clear();
|
|
|
}
|
|
|
|
|
|
// 计算游戏区域边界
|
|
|
@@ -251,7 +381,8 @@ export class EnemyController extends BaseSingleton {
|
|
|
// 游戏开始
|
|
|
startGame() {
|
|
|
// 检查游戏是否已经结束,如果结束则不开始生成敌人
|
|
|
- if (this.gameManager && typeof this.gameManager.isGameOver === 'function' && this.gameManager.isGameOver()) {
|
|
|
+ const gamePause = GamePause.getInstance();
|
|
|
+ if (gamePause.isGameOver()) {
|
|
|
console.log('[EnemyController] 游戏已经结束,不启动敌人生成');
|
|
|
return;
|
|
|
}
|
|
|
@@ -277,7 +408,8 @@ export class EnemyController extends BaseSingleton {
|
|
|
// 只有在指定时才清除所有敌人
|
|
|
if (clearEnemies) {
|
|
|
// 当游戏结束时清除敌人,不触发敌人死亡事件
|
|
|
- const isGameOver = this.gameManager && typeof this.gameManager.isGameOver === 'function' && this.gameManager.isGameOver();
|
|
|
+ const gamePause = GamePause.getInstance();
|
|
|
+ const isGameOver = gamePause.isGameOver();
|
|
|
this.clearAllEnemies(!isGameOver); // 只有在游戏没有结束时才触发事件
|
|
|
}
|
|
|
|
|
|
@@ -289,7 +421,8 @@ export class EnemyController extends BaseSingleton {
|
|
|
if (!this.gameStarted || !this.enemyPrefab) return;
|
|
|
|
|
|
// 检查游戏是否已经结束,如果结束则不生成敌人
|
|
|
- if (this.gameManager && typeof this.gameManager.isGameOver === 'function' && this.gameManager.isGameOver()) {
|
|
|
+ const gamePause = GamePause.getInstance();
|
|
|
+ if (gamePause.isGameOver()) {
|
|
|
console.log('[EnemyController] 游戏已经结束,不再生成敌人');
|
|
|
this.unschedule(this.spawnEnemy); // 取消定时生成
|
|
|
return;
|
|
|
@@ -458,7 +591,8 @@ export class EnemyController extends BaseSingleton {
|
|
|
// 恢复生成敌人
|
|
|
public resumeSpawning(): void {
|
|
|
// 检查游戏是否已经结束,如果结束则不恢复生成敌人
|
|
|
- if (this.gameManager && typeof this.gameManager.isGameOver === 'function' && this.gameManager.isGameOver()) {
|
|
|
+ const gamePause = GamePause.getInstance();
|
|
|
+ if (gamePause.isGameOver()) {
|
|
|
console.log('[EnemyController] 游戏已经结束,不恢复敌人生成');
|
|
|
return;
|
|
|
}
|
|
|
@@ -473,7 +607,8 @@ export class EnemyController extends BaseSingleton {
|
|
|
if (!enemy || !enemy.isValid) return;
|
|
|
|
|
|
// 检查游戏是否已经结束
|
|
|
- if (this.gameManager && typeof this.gameManager.isGameOver === 'function' && this.gameManager.isGameOver()) {
|
|
|
+ const gamePause = GamePause.getInstance();
|
|
|
+ if (gamePause.isGameOver()) {
|
|
|
console.warn('[EnemyController] 游戏已经结束,不再处理敌人伤害');
|
|
|
return;
|
|
|
}
|
|
|
@@ -519,19 +654,9 @@ export class EnemyController extends BaseSingleton {
|
|
|
// 停止游戏,但不清除敌人
|
|
|
this.stopGame(false);
|
|
|
|
|
|
- // 通知GameManager游戏结束
|
|
|
- if (this.gameManager) {
|
|
|
- this.gameManager.gameOver();
|
|
|
- } else {
|
|
|
- // 如果没有引用,尝试查找GameManager
|
|
|
- const gameManagerNode = find('Canvas/GameManager');
|
|
|
- if (gameManagerNode) {
|
|
|
- const gameManager = gameManagerNode.getComponent(GameManager);
|
|
|
- if (gameManager) {
|
|
|
- gameManager.gameOver();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ // 通知GamePause触发游戏失败
|
|
|
+ const gamePause = GamePause.getInstance();
|
|
|
+ gamePause.triggerGameDefeat();
|
|
|
}
|
|
|
|
|
|
update(dt: number) {
|
|
|
@@ -583,24 +708,6 @@ export class EnemyController extends BaseSingleton {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // === 查找GameManager ===
|
|
|
- private findGameManager() {
|
|
|
- // 尝试在GameLevelUI下查找GameManager
|
|
|
- let gameManagerNode = find('Canvas/GameLevelUI/GameManager');
|
|
|
- if (!gameManagerNode) {
|
|
|
- // 如果没找到,尝试在Canvas下直接查找
|
|
|
- gameManagerNode = find('Canvas/GameManager');
|
|
|
- }
|
|
|
-
|
|
|
- if (gameManagerNode) {
|
|
|
- // 使用正确的类型获取组件
|
|
|
- this.gameManager = gameManagerNode.getComponent(GameManager);
|
|
|
- console.log('[EnemyController] GameManager引用已更新:', !!this.gameManager);
|
|
|
- } else {
|
|
|
- console.warn('[EnemyController] 找不到GameManager节点');
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
/** 供 EnemyInstance 在 onDestroy 中调用 */
|
|
|
public notifyEnemyDead(enemyNode?: Node) {
|
|
|
if (enemyNode) {
|
|
|
@@ -610,17 +717,9 @@ export class EnemyController extends BaseSingleton {
|
|
|
this.updateEnemyCountLabel();
|
|
|
}
|
|
|
|
|
|
- if (this.gameManager) {
|
|
|
- // 检查游戏是否已经结束
|
|
|
- if (typeof this.gameManager.isGameOver === 'function' && this.gameManager.isGameOver()) {
|
|
|
- console.warn('[EnemyController] 游戏已经结束,不再通知GameManager敌人被击杀');
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (this.gameManager.onEnemyKilled) {
|
|
|
- this.gameManager.onEnemyKilled();
|
|
|
- }
|
|
|
- }
|
|
|
+ // 通知GamePause处理敌人被击杀
|
|
|
+ const gamePause = GamePause.getInstance();
|
|
|
+ gamePause.onEnemyKilled();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -693,7 +792,8 @@ export class EnemyController extends BaseSingleton {
|
|
|
/** 显示每波开始提示,随后开启敌人生成 */
|
|
|
public showStartWavePromptUI(duration: number = 2) {
|
|
|
// 检查游戏是否已经结束,如果结束则不显示波次提示
|
|
|
- if (this.gameManager && typeof this.gameManager.isGameOver === 'function' && this.gameManager.isGameOver()) {
|
|
|
+ const gamePause = GamePause.getInstance();
|
|
|
+ if (gamePause.isGameOver()) {
|
|
|
console.log('[EnemyController] 游戏已经结束,不显示波次提示');
|
|
|
return;
|
|
|
}
|
|
|
@@ -707,7 +807,8 @@ export class EnemyController extends BaseSingleton {
|
|
|
if (this.startWaveUI) this.startWaveUI.active = false;
|
|
|
|
|
|
// 再次检查游戏是否已经结束,如果结束则不开始生成敌人
|
|
|
- if (this.gameManager && typeof this.gameManager.isGameOver === 'function' && this.gameManager.isGameOver()) {
|
|
|
+ const gamePauseCheck = GamePause.getInstance();
|
|
|
+ if (gamePauseCheck.isGameOver()) {
|
|
|
console.log('[EnemyController] 游戏已经结束,不启动敌人生成(延时检查)');
|
|
|
return;
|
|
|
}
|
|
|
@@ -719,4 +820,16 @@ export class EnemyController extends BaseSingleton {
|
|
|
this.startGame();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ onDestroy() {
|
|
|
+ // 清理事件监听
|
|
|
+ const eventBus = EventBus.getInstance();
|
|
|
+ eventBus.off(GameEvents.GAME_PAUSE, this.onGamePauseEvent, this);
|
|
|
+ eventBus.off(GameEvents.GAME_RESUME, this.onGameResumeEvent, this);
|
|
|
+ eventBus.off(GameEvents.GAME_SUCCESS, this.onGameEndEvent, this);
|
|
|
+ eventBus.off(GameEvents.GAME_DEFEAT, this.onGameEndEvent, this);
|
|
|
+
|
|
|
+ // 清空状态
|
|
|
+ this.pausedEnemyStates.clear();
|
|
|
+ }
|
|
|
}
|