Hero.ts 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import { _decorator, Component, sp, Sprite, Label, ProgressBar, SpriteFrame, Node, SystemEvent, Prefab, instantiate } from 'cc';
  2. import { DataSystem } from '../core/data/DataSystem';
  3. import { ResourceLoader } from '../core/resourceManager/ResourceLoader';
  4. import { Sound } from '../core/sound/Sound';
  5. import { OpenWindow } from '../core/ui/window/OpenWindow';
  6. import { ConfigData } from '../data/ConfigData';
  7. import { BattleData, BattleState } from './BattleData';
  8. import { Buff } from './Buff';
  9. import { BulletData } from './BulletData';
  10. import { CommandSpine } from './CommandSpine';
  11. import { HeroData } from './HeroData';
  12. import { HeroSlotState } from './HeroSlot';
  13. import { MissionData } from './MissionData';
  14. const { ccclass, property } = _decorator;
  15. @ccclass('Hero')
  16. export class Hero extends Component {
  17. @property({ tooltip: "英雄插槽ID" }) slotID: number = 0;
  18. @property({ type: ResourceLoader, tooltip: "资源加载组件" }) res: ResourceLoader;
  19. @property({ type: Sprite, tooltip: "阵营图标" }) camp: Sprite;
  20. @property({ type: Label, tooltip: "星级" }) starLabel: Label;
  21. @property({ type: Label, tooltip: "等级" }) lvLabel: Label;
  22. @property({ type: ProgressBar, tooltip: "等级进度" }) lvProgress: ProgressBar;
  23. @property({ type: Node, tooltip: "UI组" }) uiGroup: Node;
  24. @property({ type: OpenWindow, tooltip: "窗口打开组件" }) open: OpenWindow;
  25. @property({ type: Node, tooltip: "特效层" }) layer: Node;
  26. public data: HeroData;
  27. private battle: BattleData;
  28. private spine: sp.Skeleton;
  29. private config: any;
  30. private skillConfig: any;
  31. /**音效组件 */
  32. private sound: Sound;
  33. start() {
  34. this.sound = this.getComponent(Sound);
  35. this.config = DataSystem.getData(ConfigData)["general"];
  36. this.skillConfig = DataSystem.getData(ConfigData)["skill"];
  37. this.data = new HeroData();
  38. this.battle = DataSystem.getData(BattleData);
  39. DataSystem.regeditData(this.data);
  40. this.battle.heros.set(this.slotID, this.data);
  41. this.data._buff = this.getComponent(Buff);
  42. this.spine = this.node.getComponent(sp.Skeleton);
  43. }
  44. update(dt) {
  45. DataSystem.watch(this.data, "id") && this.changeHero();
  46. DataSystem.watch(this.data, "lv") && this.lvUp();
  47. DataSystem.watch(this.data, "starLv") && this.updataHero();
  48. DataSystem.watch(this.data, "lvProgress") && this.updataHero();
  49. DataSystem.watch(this.data, "_addBuff") && this.addBuff();
  50. (this.spine && this.data.id) && this.checkAttack(dt);
  51. }
  52. /**更换英雄 */
  53. private async changeHero() {
  54. if (this.data.id != this.data._curID) {
  55. if (!this.data.id) {
  56. this.data._curID = 0;
  57. this.spine && this.spine.destroy();
  58. this.uiGroup.active = false;
  59. this.battle.slots.get(this.slotID)._state = HeroSlotState.empty;
  60. this.node.off(SystemEvent.EventType.TOUCH_END, () => { this.open.open() }, this);
  61. return;
  62. }
  63. if (this.spine) {
  64. this.spine.destroy();
  65. }
  66. this.data._curID = this.data.id;
  67. this.scheduleOnce(async () => {
  68. this.spine = this.node.addComponent(sp.Skeleton);
  69. let spData = await this.res.load<sp.SkeletonData>("spine/hero/" + this.config[this.data.id]["hero_res"], sp.SkeletonData);
  70. this.spine.skeletonData = spData;
  71. this.spine.setAnimation(0, "idle", true);
  72. }, 0);
  73. DataSystem.getData(BattleData)._isHeroChange = true;
  74. this.node.on(SystemEvent.EventType.TOUCH_END, () => { this.open.open() }, this);
  75. }
  76. }
  77. /**更新武将属性 */
  78. private async updataHero() {
  79. this.uiGroup.active = !!this.data.id;
  80. this.camp.spriteFrame = await this.res.load<SpriteFrame>('image/public/qi_camp' + this.config[this.data.id]["camp"] + "/spriteFrame", SpriteFrame);
  81. this.starLabel.string = this.data.starLv + "";
  82. this.lvProgress.progress = this.data.lvProgress;
  83. DataSystem.getData(BattleData).slots.get(this.slotID)._state = HeroSlotState.full;
  84. }
  85. /**升级 */
  86. private async lvUp() {
  87. let lastLv = this.lvLabel.string;
  88. if (this.lvLabel.string != this.data.lv + "") {
  89. this.lvLabel.string = this.data.lv + "";
  90. if (lastLv != "0") {
  91. if (this.res && this.layer) {
  92. let prefab = await this.res.load<Prefab>("prefabs/battle/commandSpine", Prefab);
  93. let node = instantiate(prefab);
  94. node.getComponent(CommandSpine).autoDestory = true;
  95. node.getComponent(CommandSpine).setData("spine/effect/level up", false, "animation");
  96. node.setParent(this.layer);
  97. this.sound.play(3);
  98. }
  99. }
  100. }
  101. }
  102. /**检查攻击 */
  103. private checkAttack(dt: number): void {
  104. if (this.battle.battleState == BattleState.inBattle) {
  105. if (this.data._attackTimer <= 0) {
  106. this.data._attackTimer = this.config[this.data.id]["attSpeed"] * (1 - this.data._dyAttackSpeed);
  107. this.battle._monsters.length > 0 && this.attack();
  108. } else {
  109. this.data._attackTimer -= dt;
  110. }
  111. } else {
  112. this.data._attackTimer = this.config[this.data.id]["attSpeed"] * (1 - this.data._dyAttackSpeed);
  113. }
  114. }
  115. /**攻击 */
  116. private attack(): void {
  117. this.data.target = DataSystem.getData(BattleData)._target == -1 ? 0 : DataSystem.getData(BattleData)._target;
  118. let self = this;
  119. let config = self.skillConfig[self.config[self.data.id]["skillID"]]["attType"]
  120. let result = self.searchMonster(parseInt(config.split(":")[1]));
  121. if (result.length > 0) {
  122. let attack = this.spine.addAnimation(1, "attack", false);
  123. attack && this.spine.setTrackEventListener(attack, (e) => {
  124. let attackType = parseInt(config.split(":")[0]);
  125. if (attackType == 1) {
  126. for (let i = 0; i < result.length; i++) {
  127. self.createBullet(result[i]);
  128. }
  129. } else {
  130. self.createBullet(result[0]);
  131. }
  132. if (this.sound && !DataSystem.getData(MissionData).isInPvp) {
  133. switch (this.config[this.data.id]["atk_res"]) {
  134. case 1: case 2:
  135. this.sound.play(2);
  136. break;
  137. case 3:
  138. this.sound.play(0);
  139. break;
  140. case 4: case 5:
  141. this.sound.play(1);
  142. break;
  143. }
  144. }
  145. });
  146. attack && this.spine.setTrackCompleteListener(attack, () => {
  147. self.spine.clearTrack(1);
  148. });
  149. }
  150. }
  151. /**创建子弹 */
  152. private createBullet(traget: number): void {
  153. let bullet = new BulletData({
  154. from: this.slotID,
  155. target: traget,
  156. res: this.config[this.data.id]["atk_res"],
  157. hit_res: this.config[this.data.id]["hit_res"],
  158. isLeader: this.slotID == 5,
  159. skillID: this.config[this.data.id]["skillID"]
  160. });
  161. this.battle._bullets.push(bullet);
  162. }
  163. /**寻敌 */
  164. private searchMonster(count: number): Array<number> {
  165. let result = [];
  166. let monsters = DataSystem.getData(BattleData)._monsters;
  167. monsters[this.data.target] && monsters[this.data.target].data && monsters[this.data.target].data._isWalking && result.push(this.data.target);
  168. for (let i = 1; i < count; i++) {
  169. for (let j = 0; j < monsters.length; j++) {
  170. if (result.indexOf(j) == -1 && monsters[i] && monsters[i].data && monsters[i].data._isWalking) {
  171. result.push(j);
  172. break;
  173. }
  174. }
  175. }
  176. return result;
  177. }
  178. /**添加buff */
  179. private addBuff(): void {
  180. this.node.getComponent(Buff).addBuff(this.data._addBuff);
  181. this.data._addBuff = [];
  182. }
  183. }