import { _decorator, Component, Node, sp, Vec3, v3, tween, Label, ProgressBar, Prefab, instantiate, UITransform, Animation, clamp } from 'cc'; import { MissionData } from '../battle/MissionData'; import { DataSystem } from '../core/data/DataSystem'; import { ResourceLoader } from '../core/resourceManager/ResourceLoader'; import { Sound } from '../core/sound/Sound'; import { ConfigData } from '../data/ConfigData'; import { PVPCardData } from './PVP'; import { PVPBullet } from './PVPBullet'; import { PVPHeroUI } from './PVPHeroUI'; const { ccclass, property } = _decorator; @ccclass('PVPHero') export class PVPHero extends Component { @property({ type: ResourceLoader, tooltip: "资源加载器" }) res: ResourceLoader; @property({ type: sp.Skeleton, tooltip: "spine组件" }) spine: sp.Skeleton; @property({ type: Prefab, tooltip: "子弹预制体" }) bulletPrefab: Prefab; @property({ type: Animation, tooltip: "动画组件" }) animation: Animation; private data: PVPCardData; private dir: number; private hp: number; private sound: Sound; private ui: PVPHeroUI; start() { this.sound = this.getComponent(Sound); } update() { this.ui && this.ui.node.setPosition(this.node.position); } onDestroy() { this.ui.node && this.ui.node.destroy(); } public setUI(ui: PVPHeroUI): void { this.ui = ui; } public async setData(data: PVPCardData, dir: number, to: Vec3, cb: Function) { this.hp = 100; this.data = data; this.dir = dir; let spData = await this.res.load("spine/hero/" + DataSystem.getData(ConfigData)["general"][data.id]["hero_res"], sp.SkeletonData); this.spine.skeletonData = spData; this.spine.setAnimation(0, "run", true); this.spine.node.setScale(v3(dir, 1, 1)); this.ui.starLabel.string = data.star + ""; this.ui.lvLabel.string = "LV." + data.lv; this.ui.nameLabel.string = DataSystem.getData(ConfigData)["general"][data.id]['name']; tween(this.node).to(0.5, { position: to }).call(async () => { this.spine.setAnimation(0, "idle", true); if (cb) { cb(); } }).start(); } public attack(to: Node, cb: Function): void { this.spine.setAnimation(0, "attack", false); let self = this; this.spine.setEventListener(() => { let node = instantiate(self.bulletPrefab); node.setPosition(self.node.position.clone().add(v3(-self.dir * self.node.getComponent(UITransform).width / 2, self.node.getComponent(UITransform).height / 2 - 30, 0))); node.setParent(self.node.parent); node.getComponent(PVPBullet).setData(self.data, self.dir, to.position.clone().add(v3(0, self.node.getComponent(UITransform).height / 2 - 30, 0)), cb); if (this.sound) { switch (DataSystem.getData(ConfigData)["general"][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; } } }); this.spine.setCompleteListener(() => { self.spine.setAnimation(0, "idle", true); }); } public onHit(hit: number, cb: Function): void { let i = 0; this.hp -= hit; this.ui.bloodLabel.string = clamp(this.hp, 0, 100,) + "%"; this.ui.bloodProgress.progress = this.hp / 100; if (this.hp > 0) { this.animation.play(this.animation.clips[0].name); this.animation.on(Animation.EventType.FINISHED, () => { if (!i && cb) { i++; cb(); } }, this); } else { cb && cb(); } } public die(cb: Function): void { let i = 0; this.animation.play(this.animation.clips[0].name); this.animation.on(Animation.EventType.FINISHED, () => { if (!i && cb) { i++; this.node.destroy(); cb(); } }, this); } }