EnemyComponent.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import { _decorator, CCBoolean, CCFloat, Collider, Component, isValid, ITriggerEvent, Material, MeshRenderer, Node, PhysicsSystem, Quat, RigidBody, tween, Tween, Vec3 } from 'cc';
  2. import { EventDispatcher } from 'db://assets/core_tgx/easy_ui_framework/EventDispatcher';
  3. import { GameEvent } from '../Enum/GameEvent';
  4. import { GameUtil } from '../GameUtil';
  5. const { ccclass, property } = _decorator;
  6. export enum EnemyStatus {
  7. LIFE,
  8. DIE
  9. }
  10. @ccclass('EnemyComponent')
  11. export class EnemyComponent extends Component {
  12. @property(RigidBody)
  13. rigidBody: RigidBody = null!;
  14. @property(Node)
  15. head: Node = null!;
  16. @property(Node)
  17. body: Node = null!;
  18. @property(Node)
  19. leftHand: Node = null!;
  20. @property(Node)
  21. rightHand: Node = null!;
  22. @property(Node)
  23. leftFoot: Node = null!;
  24. @property(Node)
  25. rightFoot: Node = null!;
  26. @property(Node)
  27. leftHandGuge: Node = null!;
  28. @property(Node)
  29. rightHandGuge: Node = null!;
  30. @property(Node)
  31. leftFootGuge: Node = null!;
  32. @property(Node)
  33. rightFootGuge: Node = null!;
  34. @property(Material)
  35. hitMaterial: Material = null!;
  36. currentHp: number = 0;
  37. status: EnemyStatus = EnemyStatus.LIFE;
  38. speed: number = 50;
  39. headshot: boolean = false;
  40. tigger: Collider = null!;
  41. protected onLoad(): void {
  42. this.tigger = this.node.getComponent(Collider)!;
  43. }
  44. start() {
  45. this.status = EnemyStatus.LIFE;
  46. this.tigger = this.node.getComponent(Collider)!;
  47. this.rigidBody.isKinematic = true;
  48. this.registerEvent();
  49. }
  50. private registerEvent() {
  51. this.tigger.on('onTriggerEnter', this.onTriggerEnter, this);
  52. EventDispatcher.instance.on(GameEvent.EVENT_CAMERA_SHOOT_ENEMY, this.onShootEnemy, this);
  53. }
  54. private unRegisterEvent() {
  55. this.tigger.off('onTriggerEnter', this.onTriggerEnter, this);
  56. }
  57. protected onTriggerEnter(event: ITriggerEvent): void {
  58. }
  59. private async onShootEnemy(hitNode: Node) {
  60. // 检查是否是当前怪物节点被击中
  61. if (this.node === hitNode && this.status === EnemyStatus.LIFE) {
  62. this.status = EnemyStatus.DIE;
  63. // 修改所有部位材质为击中材质
  64. this.changeMaterial(this.head);
  65. this.changeMaterial(this.body);
  66. this.changeMaterial(this.leftHand);
  67. this.changeMaterial(this.rightHand);
  68. this.changeMaterial(this.leftFoot);
  69. this.changeMaterial(this.rightFoot);
  70. this.playHitTwitch();
  71. await GameUtil.delay(0.5);
  72. this.rigidBody.isKinematic = false;
  73. this.rigidBody.isDynamic = true;
  74. await GameUtil.delay(0.3);
  75. this.node.destroy();
  76. }
  77. }
  78. private changeMaterial(node: Node) {
  79. if (!node || !this.hitMaterial) return;
  80. const renderer = node.getComponent(MeshRenderer);
  81. if (renderer) {
  82. renderer.material = this.hitMaterial;
  83. }
  84. }
  85. // 中枪抽搐效果
  86. playHitTwitch() {
  87. // 抖动参数配置
  88. const shakeConfig = {
  89. head: { times: 5, duration: 0.12, axis: 'x' },
  90. leftHand: { times: 6, duration: 0.1, axis: 'y' },
  91. rightHand: { times: 6, duration: 0.15, axis: 'y' },
  92. leftFoot: { times: 4, duration: 0.1, axis: 'y' },
  93. rightFoot: { times: 4, duration: 0.1, axis: 'y' }
  94. };
  95. // 生成随机抖动值
  96. const getRandomShake = () => (10 + Math.random() * 10) * (Math.random() > 0.5 ? 1 : -1);
  97. // 创建抖动动画函数
  98. const createShakeTween = (node: Node, config: { times: number, duration: number, axis: string }) => {
  99. const rotation = node.rotation.clone();
  100. const t = tween(node);
  101. for (let i = 0; i < config.times; i++) {
  102. const shakeValue = getRandomShake();
  103. let newRotation = rotation.clone();
  104. if (config.axis === 'x') {
  105. newRotation = Quat.fromEuler(new Quat(), -90 + getRandomShake(), rotation.y, rotation.z);
  106. } else {
  107. newRotation = Quat.fromEuler(new Quat(), 90, rotation.y + shakeValue, rotation.z);
  108. }
  109. t.to(config.duration, { rotation: newRotation });
  110. }
  111. return t;
  112. };
  113. // 头部抖动
  114. createShakeTween(this.head, shakeConfig.head).start();
  115. // 左手抖动
  116. createShakeTween(this.leftHandGuge, shakeConfig.leftHand).start();
  117. // 右手抖动
  118. createShakeTween(this.rightHandGuge, shakeConfig.rightHand).start();
  119. // 左腿抖动
  120. createShakeTween(this.leftFootGuge, shakeConfig.leftFoot).start();
  121. // 右腿抖动
  122. createShakeTween(this.rightFootGuge, shakeConfig.rightFoot).start();
  123. }
  124. protected onDestroy(): void {
  125. Tween.stopAllByTarget(this.node);
  126. this.unRegisterEvent();
  127. }
  128. }