GroundBurnAreaManager.ts 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import { _decorator, Component, Node, Prefab, instantiate, resources, Vec3 } from 'cc';
  2. import { GroundBurnArea } from './GroundBurnArea';
  3. import { HitEffectConfig } from '../../Core/ConfigManager';
  4. import { WeaponBullet } from '../WeaponBullet';
  5. import { PhysicsManager } from '../../Core/PhysicsManager';
  6. const { ccclass, property } = _decorator;
  7. /**
  8. * 地面燃烧区域管理器
  9. * 单例模式,统一管理所有地面燃烧区域的创建和销毁
  10. */
  11. @ccclass('GroundBurnAreaManager')
  12. export class GroundBurnAreaManager extends Component {
  13. private static _instance: GroundBurnAreaManager = null;
  14. @property({
  15. type: Node,
  16. tooltip: '游戏区域节点,燃烧区域将在此节点下创建'
  17. })
  18. public gameArea: Node = null;
  19. @property({
  20. type: Prefab,
  21. tooltip: '地面燃烧区域预制体'
  22. })
  23. public groundBurnAreaPrefab: Prefab = null;
  24. private activeBurnAreas: Node[] = [];
  25. /**
  26. * 组件加载时设置单例
  27. */
  28. protected onLoad(): void {
  29. if (GroundBurnAreaManager._instance === null) {
  30. GroundBurnAreaManager._instance = this;
  31. console.log('[GroundBurnAreaManager] 单例初始化成功');
  32. } else {
  33. console.warn('[GroundBurnAreaManager] 单例已存在,销毁重复实例');
  34. this.node.destroy();
  35. }
  36. }
  37. /**
  38. * 组件启动时验证配置
  39. */
  40. protected start(): void {
  41. if (!this.gameArea) {
  42. console.error('[GroundBurnAreaManager] gameArea未设置,请在Inspector中拖拽GameArea节点');
  43. }
  44. if (!this.groundBurnAreaPrefab) {
  45. console.error('[GroundBurnAreaManager] groundBurnAreaPrefab未设置,请在Inspector中拖拽GroundBurnArea预制体');
  46. }
  47. console.log('[GroundBurnAreaManager] 管理器配置验证完成');
  48. }
  49. onDestroy() {
  50. if (GroundBurnAreaManager._instance === this) {
  51. GroundBurnAreaManager._instance = null;
  52. }
  53. // 清理所有活跃的燃烧区域
  54. this.clearAllBurnAreas();
  55. }
  56. /**
  57. * 获取单例实例
  58. */
  59. public static getInstance(): GroundBurnAreaManager | null {
  60. return GroundBurnAreaManager._instance;
  61. }
  62. /**
  63. * 创建地面燃烧区域
  64. * @param position 燃烧区域位置
  65. * @param effect 效果配置
  66. * @param weaponBullet 武器子弹组件(用于获取最终伤害)
  67. * @param defaultBurnEffectPath 默认燃烧特效路径
  68. */
  69. public createGroundBurnArea(
  70. position: Vec3,
  71. effect: HitEffectConfig,
  72. weaponBullet: WeaponBullet | null,
  73. defaultBurnEffectPath?: string
  74. ): Node | null {
  75. if (!this.groundBurnAreaPrefab) {
  76. console.error('[GroundBurnAreaManager] 地面燃烧区域预制体未设置');
  77. return null;
  78. }
  79. if (!this.gameArea) {
  80. console.error('[GroundBurnAreaManager] 游戏区域节点未设置');
  81. return null;
  82. }
  83. // 检查物理系统状态
  84. const physicsManager = PhysicsManager.getInstance();
  85. if (!physicsManager) {
  86. console.warn('[GroundBurnAreaManager] 物理系统未初始化,无法创建燃烧区域');
  87. return null;
  88. }
  89. const physicsSystem = physicsManager.getSystem();
  90. if (!physicsSystem || !physicsSystem.enable) {
  91. console.warn('[GroundBurnAreaManager] 物理系统未启用,无法创建燃烧区域');
  92. return null;
  93. }
  94. try {
  95. // 实例化预制体
  96. const burnAreaNode = instantiate(this.groundBurnAreaPrefab);
  97. // 添加到游戏区域
  98. this.gameArea.addChild(burnAreaNode);
  99. // 获取地面燃烧区域组件
  100. const groundBurnArea = burnAreaNode.getComponent(GroundBurnArea);
  101. if (!groundBurnArea) {
  102. console.error('[GroundBurnAreaManager] 预制体中未找到 GroundBurnArea 组件');
  103. burnAreaNode.destroy();
  104. return null;
  105. }
  106. // 使用WeaponBullet的最终伤害值
  107. const finalDamage = weaponBullet ? weaponBullet.getFinalDamage() : (effect.damage || 0);
  108. // 初始化燃烧区域
  109. groundBurnArea.initGroundBurnArea(
  110. position,
  111. effect.duration || 3,
  112. finalDamage,
  113. effect.tickInterval || 0.5
  114. );
  115. // 添加到活跃列表
  116. this.activeBurnAreas.push(burnAreaNode);
  117. console.log(`[GroundBurnAreaManager] 地面燃烧区域已创建,位置: (${position.x.toFixed(1)}, ${position.y.toFixed(1)})`);
  118. return burnAreaNode;
  119. } catch (error) {
  120. console.error('[GroundBurnAreaManager] 创建地面燃烧区域失败:', error);
  121. return null;
  122. }
  123. }
  124. /**
  125. * 移除燃烧区域
  126. */
  127. public removeBurnArea(burnAreaNode: Node) {
  128. const index = this.activeBurnAreas.indexOf(burnAreaNode);
  129. if (index !== -1) {
  130. this.activeBurnAreas.splice(index, 1);
  131. console.log(`[GroundBurnAreaManager] 燃烧区域已从活跃列表中移除`);
  132. }
  133. }
  134. /**
  135. * 清理所有燃烧区域
  136. */
  137. public clearAllBurnAreas() {
  138. console.log(`[GroundBurnAreaManager] 清理所有燃烧区域,数量: ${this.activeBurnAreas.length}`);
  139. for (const burnArea of this.activeBurnAreas) {
  140. if (burnArea && burnArea.isValid) {
  141. const groundBurnArea = burnArea.getComponent(GroundBurnArea);
  142. if (groundBurnArea) {
  143. groundBurnArea.destroyBurnArea();
  144. } else {
  145. burnArea.destroy();
  146. }
  147. }
  148. }
  149. this.activeBurnAreas = [];
  150. }
  151. /**
  152. * 获取活跃燃烧区域数量
  153. */
  154. public getActiveBurnAreaCount(): number {
  155. return this.activeBurnAreas.length;
  156. }
  157. /**
  158. * 获取所有活跃的燃烧区域
  159. */
  160. public getActiveBurnAreas(): Node[] {
  161. return [...this.activeBurnAreas];
  162. }
  163. }