import { _decorator, Component, sp, Sprite, Label, ProgressBar, SpriteFrame, Node, SystemEvent, Prefab, instantiate } from 'cc'; import { DataSystem } from '../core/data/DataSystem'; import { ResourceLoader } from '../core/resourceManager/ResourceLoader'; import { Sound } from '../core/sound/Sound'; import { OpenWindow } from '../core/ui/window/OpenWindow'; import { ConfigData } from '../data/ConfigData'; import { BattleData, BattleState } from './BattleData'; import { Buff } from './Buff'; import { BulletData } from './BulletData'; import { CommandSpine } from './CommandSpine'; import { HeroData } from './HeroData'; import { HeroSlotState } from './HeroSlot'; import { MissionData } from './MissionData'; const { ccclass, property } = _decorator; @ccclass('Hero') export class Hero extends Component { @property({ tooltip: "英雄插槽ID" }) slotID: number = 0; @property({ type: ResourceLoader, tooltip: "资源加载组件" }) res: ResourceLoader; @property({ type: Sprite, tooltip: "阵营图标" }) camp: Sprite; @property({ type: Label, tooltip: "星级" }) starLabel: Label; @property({ type: Label, tooltip: "等级" }) lvLabel: Label; @property({ type: ProgressBar, tooltip: "等级进度" }) lvProgress: ProgressBar; @property({ type: Node, tooltip: "UI组" }) uiGroup: Node; @property({ type: OpenWindow, tooltip: "窗口打开组件" }) open: OpenWindow; @property({ type: Node, tooltip: "特效层" }) layer: Node; public data: HeroData; private battle: BattleData; private spine: sp.Skeleton; private config: any; private skillConfig: any; /**音效组件 */ private sound: Sound; start() { this.sound = this.getComponent(Sound); this.config = DataSystem.getData(ConfigData)["general"]; this.skillConfig = DataSystem.getData(ConfigData)["skill"]; this.data = new HeroData(); this.battle = DataSystem.getData(BattleData); DataSystem.regeditData(this.data); this.battle.heros.set(this.slotID, this.data); this.data._buff = this.getComponent(Buff); this.spine = this.node.getComponent(sp.Skeleton); } update(dt) { DataSystem.watch(this.data, "id") && this.changeHero(); DataSystem.watch(this.data, "lv") && this.lvUp(); DataSystem.watch(this.data, "starLv") && this.updataHero(); DataSystem.watch(this.data, "lvProgress") && this.updataHero(); DataSystem.watch(this.data, "_addBuff") && this.addBuff(); (this.spine && this.data.id) && this.checkAttack(dt); } /**更换英雄 */ private async changeHero() { if (this.data.id != this.data._curID) { if (!this.data.id) { this.data._curID = 0; this.spine && this.spine.destroy(); this.uiGroup.active = false; this.battle.slots.get(this.slotID)._state = HeroSlotState.empty; this.node.off(SystemEvent.EventType.TOUCH_END, () => { this.open.open() }, this); return; } if (this.spine) { this.spine.destroy(); } this.data._curID = this.data.id; this.scheduleOnce(async () => { this.spine = this.node.addComponent(sp.Skeleton); let spData = await this.res.load("spine/hero/" + this.config[this.data.id]["hero_res"], sp.SkeletonData); this.spine.skeletonData = spData; this.spine.setAnimation(0, "idle", true); }, 0); DataSystem.getData(BattleData)._isHeroChange = true; this.node.on(SystemEvent.EventType.TOUCH_END, () => { this.open.open() }, this); } } /**更新武将属性 */ private async updataHero() { this.uiGroup.active = !!this.data.id; this.camp.spriteFrame = await this.res.load('image/public/qi_camp' + this.config[this.data.id]["camp"] + "/spriteFrame", SpriteFrame); this.starLabel.string = this.data.starLv + ""; this.lvProgress.progress = this.data.lvProgress; DataSystem.getData(BattleData).slots.get(this.slotID)._state = HeroSlotState.full; } /**升级 */ private async lvUp() { let lastLv = this.lvLabel.string; if (this.lvLabel.string != this.data.lv + "") { this.lvLabel.string = this.data.lv + ""; if (lastLv != "0") { if (this.res && this.layer) { let prefab = await this.res.load("prefabs/battle/commandSpine", Prefab); let node = instantiate(prefab); node.getComponent(CommandSpine).autoDestory = true; node.getComponent(CommandSpine).setData("spine/effect/level up", false, "animation"); node.setParent(this.layer); this.sound.play(3); } } } } /**检查攻击 */ private checkAttack(dt: number): void { if (this.battle.battleState == BattleState.inBattle) { if (this.data._attackTimer <= 0) { this.data._attackTimer = this.config[this.data.id]["attSpeed"] * (1 - this.data._dyAttackSpeed); this.battle._monsters.length > 0 && this.attack(); } else { this.data._attackTimer -= dt; } } else { this.data._attackTimer = this.config[this.data.id]["attSpeed"] * (1 - this.data._dyAttackSpeed); } } /**攻击 */ private attack(): void { this.data.target = DataSystem.getData(BattleData)._target == -1 ? 0 : DataSystem.getData(BattleData)._target; let self = this; let config = self.skillConfig[self.config[self.data.id]["skillID"]]["attType"] let result = self.searchMonster(parseInt(config.split(":")[1])); if (result.length > 0) { let attack = this.spine.addAnimation(1, "attack", false); attack && this.spine.setTrackEventListener(attack, (e) => { let attackType = parseInt(config.split(":")[0]); if (attackType == 1) { for (let i = 0; i < result.length; i++) { self.createBullet(result[i]); } } else { self.createBullet(result[0]); } if (this.sound && !DataSystem.getData(MissionData).isInPvp) { switch (this.config[this.data.id]["atk_res"]) { case 1: case 2: this.sound.play(2); break; case 3: this.sound.play(0); break; case 4: case 5: this.sound.play(1); break; } } }); attack && this.spine.setTrackCompleteListener(attack, () => { self.spine.clearTrack(1); }); } } /**创建子弹 */ private createBullet(traget: number): void { let bullet = new BulletData({ from: this.slotID, target: traget, res: this.config[this.data.id]["atk_res"], hit_res: this.config[this.data.id]["hit_res"], isLeader: this.slotID == 5, skillID: this.config[this.data.id]["skillID"] }); this.battle._bullets.push(bullet); } /**寻敌 */ private searchMonster(count: number): Array { let result = []; let monsters = DataSystem.getData(BattleData)._monsters; monsters[this.data.target] && monsters[this.data.target].data && monsters[this.data.target].data._isWalking && result.push(this.data.target); for (let i = 1; i < count; i++) { for (let j = 0; j < monsters.length; j++) { if (result.indexOf(j) == -1 && monsters[i] && monsters[i].data && monsters[i].data._isWalking) { result.push(j); break; } } } return result; } /**添加buff */ private addBuff(): void { this.node.getComponent(Buff).addBuff(this.data._addBuff); this.data._addBuff = []; } }