bullet.ts 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. import { NODATA } from "dns";
  2. import { cocosz } from "../Framework/CocosZ";
  3. import { ZindexLayer } from "../Framework/Constant";
  4. import { gameMgr } from "./gameMgr";
  5. import Person from "./person";
  6. const { ccclass, property } = cc._decorator;
  7. @ccclass
  8. export default class Bullet extends cc.Component {
  9. @property()
  10. bulletId: number = 0;
  11. id: number = 1;
  12. atk: number = 10;
  13. atker: cc.Node = null
  14. @property()
  15. canMove: boolean = true;
  16. @property({ tooltip: "能否阻断" })
  17. canBreak: boolean = true;
  18. @property({ tooltip: "能否穿透敌人" })
  19. canPenetrate: boolean = false;
  20. @property({ tooltip: "能否穿透墙壁" })
  21. canWall: boolean = false;
  22. @property(cc.Prefab)
  23. boomEffect: cc.Prefab = null;
  24. @property(cc.Prefab)
  25. hitEffect: cc.Prefab = null;
  26. @property({ type: cc.String, tooltip: "子弹音效" })
  27. hitAudio: string = "";
  28. @property({ tooltip: "敌人受伤是否发出音效" })
  29. isHartMusic: boolean = true;
  30. @property()
  31. hitEffectType: number = 0;
  32. // LIFE-CYCLE CALLBACKS:
  33. @property()
  34. hartInterval: number = 0;
  35. @property({ tooltip: "击中效果设置角度" })
  36. isHitEffectAngle: boolean = false;
  37. @property({ tooltip: "每帧设置角度" })
  38. isAngle: boolean = false;
  39. @property({ tooltip: "是否爆炸子弹" })
  40. isBoom: boolean = false;
  41. @property({ tooltip: "是否记录受伤者" })
  42. isRecord: boolean = true;
  43. // 方向
  44. dir: cc.Vec2 = null;
  45. start() {
  46. gameMgr && gameMgr.setMapTs.checkNode(this.node, true);
  47. if (this.node.zIndex == 0) {
  48. if (this.isBoom) {
  49. this.node.zIndex = ZindexLayer.zindex_bomb;
  50. }
  51. else if ("liewen" === this.node.name) {
  52. this.node.zIndex = ZindexLayer.zinedx_floorLiewen;
  53. } else {
  54. this.node.zIndex = ZindexLayer.zindex_bullet + this.bulletId;
  55. }
  56. }
  57. // gameMgr
  58. if (this.node.name == "bullet_sd" || this.node.name == "bullet_hdl") {
  59. let box = this.node.getComponent(cc.BoxCollider)
  60. if (box) {
  61. cc.tween(box.size).to(0.3, { height: 550 }).start();
  62. cc.tween(box.offset).to(0.3, { x: 700 }).start();
  63. }
  64. }
  65. }
  66. protected onDisable(): void {
  67. this._lastPos = null;
  68. }
  69. private _lastPos: cc.Vec2 = null;
  70. protected lateUpdate(dt: number): void {
  71. // 每帧设置角度
  72. if (this.isAngle) {
  73. if (this._lastPos) {
  74. let div = this.node.getPosition().subSelf(this._lastPos);
  75. if (false == div.equals(cc.Vec2.ZERO)) {
  76. this.node.angle = -cc.v2(div).signAngle(cc.v2(1, 0)) / Math.PI * 180;
  77. this._lastPos = this.node.getPosition();
  78. }
  79. } else {
  80. this._lastPos = this.node.getPosition();
  81. }
  82. }
  83. }
  84. // 已攻击对象
  85. atkedArr: cc.Node[] = [];
  86. onCollisionEnter(other: any, self: any) {
  87. if (other.tag == 1) {
  88. let ts = other.getComponent(Person)
  89. if (ts.id == this.id) {
  90. return;
  91. }
  92. // 能倍阻断并且不能穿透玩家
  93. if (this.canBreak && !this.canPenetrate) {
  94. this.node.destroy();
  95. } else {
  96. if (this.atkedArr.includes(other.node)) {
  97. return;
  98. } else if (this.isRecord) {
  99. this.atkedArr.push(other.node);
  100. }
  101. }
  102. // 击中效果
  103. if (this.hitEffect && !cocosz.isPause) {
  104. let node = cc.instantiate(this.hitEffect);
  105. node.zIndex = ZindexLayer.zindex_effect_hit;
  106. if (this.hitEffectType == 1) {
  107. node.parent = other.node;
  108. // 击中特效方向
  109. if (this.isHitEffectAngle) {
  110. node.angle = -cc.v2(this.dir).signAngle(cc.v2(1, 0)) / Math.PI * 180;
  111. }
  112. }
  113. else {
  114. let pos = this.node.getPosition();
  115. let dt = this.node.width;
  116. if (dt < 5) {
  117. let box = this.node.getComponent(cc.BoxCollider);
  118. if (box) {
  119. dt += box.offset.x;
  120. }
  121. }
  122. pos = pos.add(cc.v2(dt, 0).rotate(this.node.angle / 180 * Math.PI));
  123. node.parent = this.node.parent;
  124. node.setPosition(pos);
  125. }
  126. if (this.hitAudio) {
  127. gameMgr.playEffect(this.hitAudio, this.node);
  128. }
  129. }
  130. // 爆炸效果
  131. if (this.boomEffect) {
  132. let boom = cc.instantiate(this.boomEffect)
  133. boom.parent = this.node.parent;
  134. boom.setPosition(this.node.getPosition());
  135. boom.zIndex = ZindexLayer.zindex_bomb;
  136. gameMgr.playEffect("explo", boom);
  137. let bullet = boom.getComponent(Bullet);
  138. bullet.atk = this.atk;
  139. bullet.atker = this.atker;
  140. bullet.id = this.id;
  141. bullet.dir = this.dir;
  142. return;
  143. }
  144. // 血液效果
  145. if (gameMgr.blood && self.world && self.world.points && self.world.points[0]) {
  146. let blood: cc.Node = null;
  147. blood = cc.instantiate(gameMgr.blood);
  148. blood.parent = gameMgr.map;
  149. blood.zIndex = ZindexLayer.zindex_blood;;
  150. let pos: cc.Vec2 = blood.parent.convertToNodeSpaceAR(cc.v2(self.world.points[0].x, self.world.points[0].y));
  151. if (this.dir) {
  152. let angle = -cc.v2(this.dir).signAngle(cc.v2(0, 1)) / Math.PI * 180;
  153. blood.angle = angle;
  154. }
  155. blood.setPosition(pos);
  156. }
  157. // 击退
  158. if (this.isBoom) {
  159. let dir = other.node.getPosition().subSelf(this.node.getPosition()).normalizeSelf();
  160. // 方向为0,随机方向
  161. if (dir.equals(cc.Vec2.ZERO)) {
  162. dir = cc.v2(1, 0).rotateSelf(2 * Math.PI * Math.random());
  163. }
  164. this.dir = dir.mulSelf(3);
  165. } else if (!this.canMove && this.dir && this.dir.mag() < 2) {
  166. this.dir.normalizeSelf().mulSelf(2);
  167. }
  168. // 敌人受伤
  169. ts.hart(this.atk, this.atker, this.dir, this.isHartMusic);
  170. if (this.hartInterval) {
  171. this.schedule(() => {
  172. if (ts && ts.isValid && this.atkedArr.includes(ts.node)) {
  173. ts.hart(this.atk, this.atker, this.dir, this.isHartMusic);
  174. }
  175. }, this.hartInterval)
  176. }
  177. }
  178. // 障碍物
  179. else if (other.tag == 5) {
  180. // 爆炸效果
  181. if (this.boomEffect) {
  182. let boom = cc.instantiate(this.boomEffect)
  183. boom.parent = this.node.parent;
  184. boom.setPosition(this.node.getPosition());
  185. let bullet = boom.getComponent(Bullet);
  186. bullet.atk = this.atk;
  187. bullet.atker = this.atker;
  188. bullet.id = this.id;
  189. gameMgr.playEffect("explo", boom);
  190. }
  191. // 销毁子弹
  192. if (this.canBreak && !this.canWall) {
  193. let pos = this.node.getPosition();
  194. let dt = this.node.width;
  195. if (dt < 5) {
  196. let box = this.node.getComponent(cc.BoxCollider);
  197. if (box) { dt += box.offset.x; }
  198. }
  199. pos = pos.add(cc.v2(dt, 0).rotate(this.node.angle / 180 * Math.PI));
  200. if (this.hitEffect && this.hitEffectType != 1) {
  201. let node = cc.instantiate(this.hitEffect);
  202. node.parent = this.node.parent;
  203. node.setPosition(pos);
  204. node.zIndex = ZindexLayer.zindex_effect_hit;
  205. }
  206. else {
  207. let node = cc.instantiate(gameMgr.spark);
  208. node.parent = this.node.parent;
  209. node.setPosition(pos);
  210. node.zIndex = ZindexLayer.zindex_effect_spark;
  211. }
  212. this.node.destroy();
  213. }
  214. }
  215. }
  216. }