zombieObject.ts 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. import npcHelper from "../../../dataManager/npcHelper";
  2. import { Log, LOG_TAG } from "../../../framework/log/Log";
  3. import dungeonLogic from "../../dungeonLogic";
  4. import LevelLogic from "../../levelLogic";
  5. import gameData from "../../utrl/gameData";
  6. import { EVENT_TYPE, GAME_OBJECT_TYPE, ROLE_STATE } from "../../utrl/gameEnum";
  7. import gameEventManager from "../../utrl/gameEventManager";
  8. import GameObject from "../gameObject";
  9. import PlayerObject from "../player/playerObject";
  10. import ZombieProp from "./zombieProp";
  11. import zombieView from "./zombieView";
  12. const { ccclass, requireComponent, property } = cc._decorator;
  13. /**僵尸实体类 */
  14. @ccclass
  15. @requireComponent(cc.RigidBody)
  16. export default class ZomBieObject extends GameObject {
  17. /**僵尸血条 */
  18. @property(cc.Node)
  19. cur_hp_bar: cc.Node = null;
  20. @property
  21. /**移动速度 */
  22. speed = 50;
  23. /**逻辑方法组件 */
  24. zombie_prop: ZombieProp = null;
  25. /**初始化完成 */
  26. private inited = false;
  27. /**本身刚体 */
  28. private rigid: cc.RigidBody = null;
  29. /**视图逻辑 */
  30. public zombie_view: zombieView = null;
  31. /**角色组,0玩家组,1僵尸组 */
  32. private roles: cc.Node[][] = [[], []];
  33. private barScaleX = 1;
  34. attackCb: () => void;
  35. canWalk: boolean = true; //是否可以行走
  36. isDie: boolean = false;
  37. isPause: boolean = false;
  38. isInUI: boolean = false;
  39. onEnable() {
  40. this.rigid = this.node.getComponent(cc.RigidBody);
  41. // this.rigid.type = cc.RigidBodyType.Dynamic;
  42. gameEventManager.on(EVENT_TYPE.CHANGE_STATUS, this.changeStatue, this)
  43. this.rigid.gravityScale = 0;
  44. this.rigid.linearDamping = 5;
  45. this.rigid.fixedRotation = true;
  46. this.attackCb = () => {
  47. this.zombie_view.playIdle();
  48. this.canWalk = true; //攻击播放完才行走
  49. }
  50. }
  51. onDisable() {
  52. gameEventManager.off(EVENT_TYPE.CHANGE_STATUS, this.changeStatue, this);
  53. }
  54. changeStatue(flag) {
  55. this.isPause = flag;
  56. }
  57. update(dt: number) {
  58. if (this.isPause) {
  59. return;
  60. }
  61. if (this.roles[0] == null || this.roles[1] == null) { return; }
  62. this.cur_hp_bar.parent.scaleX = this.node.scaleX * this.barScaleX;
  63. let p = this.zombie_prop.cur_hp / this.zombie_prop.base_hp;
  64. if (p == 1 || p == 0) {
  65. this.cur_hp_bar.parent.active = false;
  66. }
  67. else {
  68. this.cur_hp_bar.parent.active = true;
  69. this.cur_hp_bar.width = this.cur_hp_bar.parent.width * p;
  70. }
  71. if (!this.inited) {
  72. return;
  73. }
  74. this.runState(dt);
  75. }
  76. /**初始化 */
  77. init(id: number, pos: cc.Vec3, roles: cc.Node[][], isPause?, isInUI?) {
  78. this.isPause = isPause;
  79. this.type = GAME_OBJECT_TYPE.zombie;
  80. if (this.zombie_prop == null) {
  81. this.zombie_prop = new ZombieProp();
  82. }
  83. if (isInUI) {
  84. this.isInUI = isInUI;
  85. }
  86. this.zombie_prop.init(id);
  87. this.zombie_view = this.node.getComponent(zombieView);
  88. this.zombie_view.init(id);
  89. this.node.setPosition(pos);
  90. this.setBarView();
  91. this.roles = roles;
  92. this.inited = true;
  93. this.node.active = true;
  94. this.isDie = false;
  95. }
  96. setBarView() {
  97. let curID = this.zombie_prop.zombie_ID;
  98. if (npcHelper.isBoss(curID)) {
  99. if (curID == 54) {
  100. this.cur_hp_bar.parent.y += 100;
  101. } else {
  102. this.cur_hp_bar.parent.y += 200;
  103. }
  104. this.barScaleX = 2;
  105. this.cur_hp_bar.parent.scaleY = 2;
  106. }
  107. }
  108. /**运行状态机 */
  109. runState(dt: number) {
  110. let target = this.getCloseTarget(this.roles[0], this.zombie_prop.search_range);
  111. if (target != null) {
  112. let cbk = () => {
  113. this.attack(target);
  114. };
  115. let len = target.position.sub(this.node.position).mag();
  116. if (len < this.zombie_prop.hand_range) {
  117. this.rigid.type = cc.RigidBodyType.Animated;
  118. // this.zombie_view.playIdle();
  119. this.zombie_prop.attackRun(dt, cbk);
  120. }
  121. else {
  122. this.rigid.type = cc.RigidBodyType.Dynamic;
  123. this.moveToTarget(target);
  124. if (this.canWalk) {
  125. this.zombie_view.playWalk();
  126. }
  127. }
  128. if (this.node.x > target.x) {
  129. this.zombie_view.node.scaleX = 1;
  130. }
  131. else {
  132. this.zombie_view.node.scaleX = -1;
  133. }
  134. }
  135. else {
  136. this.zombie_view.playIdle();
  137. let o = 5
  138. if (this.rigid.linearVelocity.x > o) {
  139. this.zombie_view.node.scaleX = -1;
  140. }
  141. else if (this.rigid.linearVelocity.x < -o) {
  142. this.zombie_view.node.scaleX = 1;
  143. }
  144. }
  145. }
  146. attack(target) {
  147. if (this.zombie_prop.zombie_ID == 56) {
  148. Log.log(LOG_TAG.DEBUG, '生成怪物攻击');
  149. this.zombie_view.playAttack(this.attackCb);
  150. this.scheduleOnce(() => {
  151. gameEventManager.emit(EVENT_TYPE.BOSS_SKIN_ADDZOMBIE, 3, this.node)
  152. }, 0.2);
  153. } else if (this.zombie_prop.zombie_ID == 53) {
  154. Log.log(LOG_TAG.DEBUG, '子弹攻击');
  155. this.zombie_view.playAttack(this.attackCb);
  156. this.scheduleOnce(() => {
  157. gameEventManager.emit(EVENT_TYPE.zombie_boom, this.node.position, target.position, 3, this.zombie_prop.base_damage)
  158. }, 0.2);
  159. } else if (this.zombie_prop.zombie_ID == 46) {
  160. Log.log(LOG_TAG.DEBUG, '子弹攻击');
  161. this.zombie_view.playAttack(this.attackCb);
  162. this.scheduleOnce(() => {
  163. gameEventManager.emit(EVENT_TYPE.zombie_boom, cc.v3(this.node.x, this.node.y - 200), target.position, 1, this.zombie_prop.base_damage)
  164. }, 0.2);
  165. } else {
  166. Log.log(LOG_TAG.DEBUG, '普通攻击');
  167. this.canWalk = false;
  168. let ts = this.getAliiCloseTargets(this.roles[0], this.zombie_prop.hand_range);
  169. this.zombie_view.playAttack(this.attackCb);
  170. this.scheduleOnce(() => {
  171. for (let t of ts) {
  172. if (!t || !cc.isValid(t)) {
  173. break;
  174. }
  175. let comp = t.getComponent(PlayerObject);
  176. if (comp.isDie) {
  177. break;
  178. }
  179. let bDie = this.zombie_prop.attack(comp, this.zombie_prop.base_damage);
  180. if (bDie) {
  181. //目标死亡
  182. comp.die();
  183. }
  184. else {
  185. let curWeapon = comp.player_prop.cur_weapon;
  186. let id = curWeapon ? curWeapon.id : null;
  187. comp.player_view.playBeHurt(id);
  188. }
  189. }
  190. }, 0.5)
  191. }
  192. }
  193. /**范围内最近目标 */
  194. private getCloseTarget(nds: cc.Node[], range: number): cc.Node {
  195. let target: cc.Node = null;
  196. for (let nd of nds) {
  197. if (!nd.isValid) { continue; }
  198. let len = nd.position.sub(this.node.position).mag();
  199. if (len < range) {
  200. range = len;
  201. target = nd;
  202. }
  203. }
  204. return target;
  205. }
  206. /**范围内所有目标 */
  207. private getAliiCloseTargets(nds: cc.Node[], range: number): cc.Node[] {
  208. let targets: cc.Node[] = [];
  209. for (let nd of nds) {
  210. if (!nd.isValid) { continue; }
  211. let len = nd.position.sub(this.node.position).mag();
  212. if (len < range) {
  213. targets.push(nd);
  214. }
  215. }
  216. return targets;
  217. }
  218. /**向目标移动
  219. * @param target 目标
  220. */
  221. private moveToTarget(target: cc.Node) {
  222. let v_sub = target.position.sub(this.node.position).normalize();
  223. let rad = Math.acos(v_sub.x);
  224. if (v_sub.y < 0) {
  225. rad = Math.PI * 2 - rad;
  226. }
  227. this.setLinearVelocity(rad);
  228. }
  229. /**设置刚体线性速度
  230. * @param rad 弧度角
  231. */
  232. private setLinearVelocity(rad: number) {
  233. this.rigid.linearVelocity = cc.v2(Math.cos(rad), Math.sin(rad)).mul(this.speed);
  234. }
  235. }