BurnEffect.ts 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. const enemyInstance = this.node.getComponent('EnemyInstance') as any;
  98. if (enemyInstance && enemyInstance.isDrifting()) {
  99. console.log(`[BurnEffect] 敌人 ${this.node.name} 处于漂移状态,跳过灼烧伤害`);
  100. // 继续下一次检查,但不造成伤害
  101. if (this._duration > 0) {
  102. this.scheduleOnce(() => {
  103. this.processBurnDamage();
  104. }, this._tickInterval);
  105. } else {
  106. console.log(`[BurnEffect] 灼烧效果结束,移除组件`);
  107. this.stopBurnEffect();
  108. }
  109. return;
  110. }
  111. // 减少持续时间
  112. this._duration -= this._tickInterval;
  113. console.log(`[BurnEffect] 处理灼烧伤害 - 伤害: ${this._damage}, 剩余时间: ${this._duration.toFixed(1)}秒`);
  114. // 通过事件系统发送伤害
  115. const eventBus = EventBus.getInstance();
  116. const damageData = {
  117. enemyNode: this.node,
  118. damage: this._damage,
  119. isCritical: false,
  120. source: 'BurnEffect',
  121. burnTimerId: this._burnTimerId
  122. };
  123. eventBus.emit(GameEvents.APPLY_DAMAGE_TO_ENEMY, damageData);
  124. // 检查是否还有剩余时间
  125. if (this._duration > 0) {
  126. // 继续下一次伤害
  127. this.scheduleOnce(() => {
  128. this.processBurnDamage();
  129. }, this._tickInterval);
  130. } else {
  131. // 灼烧效果结束
  132. console.log(`[BurnEffect] 灼烧效果结束,移除组件`);
  133. this.stopBurnEffect();
  134. }
  135. }
  136. /**
  137. * 设置灼烧特效节点
  138. */
  139. public setBurnEffectNode(effectNode: Node): void {
  140. this._burnEffectNode = effectNode;
  141. }
  142. /**
  143. * 停止灼烧效果
  144. */
  145. public stopBurnEffect(): void {
  146. this._isActive = false;
  147. this.unscheduleAllCallbacks();
  148. // 销毁灼烧特效节点
  149. if (this._burnEffectNode && this._burnEffectNode.isValid) {
  150. console.log(`[BurnEffect] 销毁灼烧特效节点`);
  151. this._burnEffectNode.destroy();
  152. this._burnEffectNode = null;
  153. }
  154. // 通过事件通知灼烧效果结束
  155. const eventBus = EventBus.getInstance();
  156. eventBus.emit(GameEvents.BURN_EFFECT_ENDED, {
  157. enemyNode: this.node,
  158. burnTimerId: this._burnTimerId
  159. });
  160. console.log(`[BurnEffect] 灼烧效果已停止`);
  161. // 移除组件
  162. if (this.node && this.node.isValid) {
  163. this.node.removeComponent(BurnEffect);
  164. }
  165. }
  166. /**
  167. * 获取灼烧效果是否激活
  168. */
  169. public isActive(): boolean {
  170. return this._isActive;
  171. }
  172. /**
  173. * 组件销毁时清理定时器
  174. */
  175. protected onDestroy(): void {
  176. this._isActive = false;
  177. // 取消所有定时器
  178. this.unscheduleAllCallbacks();
  179. // 清理灼烧特效节点
  180. if (this._burnEffectNode && this._burnEffectNode.isValid) {
  181. console.log(`[BurnEffect] 组件销毁时清理灼烧特效节点`);
  182. this._burnEffectNode.destroy();
  183. this._burnEffectNode = null;
  184. }
  185. console.log(`[BurnEffect] 灼烧效果组件已销毁,清理定时器`);
  186. }
  187. }