GameManager.ts 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. import { _decorator, Component, Node, Prefab, instantiate, Vec3, find, director, Canvas, UITransform, Button, Label, PhysicsSystem2D, EPhysics2DDrawFlags, Vec2, sys } from 'cc';
  2. import { LevelManager } from './LevelManager';
  3. import { LevelConfigManager } from './LevelConfigManager';
  4. import { ShopManager } from '../ShopSystem/ShopManager';
  5. import { ConfigManager } from '../Core/ConfigManager';
  6. import { EnemyController } from '../CombatSystem/EnemyController';
  7. const { ccclass, property } = _decorator;
  8. /**
  9. * 游戏状态枚举
  10. */
  11. enum GameState {
  12. PLAYING = 'playing',
  13. SUCCESS = 'success',
  14. DEFEAT = 'defeat',
  15. PAUSED = 'paused'
  16. }
  17. /**
  18. * 增强版游戏管理器
  19. * 整合了游戏启动、状态管理、UI控制等功能
  20. */
  21. @ccclass('GameManager')
  22. export class GameManager extends Component {
  23. // === 原GameManager属性 ===
  24. @property({
  25. type: Node,
  26. tooltip: '拖拽BallController节点到这里'
  27. })
  28. public ballController: Node = null;
  29. @property({
  30. type: Node,
  31. tooltip: '拖拽BlockSelectionUI节点到这里'
  32. })
  33. public blockSelectionUI: Node = null;
  34. @property({
  35. type: Node,
  36. tooltip: '拖拽GameArea节点到这里'
  37. })
  38. public gameArea: Node = null;
  39. @property({
  40. type: Node,
  41. tooltip: '拖拽EnemyController节点到这里'
  42. })
  43. public enemyManager: Node = null;
  44. // === 游戏状态管理属性 ===
  45. @property({
  46. type: Node,
  47. tooltip: '血量显示节点 (HeartLabeld)'
  48. })
  49. public heartLabelNode: Node = null;
  50. @property({
  51. type: Node,
  52. tooltip: '游戏成功UI节点 (GameSuccess)'
  53. })
  54. public gameSuccessUI: Node = null;
  55. @property({
  56. type: Node,
  57. tooltip: '游戏失败UI节点 (GameDefeat)'
  58. })
  59. public gameDefeatUI: Node = null;
  60. @property({
  61. type: Node,
  62. tooltip: '波次显示节点 (WaveNumber)'
  63. })
  64. public waveNumberNode: Node = null;
  65. @property({
  66. type: Node,
  67. tooltip: '敌人数量显示节点 (EnemyNumber)'
  68. })
  69. public enemyNumberNode: Node = null;
  70. // === 游戏配置属性 ===
  71. @property({
  72. tooltip: '墙体初始血量'
  73. })
  74. public wallHealth: number = 1200;
  75. @property({
  76. tooltip: '初始血量'
  77. })
  78. public initialHealth: number = 100;
  79. @property({
  80. tooltip: '状态检查间隔(秒)'
  81. })
  82. public checkInterval: number = 1.0;
  83. // === 私有属性 ===
  84. private gameStarted: boolean = false;
  85. private currentHealth: number = 100;
  86. private currentState: GameState = GameState.PLAYING;
  87. private checkTimer: number = 0;
  88. private heartLabel: Label = null;
  89. private waveNumberLabel: Label = null;
  90. private enemyNumberLabel: Label = null;
  91. private enemyController: EnemyController = null;
  92. private levelManager: LevelManager = null;
  93. private levelConfigManager: LevelConfigManager = null;
  94. private shopManager: ShopManager = null;
  95. private configManager: ConfigManager = null;
  96. private enemySpawningStarted: boolean = false;
  97. private totalEnemiesSpawned: number = 0;
  98. private currentWave: number = 1;
  99. private currentWaveEnemyCount: number = 0;
  100. private currentWaveTotalEnemies: number = 0; // 当前波次总敌人数
  101. // 游戏区域的边界
  102. private gameBounds = {
  103. left: 0,
  104. right: 0,
  105. top: 0,
  106. bottom: 0
  107. };
  108. start() {
  109. // 初始化物理系统
  110. this.initPhysicsSystem();
  111. // 初始化管理器
  112. this.initializeManagers();
  113. // 计算游戏区域边界
  114. this.calculateGameBounds();
  115. // 初始化游戏状态
  116. this.initializeGameState();
  117. // 查找UI节点
  118. this.findUINodes();
  119. // 查找敌人控制器
  120. this.findEnemyController();
  121. // 初始化墙体血量显示
  122. this.initWallHealthDisplay();
  123. // 设置敌人控制器
  124. this.setupEnemyController();
  125. // 设置UI按钮
  126. this.setupUIButtons();
  127. // 加载当前关卡配置
  128. this.loadCurrentLevelConfig();
  129. }
  130. update(deltaTime: number) {
  131. if (this.currentState !== GameState.PLAYING) {
  132. return;
  133. }
  134. // 更新检查计时器
  135. this.checkTimer += deltaTime;
  136. if (this.checkTimer >= this.checkInterval) {
  137. this.checkTimer = 0;
  138. this.checkGameState();
  139. }
  140. }
  141. // === 物理系统初始化 ===
  142. private initPhysicsSystem() {
  143. // 启用物理系统
  144. PhysicsSystem2D.instance.enable = true;
  145. // 设置物理系统参数
  146. PhysicsSystem2D.instance.gravity = new Vec2(0, 0); // 无重力
  147. // 调试模式下显示碰撞框
  148. PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.Aabb |
  149. EPhysics2DDrawFlags.Pair |
  150. EPhysics2DDrawFlags.CenterOfMass |
  151. EPhysics2DDrawFlags.Joint |
  152. EPhysics2DDrawFlags.Shape;
  153. }
  154. // === 管理器初始化 ===
  155. private initializeManagers() {
  156. this.levelManager = LevelManager.getInstance();
  157. this.shopManager = ShopManager.getInstance();
  158. this.configManager = ConfigManager.getInstance();
  159. this.levelConfigManager = LevelConfigManager.getInstance();
  160. }
  161. // === 游戏状态初始化 ===
  162. private initializeGameState() {
  163. this.currentHealth = this.initialHealth;
  164. this.currentState = GameState.PLAYING;
  165. this.checkTimer = 0;
  166. this.enemySpawningStarted = false;
  167. this.totalEnemiesSpawned = 0;
  168. this.currentWave = 1;
  169. this.currentWaveEnemyCount = 0;
  170. this.currentWaveTotalEnemies = 0; // 当前波次总敌人数
  171. // 初始化UI显示
  172. this.updateWaveDisplay();
  173. this.updateEnemyCountDisplay();
  174. }
  175. // === 计算游戏区域边界 ===
  176. private calculateGameBounds() {
  177. const canvas = find('Canvas');
  178. if (!canvas) {
  179. return;
  180. }
  181. const canvasUI = canvas.getComponent(UITransform);
  182. if (!canvasUI) {
  183. return;
  184. }
  185. const screenWidth = canvasUI.width;
  186. const screenHeight = canvasUI.height;
  187. const worldPos = canvas.worldPosition;
  188. this.gameBounds.left = worldPos.x - screenWidth / 2;
  189. this.gameBounds.right = worldPos.x + screenWidth / 2;
  190. this.gameBounds.bottom = worldPos.y - screenHeight / 2;
  191. this.gameBounds.top = worldPos.y + screenHeight / 2;
  192. }
  193. // === 查找UI节点 ===
  194. private findUINodes() {
  195. // 查找血量显示节点
  196. if (!this.heartLabelNode) {
  197. this.heartLabelNode = find('Canvas/GameLevelUI/HeartNode/HeartLabeld');
  198. }
  199. if (this.heartLabelNode) {
  200. this.heartLabel = this.heartLabelNode.getComponent(Label);
  201. }
  202. // 查找波次显示节点
  203. if (!this.waveNumberNode) {
  204. this.waveNumberNode = find('Canvas/GameLevelUI/WaveInfo/WaveNumber');
  205. }
  206. if (this.waveNumberNode) {
  207. this.waveNumberLabel = this.waveNumberNode.getComponent(Label);
  208. }
  209. // 查找敌人数量显示节点
  210. if (!this.enemyNumberNode) {
  211. this.enemyNumberNode = find('Canvas/GameLevelUI/EnemyNode/EnemyNumber');
  212. }
  213. if (this.enemyNumberNode) {
  214. this.enemyNumberLabel = this.enemyNumberNode.getComponent(Label);
  215. }
  216. // 查找游戏成功UI
  217. if (!this.gameSuccessUI) {
  218. this.gameSuccessUI = find('Canvas/GameSuccess');
  219. }
  220. if (this.gameSuccessUI) {
  221. this.gameSuccessUI.active = false;
  222. }
  223. // 查找游戏失败UI
  224. if (!this.gameDefeatUI) {
  225. this.gameDefeatUI = find('Canvas/GameDefeat');
  226. }
  227. if (this.gameDefeatUI) {
  228. this.gameDefeatUI.active = false;
  229. }
  230. }
  231. // === 查找敌人控制器 ===
  232. private findEnemyController() {
  233. if (this.enemyManager) {
  234. this.enemyController = this.enemyManager.getComponent(EnemyController);
  235. }
  236. if (!this.enemyController) {
  237. const enemyNode = find('Canvas/GameLevelUI/EnemyController');
  238. if (enemyNode) {
  239. this.enemyController = enemyNode.getComponent(EnemyController);
  240. }
  241. }
  242. }
  243. // === 初始化墙体血量显示 ===
  244. private initWallHealthDisplay() {
  245. if (this.heartLabelNode && this.heartLabel) {
  246. this.heartLabel.string = this.wallHealth.toString();
  247. }
  248. // 通知敌人控制器墙体血量节点
  249. if (this.enemyController && this.heartLabelNode) {
  250. this.updateEnemyControllerWallHealth(this.heartLabelNode);
  251. }
  252. }
  253. // === 更新EnemyController的墙体血量 ===
  254. private updateEnemyControllerWallHealth(wallHealthNode: Node) {
  255. if (this.enemyController) {
  256. // 同步血量值
  257. this.enemyController.wallHealth = this.wallHealth;
  258. // 设置血量显示节点
  259. const heartLabelNode = find('Canvas/GameLevelUI/HeartNode/HeartLabeld');
  260. if (heartLabelNode) {
  261. this.enemyController.wallHealthNode = heartLabelNode;
  262. }
  263. // 让EnemyController更新显示
  264. this.enemyController.updateWallHealthDisplay();
  265. }
  266. }
  267. // === 设置敌人控制器 ===
  268. private setupEnemyController() {
  269. if (!this.enemyManager) {
  270. const gameLevelUI = find('Canvas/GameLevelUI');
  271. if (!gameLevelUI) {
  272. console.error('找不到GameLevelUI节点,无法创建EnemyController');
  273. return;
  274. }
  275. this.enemyManager = new Node('EnemyController');
  276. gameLevelUI.addChild(this.enemyManager);
  277. }
  278. if (!this.enemyController) {
  279. this.enemyController = this.enemyManager.addComponent(EnemyController);
  280. this.enemyController.wallHealth = this.wallHealth;
  281. }
  282. }
  283. // === 游戏状态检查 ===
  284. private checkGameState() {
  285. // 检查血量
  286. this.updateHealthFromUI();
  287. if (this.currentHealth <= 0) {
  288. this.triggerGameDefeat();
  289. return;
  290. }
  291. // 更新当前敌人数量(用于胜利检测,不影响UI显示)
  292. if (this.enemyController) {
  293. const currentEnemyCount = this.enemyController.getCurrentEnemyCount ?
  294. this.enemyController.getCurrentEnemyCount() : 0;
  295. this.updateCurrentWaveEnemyCount(currentEnemyCount);
  296. }
  297. // 检查敌人状态
  298. if (this.checkAllEnemiesDefeated()) {
  299. this.triggerGameSuccess();
  300. return;
  301. }
  302. }
  303. // === 从UI更新血量 ===
  304. private updateHealthFromUI() {
  305. if (this.heartLabel) {
  306. const healthText = this.heartLabel.string;
  307. const healthMatch = healthText.match(/\d+/);
  308. if (healthMatch) {
  309. const newHealth = parseInt(healthMatch[0]);
  310. if (newHealth !== this.currentHealth) {
  311. this.currentHealth = newHealth;
  312. }
  313. }
  314. }
  315. }
  316. // === 检查所有敌人是否被击败 ===
  317. private checkAllEnemiesDefeated(): boolean {
  318. if (!this.enemyController) {
  319. return false;
  320. }
  321. // 检查敌人是否已开始生成
  322. if (!this.enemySpawningStarted) {
  323. // 检查游戏是否已开始(EnemyController的gameStarted属性)
  324. if (this.enemyController.isGameStarted()) {
  325. this.enemySpawningStarted = true;
  326. } else {
  327. // 敌人还未开始生成,不算胜利
  328. return false;
  329. }
  330. }
  331. // 获取当前敌人数量
  332. const currentEnemyCount = this.enemyController.getCurrentEnemyCount ?
  333. this.enemyController.getCurrentEnemyCount() : 0;
  334. // 更新已生成敌人总数(记录曾经达到的最大值)
  335. if (currentEnemyCount > this.totalEnemiesSpawned) {
  336. this.totalEnemiesSpawned = currentEnemyCount;
  337. }
  338. // 只有在以下情况下才算胜利:
  339. // 1. 敌人生成已开始
  340. // 2. 当前敌人数量为0
  341. // 3. 曾经生成过敌人(避免游戏刚开始就判定胜利)
  342. const shouldCheckVictory = this.enemySpawningStarted &&
  343. currentEnemyCount === 0 &&
  344. this.totalEnemiesSpawned > 0;
  345. return shouldCheckVictory;
  346. }
  347. // === 触发游戏失败 ===
  348. private triggerGameDefeat() {
  349. if (this.currentState === GameState.DEFEAT) {
  350. return;
  351. }
  352. this.currentState = GameState.DEFEAT;
  353. this.pauseGame();
  354. if (this.gameDefeatUI) {
  355. this.gameDefeatUI.active = true;
  356. }
  357. this.onGameDefeat();
  358. }
  359. // === 触发游戏成功 ===
  360. private triggerGameSuccess() {
  361. if (this.currentState === GameState.SUCCESS) {
  362. return;
  363. }
  364. this.currentState = GameState.SUCCESS;
  365. this.pauseGame();
  366. if (this.gameSuccessUI) {
  367. this.gameSuccessUI.active = true;
  368. }
  369. this.onGameSuccess();
  370. }
  371. // === 暂停游戏 ===
  372. private pauseGame() {
  373. this.gameStarted = false;
  374. if (this.enemyController && this.enemyController.pauseSpawning) {
  375. this.enemyController.pauseSpawning();
  376. }
  377. }
  378. // === 恢复游戏 ===
  379. private resumeGame() {
  380. this.currentState = GameState.PLAYING;
  381. this.gameStarted = true;
  382. if (this.enemyController && this.enemyController.resumeSpawning) {
  383. this.enemyController.resumeSpawning();
  384. }
  385. if (this.gameSuccessUI) {
  386. this.gameSuccessUI.active = false;
  387. }
  388. if (this.gameDefeatUI) {
  389. this.gameDefeatUI.active = false;
  390. }
  391. }
  392. // === 游戏失败回调 ===
  393. private onGameDefeat() {
  394. console.log('处理游戏失败逻辑');
  395. }
  396. // === 游戏成功回调 ===
  397. private onGameSuccess() {
  398. console.log('处理游戏成功逻辑');
  399. this.giveReward();
  400. this.onLevelComplete();
  401. }
  402. // === 给予奖励 ===
  403. private giveReward() {
  404. if (!this.shopManager) return;
  405. const baseReward = 100;
  406. const healthBonus = Math.floor(this.currentHealth * 0.1);
  407. const totalReward = baseReward + healthBonus;
  408. this.shopManager.addCoins(totalReward);
  409. }
  410. // === 处理关卡完成 ===
  411. private onLevelComplete(score: number = 0, stars: number = 1) {
  412. if (this.levelManager) {
  413. const currentLevel = this.levelManager.getCurrentLevel();
  414. this.levelManager.completeLevel(currentLevel, score, stars);
  415. }
  416. }
  417. // === 设置UI按钮 ===
  418. private setupUIButtons() {
  419. this.setupSuccessUIButtons();
  420. this.setupDefeatUIButtons();
  421. }
  422. // === 设置成功界面按钮 ===
  423. private setupSuccessUIButtons() {
  424. if (this.gameSuccessUI) {
  425. const nextLevelBtn = this.gameSuccessUI.getChildByName('NextLevelBtn');
  426. const restartBtn = this.gameSuccessUI.getChildByName('RestartBtn');
  427. const mainMenuBtn = this.gameSuccessUI.getChildByName('MainMenuBtn');
  428. const shopBtn = this.gameSuccessUI.getChildByName('ShopBtn');
  429. if (nextLevelBtn) {
  430. const button = nextLevelBtn.getComponent(Button);
  431. if (button) {
  432. button.node.on(Button.EventType.CLICK, this.onNextLevelClick, this);
  433. }
  434. }
  435. if (restartBtn) {
  436. const button = restartBtn.getComponent(Button);
  437. if (button) {
  438. button.node.on(Button.EventType.CLICK, this.onRestartClick, this);
  439. }
  440. }
  441. if (mainMenuBtn) {
  442. const button = mainMenuBtn.getComponent(Button);
  443. if (button) {
  444. button.node.on(Button.EventType.CLICK, this.onMainMenuClick, this);
  445. }
  446. }
  447. if (shopBtn) {
  448. const button = shopBtn.getComponent(Button);
  449. if (button) {
  450. button.node.on(Button.EventType.CLICK, this.onShopClick, this);
  451. }
  452. }
  453. }
  454. }
  455. // === 设置失败界面按钮 ===
  456. private setupDefeatUIButtons() {
  457. if (this.gameDefeatUI) {
  458. const restartBtn = this.gameDefeatUI.getChildByName('RestartBtn');
  459. const mainMenuBtn = this.gameDefeatUI.getChildByName('MainMenuBtn');
  460. const shopBtn = this.gameDefeatUI.getChildByName('ShopBtn');
  461. const reviveBtn = this.gameDefeatUI.getChildByName('ReviveBtn');
  462. if (restartBtn) {
  463. const button = restartBtn.getComponent(Button);
  464. if (button) {
  465. button.node.on(Button.EventType.CLICK, this.onRestartClick, this);
  466. }
  467. }
  468. if (mainMenuBtn) {
  469. const button = mainMenuBtn.getComponent(Button);
  470. if (button) {
  471. button.node.on(Button.EventType.CLICK, this.onMainMenuClick, this);
  472. }
  473. }
  474. if (shopBtn) {
  475. const button = shopBtn.getComponent(Button);
  476. if (button) {
  477. button.node.on(Button.EventType.CLICK, this.onShopClick, this);
  478. }
  479. }
  480. if (reviveBtn) {
  481. const button = reviveBtn.getComponent(Button);
  482. if (button) {
  483. button.node.on(Button.EventType.CLICK, this.onReviveClick, this);
  484. }
  485. }
  486. }
  487. }
  488. // === 按钮点击事件处理 ===
  489. private onNextLevelClick() {
  490. if (this.levelManager) {
  491. const currentLevel = this.levelManager.getCurrentLevel();
  492. const nextLevel = currentLevel + 1;
  493. if (this.levelManager.isLevelUnlocked(nextLevel)) {
  494. this.levelManager.setCurrentLevel(nextLevel);
  495. this.restartCurrentLevel();
  496. }
  497. }
  498. }
  499. private onRestartClick() {
  500. this.restartCurrentLevel();
  501. }
  502. private onMainMenuClick() {
  503. this.restartGame();
  504. }
  505. private onShopClick() {
  506. // 可以在这里实现商店界面逻辑
  507. }
  508. private onReviveClick() {
  509. const reviveCost = 5;
  510. if (this.shopManager && this.shopManager.getGems() >= reviveCost) {
  511. if (this.shopManager.spendGems(reviveCost)) {
  512. this.revivePlayer();
  513. }
  514. }
  515. }
  516. // === 复活玩家 ===
  517. private revivePlayer() {
  518. this.setHealth(50);
  519. this.restartGame();
  520. }
  521. // === 重新开始当前关卡 ===
  522. private restartCurrentLevel() {
  523. this.restartGame();
  524. }
  525. // === 原GameManager方法 ===
  526. public onConfirmButtonClicked() {
  527. if (this.blockSelectionUI) {
  528. this.blockSelectionUI.active = false;
  529. const gridContainer = find('Canvas/GameLevelUI/GameArea/GridContainer');
  530. if (gridContainer) {
  531. gridContainer.active = true;
  532. }
  533. this.preservePlacedBlocks();
  534. }
  535. this.startGame();
  536. }
  537. private preservePlacedBlocks() {
  538. const blockController = find('Canvas/GameLevelUI/BlockController');
  539. if (blockController) {
  540. const blockManager = blockController.getComponent('BlockManager') as any;
  541. if (blockManager) {
  542. blockManager.onGameStart();
  543. }
  544. }
  545. }
  546. public startGame() {
  547. if (this.gameStarted) return;
  548. this.gameStarted = true;
  549. this.currentState = GameState.PLAYING;
  550. this.spawnBall();
  551. if (this.enemyController) {
  552. this.enemyController.startGame();
  553. }
  554. }
  555. private spawnBall() {
  556. if (!this.ballController) {
  557. return;
  558. }
  559. // 注意:BallController可能需要导入,这里先使用any类型
  560. const ballControllerComp = this.ballController.getComponent('BallController') as any;
  561. if (ballControllerComp) {
  562. ballControllerComp.initialize();
  563. }
  564. }
  565. public gameOver() {
  566. this.triggerGameDefeat();
  567. }
  568. // === 公共方法 ===
  569. public setHealth(health: number) {
  570. this.currentHealth = Math.max(0, health);
  571. }
  572. public takeDamage(damage: number) {
  573. this.currentHealth = Math.max(0, this.currentHealth - damage);
  574. if (this.currentHealth <= 0) {
  575. this.triggerGameDefeat();
  576. }
  577. }
  578. public getCurrentState(): GameState {
  579. return this.currentState;
  580. }
  581. public restartGame() {
  582. this.initializeGameState();
  583. this.resumeGame();
  584. }
  585. public isGameOver(): boolean {
  586. return this.currentState === GameState.SUCCESS || this.currentState === GameState.DEFEAT;
  587. }
  588. public forceGameSuccess() {
  589. this.triggerGameSuccess();
  590. }
  591. public forceGameDefeat() {
  592. this.triggerGameDefeat();
  593. }
  594. // === 获取EnemyController组件 ===
  595. public getEnemyController() {
  596. return this.enemyController;
  597. }
  598. // === 调试方法 ===
  599. public getEnemyStatus() {
  600. if (!this.enemyController) {
  601. return;
  602. }
  603. const currentCount = this.enemyController.getCurrentEnemyCount ?
  604. this.enemyController.getCurrentEnemyCount() : 0;
  605. const gameStarted = this.enemyController.isGameStarted();
  606. console.log('=== 敌人状态调试信息 ===');
  607. console.log(`敌人生成已开始: ${this.enemySpawningStarted}`);
  608. console.log(`当前敌人数量: ${currentCount}`);
  609. console.log(`曾生成最大敌人数: ${this.totalEnemiesSpawned}`);
  610. console.log(`EnemyController游戏已开始: ${gameStarted}`);
  611. console.log(`GameManager游戏状态: ${this.currentState}`);
  612. console.log(`GameManager游戏已开始: ${this.gameStarted}`);
  613. console.log(`当前血量: ${this.currentHealth}`);
  614. // 显示活跃敌人的详细信息
  615. if (this.enemyController.getActiveEnemies) {
  616. const activeEnemies = this.enemyController.getActiveEnemies();
  617. console.log(`活跃敌人列表 (${activeEnemies.length}个):`);
  618. activeEnemies.forEach((enemy, index) => {
  619. if (enemy && enemy.isValid) {
  620. console.log(` ${index + 1}. ${enemy.name} - 位置: (${enemy.position.x.toFixed(1)}, ${enemy.position.y.toFixed(1)})`);
  621. } else {
  622. console.log(` ${index + 1}. 无效敌人节点`);
  623. }
  624. });
  625. }
  626. }
  627. public forceStartEnemySpawning() {
  628. this.enemySpawningStarted = true;
  629. }
  630. public setTotalEnemiesSpawned(count: number) {
  631. this.totalEnemiesSpawned = count;
  632. }
  633. // === 测试方法 ===
  634. public testEnemyDetection() {
  635. const result = this.checkAllEnemiesDefeated();
  636. this.getEnemyStatus();
  637. return result;
  638. }
  639. // 测试组件获取是否正常
  640. public testComponentAccess() {
  641. console.log('=== 测试组件访问 ===');
  642. if (this.enemyController) {
  643. console.log('✅ EnemyController 访问正常');
  644. console.log(`当前敌人数量: ${this.enemyController.getCurrentEnemyCount()}`);
  645. console.log(`游戏是否开始: ${this.enemyController.isGameStarted()}`);
  646. } else {
  647. console.log('❌ EnemyController 未找到');
  648. }
  649. console.log('组件测试完成');
  650. }
  651. // === 测试敌人攻击 ===
  652. public testEnemyAttackWall() {
  653. console.log('=== GameManager: 测试敌人攻击墙体 ===');
  654. if (this.enemyController) {
  655. console.log(`攻击前墙体血量: ${this.enemyController.getCurrentWallHealth()}`);
  656. // 测试EnemyController的攻击功能
  657. const newHealth = this.enemyController.testEnemyAttack();
  658. console.log(`攻击后墙体血量: ${newHealth}`);
  659. // 强制所有敌人攻击
  660. this.enemyController.forceEnemyAttack();
  661. return newHealth;
  662. } else {
  663. console.error('EnemyController未找到');
  664. return -1;
  665. }
  666. }
  667. onDestroy() {
  668. // 清理按钮事件监听
  669. if (this.gameSuccessUI) {
  670. const buttons = this.gameSuccessUI.getComponentsInChildren(Button);
  671. buttons.forEach(button => {
  672. button.node.off(Button.EventType.CLICK);
  673. });
  674. }
  675. if (this.gameDefeatUI) {
  676. const buttons = this.gameDefeatUI.getComponentsInChildren(Button);
  677. buttons.forEach(button => {
  678. button.node.off(Button.EventType.CLICK);
  679. });
  680. }
  681. }
  682. // === 加载当前关卡配置 ===
  683. public async loadCurrentLevelConfig() {
  684. if (!this.levelManager || !this.levelConfigManager) {
  685. return null;
  686. }
  687. try {
  688. const currentLevel = this.levelManager.getCurrentLevel();
  689. console.log(`加载关卡 ${currentLevel} 配置`);
  690. const levelConfig = await this.levelConfigManager.getLevelConfig(currentLevel);
  691. if (levelConfig) {
  692. console.log(`关卡 ${currentLevel} 配置加载成功:`, levelConfig);
  693. this.applyLevelConfig(levelConfig);
  694. return levelConfig;
  695. } else {
  696. console.warn(`关卡 ${currentLevel} 的配置文件不存在`);
  697. return null;
  698. }
  699. } catch (error) {
  700. console.error('加载关卡配置失败:', error);
  701. return null;
  702. }
  703. }
  704. // === 应用关卡配置 ===
  705. private applyLevelConfig(levelConfig: any) {
  706. if (!levelConfig) return;
  707. // 应用关卡设置
  708. if (levelConfig.settings) {
  709. const settings = levelConfig.settings;
  710. if (settings.initialHealth !== undefined) {
  711. this.wallHealth = settings.initialHealth;
  712. this.initialHealth = settings.initialHealth;
  713. this.currentHealth = settings.initialHealth;
  714. }
  715. if (settings.checkInterval !== undefined) {
  716. this.checkInterval = settings.checkInterval;
  717. }
  718. }
  719. // 记录武器配置信息
  720. if (levelConfig.weapons) {
  721. console.log('关卡武器配置:', levelConfig.weapons);
  722. }
  723. // 记录敌人波次配置信息并初始化第一波
  724. if (levelConfig.waves && levelConfig.waves.length > 0) {
  725. console.log('关卡敌人波次配置:', levelConfig.waves);
  726. // 设置第一波的信息
  727. const firstWave = levelConfig.waves[0];
  728. if (firstWave && firstWave.enemies) {
  729. const totalEnemiesInFirstWave = firstWave.enemies.reduce((total, enemyGroup) => {
  730. return total + (enemyGroup.count || 0);
  731. }, 0);
  732. this.setCurrentWave(1, totalEnemiesInFirstWave);
  733. }
  734. }
  735. }
  736. // === 获取当前关卡信息 ===
  737. public async getCurrentLevelInfo() {
  738. if (!this.levelManager) {
  739. return null;
  740. }
  741. const currentLevel = this.levelManager.getCurrentLevel();
  742. const levelData = this.levelManager.getLevelData(currentLevel);
  743. const levelConfig = await this.loadCurrentLevelConfig();
  744. return {
  745. level: currentLevel,
  746. data: levelData,
  747. config: levelConfig
  748. };
  749. }
  750. // === 更新波次显示 ===
  751. private updateWaveDisplay() {
  752. if (this.waveNumberLabel) {
  753. this.waveNumberLabel.string = this.currentWave.toString();
  754. }
  755. }
  756. // === 更新敌人数量显示 ===
  757. private updateEnemyCountDisplay() {
  758. if (this.enemyNumberLabel) {
  759. this.enemyNumberLabel.string = this.currentWaveTotalEnemies.toString();
  760. }
  761. }
  762. // === 设置当前波次 ===
  763. public setCurrentWave(wave: number, enemyCount: number = 0) {
  764. this.currentWave = wave;
  765. this.currentWaveEnemyCount = 0; // 重置当前敌人数量为0
  766. this.currentWaveTotalEnemies = enemyCount; // 设置该波次总敌人数
  767. this.updateWaveDisplay();
  768. this.updateEnemyCountDisplay();
  769. }
  770. // === 更新当前波次敌人数量 ===
  771. public updateCurrentWaveEnemyCount(count: number) {
  772. this.currentWaveEnemyCount = count;
  773. // 不应该修改总敌人数,总敌人数只在设置波次时确定
  774. // this.currentWaveTotalEnemies = count; // 移除这行
  775. // 敌人数量显示的是总数,不需要在这里更新
  776. // this.updateEnemyCountDisplay(); // 移除这行
  777. }
  778. // === 获取当前波次 ===
  779. public getCurrentWave(): number {
  780. return this.currentWave;
  781. }
  782. // === 获取当前波次敌人数量 ===
  783. public getCurrentWaveEnemyCount(): number {
  784. return this.currentWaveEnemyCount;
  785. }
  786. // === 获取当前波次总敌人数量 ===
  787. public getCurrentWaveTotalEnemies(): number {
  788. return this.currentWaveTotalEnemies;
  789. }
  790. // === 进入下一波 ===
  791. public nextWave() {
  792. this.currentWave++;
  793. this.updateWaveDisplay();
  794. // 这里可以根据关卡配置设置下一波的敌人数量
  795. // 暂时设置为0,等待具体的波次系统实现
  796. this.setCurrentWave(this.currentWave, 0);
  797. }
  798. }