import { _decorator, Component, instantiate, Node, Prefab, Animation, Vec3, Label, sp, randomRangeInt, ProgressBar, ParticleSystem2D, tween, Sprite, color, UITransform, Vec2 } from 'cc'; import { resLoader } from '../../../../core_tgx/base/utils/ResLoader'; import { ModuleDef } from '../../../../scripts/ModuleDef'; import { areanMgr } from '../../AreanManager'; import { AreanGameAudioMgr } from '../../AreanGameAudioMgr'; import { Bullet } from './Bullet'; import { IMonsterCfg } from '../../../../module_basic/shared/configs/interface/IMonsterCfg'; import { IHeroCfg } from '../../../../module_basic/shared/configs/interface/IHeroCfg'; const { ccclass, property } = _decorator; @ccclass('RoleController') export class RoleController extends Component { @property({ type: Node }) roleNode: Node = null; @property({ type: Node }) skin: Node = null; @property({ type: Node }) effectsNode: Node = null; @property({ type: Node }) textNode: Node = null; @property({ type: Node }) hpManaNode1: Node = null; @property({ type: Node }) hpBar1: Node = null; @property({ type: Label }) hpBarLabel1: Label; @property({ type: Node }) manaBar1: Node = null; @property({ type: Label }) manaBarLabel1: Label; @property({ type: Node }) shieldsNode1: Node; @property({ type: Node }) hpBar: Node = null; @property({ type: Node }) hpManaNode2: Node = null; @property({ type: Node }) hpBar2: Node = null; @property({ type: Label }) hpBarLabel2: Label; @property({ type: Node }) manaBar2: Node = null; @property({ type: Label }) manaBarLabel2: Label; @property({ type: Node }) shieldsNode2: Node; @property({ type: Node }) hpManaNode: Node = null; @property({ type: Node }) newHpBar: Node = null; @property({ type: Node }) manaBar: Node = null; @property({ type: Node }) shieldsNode: Node; @property({ type: Label }) roleName: Label; @property({ type: Label }) bigName: Label; @property({ type: Prefab }) damageNum: Prefab = null; @property({ type: Prefab }) hitEffect: Prefab = null; @property({ type: Label }) attackValue: Label; @property({ type: Label }) hpValue: Label; data: IHeroCfg | IMonsterCfg = null; isMonster = false; id: number = 1001 faceType: number = 0; isAttackIng: boolean = false; buffList: number[] = []; debuffList: number[] = []; skillAnimTime: boolean = false; hp: number = 100; maxHp: number = 100; mp: number = 0; maxMp: number = 50; shields: number = 0; curGroup: number = -1; attack: number = 1; init(id: number) { this.data = areanMgr.cfgMgr.HeroDatas.getData(id); console.log("this.data === ", this.data, id); if (this.data == null) { // console.log("this.data 002=== ",this.data,id); this.data = areanMgr.cfgMgr.MonsterDatas.getData(id); // console.log("this.data 003=== ",this.data,id); this.isMonster = true; } } getDefautPos() { const face0PosX = -175; const face1PosX = 175; let posX = this.faceType == 0 ? face0PosX : face1PosX; let pos = new Vec3(posX, 0, 0); return pos; } useSkill(skillId: number, isCrit: boolean, target: RoleController) { let skillData = areanMgr.cfgMgr.SkillPerformanceDatas.getData(skillId); let delay = 0; if (this.data.normalSkill == skillId || this.data.mainSkill.indexOf(skillId) != -1) { //若为普攻或大招,播放攻击动作 this.playAttack(this.data.mainSkill.indexOf(skillId) != -1, isCrit); delay = 500; //this.playAnimation("roleAttack", "sp_idle"); } if (skillData.skillSound != '') AreanGameAudioMgr.playOneShot('res/Audio/' + skillData.skillSound, 1); if (skillData.skillEffect != '') { const path = 'res/Prefebs/effect/' + skillData.skillEffect; let sp: Prefab = resLoader.get(path, Prefab, ModuleDef.Arean); let skillEffect = instantiate(sp); this.node.addChild(skillEffect); setTimeout(() => { skillEffect.removeFromParent(); } , 2000); } if (skillData.bulletRes != '' && skillData.bulletFly > 0) { setTimeout(() => { let timer = areanMgr.cfgMgr.SkillDatas.getData(skillId).delayTime; switch (skillData.bulletFly) { case 1: const path = 'res/Prefebs/bullet/' + skillData.bulletRes; let sp: Prefab = resLoader.get(path, Prefab, ModuleDef.Arean); let bullet = instantiate(sp); this.scheduleOnce(() => { let heroAttackPos = this.node.getChildByName("hero5AttackPos"); heroAttackPos.addChild(bullet); // 获取子弹的世界坐标 let worldPosition = bullet.getWorldPosition(); //console.log("子弹初始世界坐标————————", worldPosition); let pos = areanMgr.BattleView.effectLayer.getComponent(UITransform).convertToNodeSpaceAR(worldPosition) // bullet.setParent(areanMgr.BattleView.effectLayer); // bullet.setPosition(pos); bullet.setScale(2,2,1); //console.log("子弹在 effectLayer 中的位置————————", pos); }, 0); bullet.getComponent(Bullet).init(target, timer - delay / 1000); break; } }, delay); } } skillTakesEffect(skillId: number) { //技能生效 let skillData = areanMgr.cfgMgr.SkillPerformanceDatas.getData(skillId); if (skillData.hitSound != '') AreanGameAudioMgr.playOneShot('res/Audio/' + skillData.hitSound, 1); if (skillData.hitEffect != '') { const path = 'res/Prefebs/effect/' + skillData.hitEffect; //console.log("path ===", path); let sp: Prefab = resLoader.get(path, Prefab, ModuleDef.Arean); let skillEffect = instantiate(sp); this.node.addChild(skillEffect); setTimeout(() => { skillEffect.removeFromParent(); } , 2000); } } takeDamage(damage: number, isCrit: boolean) { if (this.damageNum) { let damageNode = instantiate(this.damageNum); this.textNode.addChild(damageNode); if (!isCrit) { damageNode.getComponent(Animation)?.play("normal"); damageNode.getChildByName("normal")!.getComponent(Label)!.string = "-" + damage; } else { damageNode.getComponent(Animation)?.play("crit"); damageNode.getChildByName("crit")!.getComponent(Label)!.string = "-" + damage; } damageNode.setPosition(new Vec3(randomRangeInt(-20, 20), randomRangeInt(0, 80), 0)); let commonHitEffect = instantiate(this.hitEffect); this.node.addChild(commonHitEffect); this.getComponent(Animation).play("roleHit"); setTimeout(() => { damageNode.removeFromParent(); commonHitEffect.removeFromParent(); } , 1000); } } takeHeal(heal: number) { if (this.damageNum) { let damageNode = instantiate(this.damageNum); this.textNode.addChild(damageNode); damageNode.getComponent(Animation)?.play("heal"); damageNode.getChildByName("heal")!.getComponent(Label)!.string = "+" + heal; damageNode.setPosition(new Vec3(randomRangeInt(-20, 20), randomRangeInt(0, 80), 0)); setTimeout(() => { damageNode.removeFromParent(); } , 500); } } showBattleText(text: string) { if (this.damageNum) { let damageNode = instantiate(this.damageNum); this.textNode.addChild(damageNode); damageNode.getComponent(Animation)?.play("text"); damageNode.getChildByName("text")!.getComponent(Label)!.string = text; damageNode.setPosition(new Vec3(randomRangeInt(-80, 80), randomRangeInt(0, 80), 0)); setTimeout(() => { damageNode.removeFromParent(); } , 2000); } } async AddBuff() { if (this.damageNum) { let list = this.buffList; for (let i = 0; i < list.length; i++) { if (this.hp <= 0) break; let buffId = list[i]; let damageNode = instantiate(this.damageNum); this.textNode.addChild(damageNode); damageNode.getComponent(Animation)?.play("buff"); //console.log("buffId === ",buffId); let duffData = areanMgr.cfgMgr.BuffDatas.getData(buffId); if (duffData) { let text = duffData.name; damageNode.getChildByName("buff")!.getComponent(Label)!.string = text + "↑"; damageNode.setPosition(new Vec3(0, 40, 0)); await new Promise(resolve => setTimeout(resolve, 200)); } else { console.error("没有相关数据 :buffId === ", buffId); } } } } async AddDeBuff() { if (this.damageNum) { let list = this.debuffList; for (let i = 0; i < list.length; i++) { if (this.hp <= 0) break; let buffId = list[i]; let damageNode = instantiate(this.damageNum); this.textNode.addChild(damageNode); damageNode.getComponent(Animation)?.play("debuff"); let text = areanMgr.cfgMgr.BuffDatas.getData(buffId).name; damageNode.getChildByName("debuff")!.getComponent(Label)!.string = text + "↓"; damageNode.setPosition(new Vec3(0, 40, 0)); await new Promise(resolve => setTimeout(resolve, 200)); } } } playAttack(isSpSkill: boolean, isCrit: boolean) { if (isSpSkill) { let animName = this.isMonster ? "sp_attack2" : "sp_attack00"; this.playAnimation(animName, "sp_idle"); this.skillAnimTime = true; setTimeout(() => { this.skillAnimTime = false; }, 600); } else { let ctAnim = isCrit && !this.isMonster ? "sp_attack0" : "sp_attack1"; this.playAnimation(ctAnim, "sp_idle"); } this.isAttackIng = true; } playDodge() { //this.playAnimation("dodge"); } changeHp(hp: number, maxHp: number, shields: number) { this.hp = hp; this.maxHp = maxHp; let hpBar = this.hpBar.getComponent(ProgressBar); tween(hpBar) .to(0.3, { progress: this.hp / this.maxHp }) .start(); hpBar = this.hpBar1.getComponent(ProgressBar); tween(hpBar) .to(0.3, { progress: this.hp / this.maxHp }) .start(); this.hpBarLabel1.string = this.hp + "/" + this.maxHp; hpBar = this.hpBar2.getComponent(ProgressBar); tween(hpBar) .to(0.3, { progress: this.hp / this.maxHp }) .start(); this.hpBarLabel2.string = this.hp + "/" + this.maxHp; if (shields) { this.shields = shields; let shieldsProgressValue = this.shields / (this.maxHp / 3); this.shieldsNode.getComponent(ProgressBar).progress = shieldsProgressValue; this.shieldsNode.active = shieldsProgressValue > 0; this.shieldsNode1.active = shieldsProgressValue > 0; this.shieldsNode2.active = shieldsProgressValue > 0; this.shieldsNode1.getComponent(ProgressBar).progress = shieldsProgressValue; this.shieldsNode1.getChildByName("value").getComponent(Label).string = this.shields + "" this.shieldsNode2.getComponent(ProgressBar).progress = shieldsProgressValue; this.shieldsNode2.getChildByName("value").getComponent(Label).string = this.shields + "" } this.hpValue.getComponent(Label).string = this.hp + "" return; this.hpBar.active = true; this.newHpBar.children[0].getComponent(Sprite)!.color = color(255, 255, 255, 255); let node = this.newHpBar.children[0]; this.newHpBar.removeAllChildren(); for (let i = 1; i <= this.maxHp; i++) { const cloneNode = instantiate(node); this.newHpBar.addChild(cloneNode!); cloneNode.name = "hpBarItem" + i; } for (let i = 1; i <= this.maxHp; i++) { if (i > this.hp) { this.newHpBar.getChildByName("hpBarItem" + i)!.getComponent(Sprite)!.color = color(255, 255, 255, 0); } } } changeMp(mp: number, maxMp: number) { this.mp = mp; this.maxMp = maxMp; let manaBar = this.manaBar.getComponent(ProgressBar); tween(manaBar) .to(0.3, { progress: this.mp / this.maxMp }) .start(); manaBar = this.manaBar1.getComponent(ProgressBar); tween(manaBar) .to(0.3, { progress: this.mp / this.maxMp }) .start(); this.manaBarLabel1.string = this.mp.toFixed(0) + "/" + this.maxMp; manaBar = this.manaBar2.getComponent(ProgressBar); tween(manaBar) .to(0.3, { progress: this.mp / this.maxMp }) .start(); this.manaBarLabel2.string = this.mp.toFixed(0) + "/" + this.maxMp; } changeAttack(value: number) { this.attack = value; this.attackValue.getComponent(Label).string = this.attack + "" } refreshSkin(faceType: number) { //1正 0反 this.faceType = faceType; let skin = areanMgr.cfgMgr.SkinData.getData(this.data.skinRes[0]).icon; let imagePath = 'res/Spine/' + skin; let spAsset: sp.SkeletonData = resLoader.get(imagePath, sp.SkeletonData, ModuleDef.Arean); let com = this.skin.getComponent(sp.Skeleton); com.skeletonData = spAsset; // console.log("刷新皮肤", com,spAsset); //com.setAnimation(0, 'idle', true); if (faceType == 0) { this.roleNode.setScale(-1, 1, 1); } else { this.roleNode.setScale(1, 1, 1); } this.node.setPosition(this.getDefautPos()); } changeHpBarType() { { if (areanMgr.BattleView.soloMode) { if (areanMgr.BattleView.curGroup == this.curGroup) { this.hpManaNode.active = false; this.bigName.node.active = true; if (this.faceType == 0) { this.hpManaNode1.active = false; this.hpManaNode2.active = true; } else { this.hpManaNode1.active = true; this.hpManaNode2.active = false; } } else { this.bigName.node.active = false; this.hpManaNode.active = false; this.hpManaNode1.active = false; this.hpManaNode2.active = false; } } else { this.bigName.node.active = false; this.hpManaNode.active = true; this.hpManaNode1.active = false; this.hpManaNode2.active = false; } } } playAnimation(anim: string, backAnim?: string) { //死亡或释放大招时不会被其他动作打断 if ((this.hp <= 0 && anim != "sp_death") || (this.skillAnimTime && anim != "sp_death")) return; // 播放动画 let animation = this.node.getComponent(Animation); let spineAnimation = this.node.getComponentInChildren(sp.Skeleton); if (anim.startsWith("sp_")) { let animName = anim.substring(3); spineAnimation.setAnimation(0, animName, false); if (backAnim && backAnim.startsWith("sp_")) { spineAnimation.setCompleteListener(() => { let animName = backAnim.substring(3); if (this.hp > 0 && !this.skillAnimTime) { spineAnimation.setAnimation(0, animName, true); }; }) } else if (backAnim) { animation.play(backAnim); } } else { animation.play(anim); if (backAnim && backAnim.startsWith("sp_")) { animation.once(Animation.EventType.FINISHED, () => { let animName = backAnim.substring(3); spineAnimation.setAnimation(0, animName, true); },); } else if (backAnim) { animation.play(backAnim); } } } death() { this.playAnimation("sp_death"); if (!this.isMonster) { const path = 'res/Prefebs/effect/Dizzy'; let sp: Prefab = resLoader.get(path, Prefab, ModuleDef.Arean); let skillEffect = instantiate(sp); this.effectsNode.addChild(skillEffect); this.hpManaNode1.active = false; this.hpManaNode2.active = false; } this.hpManaNode.active = false; } }