BurnEffect.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import { _decorator, Component, Node } from 'cc';
  2. import EventBus, { GameEvents } from '../../Core/EventBus';
  3. const { ccclass, property } = _decorator;
  4. /**
  5. * 灼烧效果组件
  6. * 用于管理敌人身上的持续灼烧效果
  7. */
  8. @ccclass('BurnEffect')
  9. export class BurnEffect extends Component {
  10. private _duration: number = 0;
  11. private _originalDuration: number = 0;
  12. private _damage: number = 0;
  13. private _tickInterval: number = 0;
  14. private _burnTimerId: string = '';
  15. private _isActive: boolean = false;
  16. private _burnEffectNode: Node | null = null; // 灼烧特效节点
  17. /**
  18. * 初始化灼烧效果
  19. * @param duration 持续时间(秒)
  20. * @param damage 每次伤害值
  21. * @param tickInterval 伤害间隔(秒)
  22. */
  23. public initBurnEffect(duration: number, damage: number, tickInterval: number): void {
  24. this._duration = duration;
  25. this._originalDuration = duration;
  26. this._damage = damage;
  27. this._tickInterval = tickInterval;
  28. this._isActive = true;
  29. this._burnTimerId = `burn_${this.node.uuid}_${Date.now()}`;
  30. // 启动灼烧伤害循环
  31. this.startBurnDamageLoop();
  32. }
  33. /**
  34. * 刷新灼烧效果的持续时间
  35. * @param newDuration 新的持续时间
  36. */
  37. public refreshDuration(newDuration: number): void {
  38. this._duration = newDuration;
  39. this._originalDuration = newDuration;
  40. console.log(`[BurnEffect] 刷新灼烧效果持续时间: ${newDuration}秒`);
  41. // 如果当前没有激活,重新启动
  42. if (!this._isActive) {
  43. this._isActive = true;
  44. this.startBurnDamageLoop();
  45. }
  46. }
  47. /**
  48. * 获取剩余持续时间
  49. */
  50. public getRemainingDuration(): number {
  51. return this._duration;
  52. }
  53. /**
  54. * 获取伤害值
  55. */
  56. public getDamage(): number {
  57. return this._damage;
  58. }
  59. /**
  60. * 获取伤害间隔
  61. */
  62. public getTickInterval(): number {
  63. return this._tickInterval;
  64. }
  65. /**
  66. * 减少持续时间
  67. * @param deltaTime 减少的时间
  68. * @returns 是否还有剩余时间
  69. */
  70. public reduceDuration(deltaTime: number): boolean {
  71. this._duration -= deltaTime;
  72. return this._duration > 0;
  73. }
  74. /**
  75. * 启动灼烧伤害循环
  76. */
  77. private startBurnDamageLoop(): void {
  78. if (!this._isActive || this._duration <= 0) {
  79. return;
  80. }
  81. console.log(`[BurnEffect] 启动灼烧伤害循环 - 持续时间: ${this._duration}秒, 伤害间隔: ${this._tickInterval}秒`);
  82. // 使用定时器进行伤害循环
  83. this.scheduleOnce(() => {
  84. this.processBurnDamage();
  85. }, this._tickInterval);
  86. }
  87. /**
  88. * 处理灼烧伤害
  89. */
  90. private processBurnDamage(): void {
  91. // 检查组件和节点是否仍然有效
  92. if (!this._isActive || !this.node || !this.node.isValid) {
  93. console.log(`[BurnEffect] 灼烧效果已停止或节点无效`);
  94. return;
  95. }
  96. // 减少持续时间
  97. this._duration -= this._tickInterval;
  98. console.log(`[BurnEffect] 处理灼烧伤害 - 伤害: ${this._damage}, 剩余时间: ${this._duration.toFixed(1)}秒`);
  99. // 通过事件系统发送伤害
  100. const eventBus = EventBus.getInstance();
  101. const damageData = {
  102. enemyNode: this.node,
  103. damage: this._damage,
  104. isCritical: false,
  105. source: 'BurnEffect',
  106. burnTimerId: this._burnTimerId
  107. };
  108. eventBus.emit(GameEvents.APPLY_DAMAGE_TO_ENEMY, damageData);
  109. // 检查是否还有剩余时间
  110. if (this._duration > 0) {
  111. // 继续下一次伤害
  112. this.scheduleOnce(() => {
  113. this.processBurnDamage();
  114. }, this._tickInterval);
  115. } else {
  116. // 灼烧效果结束
  117. console.log(`[BurnEffect] 灼烧效果结束,移除组件`);
  118. this.stopBurnEffect();
  119. }
  120. }
  121. /**
  122. * 设置灼烧特效节点
  123. */
  124. public setBurnEffectNode(effectNode: Node): void {
  125. this._burnEffectNode = effectNode;
  126. }
  127. /**
  128. * 停止灼烧效果
  129. */
  130. public stopBurnEffect(): void {
  131. this._isActive = false;
  132. this.unscheduleAllCallbacks();
  133. // 销毁灼烧特效节点
  134. if (this._burnEffectNode && this._burnEffectNode.isValid) {
  135. console.log(`[BurnEffect] 销毁灼烧特效节点`);
  136. this._burnEffectNode.destroy();
  137. this._burnEffectNode = null;
  138. }
  139. // 通过事件通知灼烧效果结束
  140. const eventBus = EventBus.getInstance();
  141. eventBus.emit(GameEvents.BURN_EFFECT_ENDED, {
  142. enemyNode: this.node,
  143. burnTimerId: this._burnTimerId
  144. });
  145. console.log(`[BurnEffect] 灼烧效果已停止`);
  146. // 移除组件
  147. if (this.node && this.node.isValid) {
  148. this.node.removeComponent(BurnEffect);
  149. }
  150. }
  151. /**
  152. * 获取灼烧效果是否激活
  153. */
  154. public isActive(): boolean {
  155. return this._isActive;
  156. }
  157. /**
  158. * 组件销毁时清理定时器
  159. */
  160. protected onDestroy(): void {
  161. this._isActive = false;
  162. // 取消所有定时器
  163. this.unscheduleAllCallbacks();
  164. // 清理灼烧特效节点
  165. if (this._burnEffectNode && this._burnEffectNode.isValid) {
  166. console.log(`[BurnEffect] 组件销毁时清理灼烧特效节点`);
  167. this._burnEffectNode.destroy();
  168. this._burnEffectNode = null;
  169. }
  170. console.log(`[BurnEffect] 灼烧效果组件已销毁,清理定时器`);
  171. }
  172. }