Bullet.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import { _decorator, Animation, AnimationClip, BoxCollider2D, Collider2D, Component, Contact2DType, ICollisionEvent, IPhysics2DContact, Node, PhysicsSystem2D, SpriteFrame, UITransform } from 'cc';
  2. import { Tools } from '../../Tools/Tools';
  3. import { LifeBar } from './LifeBar';
  4. const { ccclass, property } = _decorator;
  5. @ccclass('Bullet')
  6. export class Bullet extends Component {
  7. explodeframes: SpriteFrame[] = [];
  8. bulletFrames: SpriteFrame[] = [];
  9. explodeAni: Animation = null;
  10. bulletAni: Animation = null;
  11. //是否爆炸 true -> 爆炸
  12. isExplode: boolean = false;
  13. //子弹速度
  14. bulletSpeed: number = 100;
  15. //子弹方向
  16. direction: number = 1;
  17. //攻击力
  18. atk: number = null;
  19. //被攻击的节点
  20. targetNode: Node = null;
  21. //是否碰撞
  22. private _hasCollided: boolean = false;
  23. protected onLoad(): void {
  24. const collider = this.getComponent(Collider2D);
  25. if (collider) {
  26. //collider.on(Contact2DType.BEGIN_CONTACT, this._onBeginContact, this)
  27. }
  28. }
  29. start() {
  30. this.explodeAni = Tools.createAnimation(this.explodeframes, 5, this.node, AnimationClip.WrapMode.Normal);
  31. this.bulletAni = Tools.createAnimation(this.bulletFrames, 5, this.node, AnimationClip.WrapMode.Loop);
  32. //this.node.setPosition(0, 0, 0);
  33. this.setState(false);
  34. }
  35. setState(isExplode: boolean) {
  36. if (isExplode) {
  37. this.bulletSpeed = 0;
  38. this.explodeAni.play();
  39. this.explodeAni.once(Animation.EventType.FINISHED, () => {
  40. this.node.destroy()
  41. },
  42. this.node)
  43. } else {
  44. this.bulletAni.play();
  45. }
  46. }
  47. _onBeginContact(otherCollider: BoxCollider2D) {
  48. const lifeBar = this.targetNode.getComponent(LifeBar);
  49. lifeBar.updateProgressBar(lifeBar._curHp - this.atk);
  50. this.setState(true);
  51. }
  52. update(deltaTime: number) {
  53. this.move(deltaTime);
  54. this.onBulletCollision(this.targetNode);
  55. }
  56. move(dt: number) {
  57. let x = this.node.getWorldPosition().x;
  58. let y = this.node.getWorldPosition().y;
  59. let z = this.node.getWorldPosition().z;
  60. if (this.direction) {
  61. x = x + this.bulletSpeed * dt;
  62. } else {
  63. x = x - this.bulletSpeed * dt;
  64. }
  65. this.node.setWorldPosition(x, y, z)
  66. }
  67. // 处理子弹碰撞
  68. onBulletCollision(targetNode: Node) {
  69. if(this._hasCollided) return;
  70. if(!targetNode.isValid) return;
  71. const boxBullet = this.node.getComponent(UITransform).getBoundingBoxToWorld();
  72. const boxTarget = targetNode.getComponent(UITransform).getBoundingBoxToWorld();
  73. if (boxTarget.containsRect(boxBullet)) {
  74. const targetLifeBar = targetNode.getComponent(LifeBar);
  75. if((targetLifeBar._curHp - this.atk) <= 0){
  76. this.targetNode.destroy();
  77. this.node.destroy();
  78. }
  79. targetLifeBar.updateProgressBar(targetLifeBar._curHp - this.atk);
  80. this._hasCollided = true;
  81. this.setState(true);
  82. }
  83. }
  84. //targetNode为目标节点,子弹需要攻击的对象
  85. //如果子弹与targetNode碰撞,targetNode的hp(血量)将会减少子弹发射者的atk(攻击力);
  86. //同时子弹播放爆炸动画,播放结束后,子弹销毁
  87. }