Bullet.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { _decorator, Component, Sprite, SpriteFrame, UITransform, v3, Vec3, sp, Quat } from 'cc';
  2. import { DataSystem } from '../core/data/DataSystem';
  3. import { ResourceLoader } from '../core/resourceManager/ResourceLoader';
  4. import { ConfigData } from '../data/ConfigData';
  5. import { BattleData, BattleState } from './BattleData';
  6. import { BulletData } from './BulletData';
  7. import { Monster } from './Monster';
  8. const { ccclass, property } = _decorator;
  9. @ccclass('Bullet')
  10. export class Bullet extends Component {
  11. @property({ type: Sprite, tooltip: "子弹资源" }) bulletSprite: Sprite;
  12. @property({ type: sp.Skeleton, tooltip: "受击特效" }) hitEffect: sp.Skeleton;
  13. @property({ type: [sp.SkeletonData], tooltip: "受击特效集合" }) hitArray: Array<sp.SkeletonData> = [];
  14. @property({ type: [SpriteFrame], tooltip: "子弹精灵集合" }) bulletSprites: Array<SpriteFrame> = [];
  15. private _battle: BattleData;
  16. private data: BulletData;
  17. private target: Monster;
  18. private config: any;
  19. private beenHit = false;
  20. private get battle(): BattleData {
  21. if (!this._battle) {
  22. this._battle = DataSystem.getData(BattleData);
  23. }
  24. return this._battle;
  25. }
  26. async start() {
  27. this.config = DataSystem.getData(ConfigData)["skill"];
  28. }
  29. update(dt: number) {
  30. if (this.target && this.target.node && this.battle.battleState == BattleState.inBattle) {
  31. if (!this.beenHit) {
  32. this.move();
  33. this.look();
  34. this.checkHit();
  35. }
  36. } else {
  37. this.node.destroy();
  38. }
  39. }
  40. public async setData(data: BulletData) {
  41. this.data = data;
  42. if (this.data) {
  43. // this.hitEffect = this.node.addComponent(sp.Skeleton);
  44. let spData = this.hitArray[this.data.hit_res - 1];
  45. this.hitEffect.skeletonData = spData;
  46. this.target = DataSystem.getData(BattleData)._monsters[this.data.target];
  47. this.bulletSprite.spriteFrame = this.bulletSprites[data.res - 1];
  48. let direction = this.battle.slots.get(data.from)._direction;
  49. let offset = direction == 1 ? -this.battle.slots.get(data.from).node.getComponent(UITransform).width / 2 : this.battle.slots.get(data.from).node.getComponent(UITransform).width / 2;
  50. this.node.scale = this.battle.slots.get(data.from).node.scale;
  51. this.node.setPosition(v3(this.battle.slots.get(data.from).node.position).add(v3(offset, 0, 0)));
  52. this.bulletSprite.node.scale.multiplyScalar(this.data.isLeader ? 1 : 0.8);
  53. }
  54. }
  55. /**子弹转向 */
  56. private look(): void {
  57. let radian = 0;
  58. let node = this.target.node;
  59. let tran = this.target.node.getComponent(UITransform);
  60. if (this.node.scale.x < 0) {
  61. radian = Math.atan2((node.position.y + tran.height / 2) - this.node.position.y, node.position.x - this.node.position.x);
  62. }
  63. else {
  64. radian = Math.PI - Math.atan2(this.target.node.position.y - this.node.position.y, this.target.node.position.x - this.node.position.x);
  65. if (radian > Math.PI) {
  66. radian -= Math.PI * 2;
  67. }
  68. radian = -radian;
  69. }
  70. let distance = Vec3.distance(this.node.position, v3(this.target.node.position.clone().add(v3(0, this.target.getComponent(UITransform).height * this.target.node.scale.y / 20, 0))));
  71. if (distance > 150 || this.node.rotation.z == 0) {//位置接近时,停止转向
  72. this.node.setRotationFromEuler(v3(0, 0, 180 / Math.PI * radian));
  73. } else {
  74. this.node.setRotation(this.node.rotation);
  75. }
  76. }
  77. /**子弹移动 */
  78. private move(): void {
  79. let node = this.target.node;
  80. let tran = this.target.node.getComponent(UITransform);
  81. let angle = Math.atan2((node.position.y + tran.height * node.scale.y / 2) - this.node.position.y, node.position.x - this.node.position.x);
  82. this.node.position.add(v3(Math.cos(angle) * this.data.speed, Math.sin(angle) * this.data.speed, 0));
  83. }
  84. /**检查是否击中 */
  85. private checkHit() {
  86. let targetPosition = this.target.node.position.clone();
  87. targetPosition.y += this.target.getComponent(UITransform).height * this.target.node.scale.y / 2;
  88. let distance = Vec3.distance(this.node.position, targetPosition);
  89. if (distance <= 10) {
  90. this.hit();
  91. }
  92. }
  93. /**击中 */
  94. private async hit() {
  95. this.beenHit = true;
  96. let node = this.target.node;
  97. let tran = this.target.node.getComponent(UITransform);
  98. this.node.position = v3(node.position.x, node.position.y + tran.height * node.scale.y / 2, node.position.z);
  99. this.bulletSprite.node.active = false;
  100. this.node.setRotationFromEuler(v3(0, 0, 0));
  101. this.hitEffect.addAnimation(0, "animation", false);
  102. this.hitEffect.setCompleteListener(() => {
  103. let config = this.config[this.data.skillID]["attType"];
  104. let type = parseInt(config.split(":")[0]);
  105. if (type == 1) {
  106. DataSystem.getData(BattleData)._hitMonster.push(this.data);
  107. } else {
  108. this.pushRangeMonsterToHit();
  109. }
  110. this.node.destroy();
  111. });
  112. }
  113. /**将攻击范围内的敌人放入受击容器 */
  114. private pushRangeMonsterToHit(): void {
  115. let node = this.target.node;
  116. let config = this.config[this.data.skillID]["attType"];
  117. let range = parseInt(config.split(":")[1].split(",")[0]);
  118. let maxCount = parseInt(config.split(":")[1].split(",")[1]);
  119. let monsters = DataSystem.getData(BattleData)._monsters;
  120. let result = [];
  121. for (let i = 0; i < monsters.length; i++) {
  122. if (Vec3.distance(node.position, monsters[i].node.position) <= range) {
  123. if (result.length < maxCount - 1) {
  124. result.push(i);
  125. }
  126. }
  127. }
  128. DataSystem.getData(BattleData)._hitMonster.push(this.data);
  129. for (let j = 0; j < result.length; j++) {
  130. DataSystem.getData(BattleData)._hitMonster.push(this.data);
  131. }
  132. }
  133. }