import { Vec3, _decorator , v3,Collider2D,Contact2DType,Label ,Node,Prefab,instantiate,ProgressBar, Component, Material, Sprite, math, clamp, Game, tween, Color} from "cc"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { HeroSpine } from "./HeroSpine"; import { BoxSet, FacSet } from "../common/config/BoxSet"; import { smc } from "../common/SingletonModuleComp"; import { Timer } from "../../../../extensions/oops-plugin-framework/assets/core/common/timer/Timer"; import { SkillSet, TargetGroup, TargetType } from "../common/config/SkillSet"; import { BuffComp } from "./BuffComp"; import { oops } from "db://oops-framework/core/Oops"; import { GameEvent } from "../common/config/GameEvent"; import { FightConComp } from "../map/FightConComp"; import { EquipSpecialAttr } from "../common/config/Equips"; import { FightSet } from "../common/config/Mission"; import { HeroPos } from "../common/config/heroSet"; const { ccclass, property } = _decorator; /** 角色显示组件 */ @ccclass('HeroViewComp') // 定义为 Cocos Creator 组件 @ecs.register('HeroView', false) // 定义为 ECS 组件 export class HeroViewComp extends CCComp { FIGHTCON:FightConComp=null! BUFFCOMP:BuffComp=null! as: HeroSpine = null! status:String = "idle" hero_uuid:number = 1001; hero_name : string = "hero"; fight_pos:number=0; lv:number =1; slv:number =1; scale: number = 1; /** 角色阵营 1:hero -1 :mon */ type: number = 0; /**角色类型 0近战-需要贴身 1远程-保持距离 2辅助 */ fac:number=0; //阵营 0:hero 1:monster atk_range:number = 150; box_group:number = BoxSet.HERO; is_dead:boolean = false; //是否摧毁 is_stop:boolean = false; is_atking:boolean = false; is_boss:boolean = false; is_big_boss:boolean = false; is_master:boolean =false; ap_u:number=0; ap_ur:number=0; hp_up:number=0; hp: number = 100; /** 血量 */ hp_max: number = 100; /** 最大血量 */ hp_speed: number = 0; //每秒回复量 pwt:Timer = new Timer(1); //计时器 ap: number = 10; /**攻击力 */ // atk_speed: number = 1; cd: number = 1.3; /**攻击速度 攻击间隔 */ dis: number = 80; at: number = 0; /** 冷却时间 */ atk_skill:number=0; def: number = 0; //防御 vun: number = 0; //易伤 dodge: number = 10; //闪避率 shield:number = 0; //护盾,免伤1次减1 speed: number = 100; /** 角色移动速度 */ ospeed: number = 100; /** 角色初始速度 */ atk_count: number = 0; atked_count: number = 0; stop_cd: number = 0; /*停止倒计时*/ yun_cd: number = 0; //眩晕倒计时 ice_cd: number = 0; //冰冻倒计时 dir_y:number = 0; speek_time:number = 0; is_stop_temp:boolean = false;i Friend_alive_cd:Timer=new Timer(10) private damageQueue: Array<{ damage: number, isCrit: boolean, delay: number }> = []; private isProcessingDamage: boolean = false; private damageInterval: number = 0.2; // 伤害数字显示间隔 private timer:Timer=new Timer(1); onLoad() { this.as = this.getComponent(HeroSpine); this.FIGHTCON=this.node.parent.getComponent(FightConComp); console.log("[HeroViewComp]:hero view comp ",this.FIGHTCON) this.on(GameEvent.ChangeATK,this.change_atk,this) // let anm = this.node.getChildByName("anm") // anm.setScale(anm.scale.x*0.8,anm.scale.y*0.8); } /** 视图层逻辑代码分离演示 */ start () { this.as.idle() this.BUFFCOMP=this.node.getComponent(BuffComp); /** 方向 */ this.node.setScale(this.scale,1); this.node.getChildByName("top").setScale(this.scale,1); if(this.is_boss){ this.node.setScale(this.node.scale.x*1.5,this.node.scale.y*1.5); this.node.getChildByName("top").getChildByName("sboss").active = true; } /* 显示角色血量 */ this.node.getChildByName("top").getChildByName("hp").active = true; } update(dt: number){ if(!smc.mission.play||smc.mission.pause) return // if(this.is_dead) { // this.ent.destroy(); // return // } if(this.is_dead) { console.log("[HeroViewComp]:alive friend cd",this.Friend_alive_cd ,this.Friend_alive_cd.elapsedTime) if(this.Friend_alive_cd.update(dt)){ this.to_alive() } } if(this.timer.update(dt)){ // this.add_ap(10) }; if(this.ice_cd > 0){ this.ice_cd -=dt; return } if(this.yun_cd > 0){ this.yun_cd -=dt; return } this.in_stop(dt); // 处理伤害队列 this.processDamageQueue(); } change_atk(e:GameEvent,data:any){ switch(data){ case EquipSpecialAttr.ICE: this.atk_skill=6001 break case EquipSpecialAttr.FIRE: this.atk_skill=6002 break case EquipSpecialAttr.WIND: this.atk_skill=6003 break default: this.atk_skill=6001 break } } get isActive() { return this.ent.has(HeroViewComp) && this.node?.isValid; } hide_info(){ this.node.getChildByName("top").getChildByName("ihp").active = false; this.node.getChildByName("top").getChildByName("iap").active = false; } //状态切换 status_change(type:string){ this.status=type if(type == "idle"){ this.as.idle() // this.as.change_default("idle") } if(type == "move"){ this.as.move() // this.as.change_default("move") } } add_shield(shield:number){ this.shield =shield if(this.shield>0) this.BUFFCOMP.show_shield(true) } // add_cd(cd: number){ // this.cd += this.cd*((100-cd)/100); // this.BUFFCOMP.buff_get("cd") // } /** * 增加英雄的攻击(AP)。 * @param ap 要增加的攻击。 */ add_ap(ap: number,is_num:boolean=true){ if(is_num){ this.ap += Math.floor(ap); }else{ this.ap += Math.floor(ap/100*this.ap); } this.BUFFCOMP.update_info_ap() } de_ap(ap: number,is_num:boolean=true){ if(is_num){ this.ap -= Math.floor(ap); }else{ this.ap -= Math.floor(ap/100*this.ap); } this.BUFFCOMP.update_info_ap() } add_hp_max(hp: number=0,is_num:boolean=true){ if(is_num){ this.hp_max += Math.floor(hp) ; this.hp += Math.floor(hp) ; }else{ this.hp_max += Math.floor(hp/100*this.hp_max); this.hp += Math.floor(hp/100*this.hp_max); } this.BUFFCOMP.update_info_hp() } de_hp_max(hp: number=0,is_num:boolean=true){ if(is_num){ this.hp_max -= Math.floor(hp) ; }else{ this.hp_max -= Math.floor(hp/100*this.hp_max); } this.BUFFCOMP.update_info_hp() } add_hp(hp: number = 0,is_num:boolean=true) { this.BUFFCOMP.heathed(); if(is_num){ this.hp+=Math.floor(hp); }else{ this.hp+=Math.floor(hp/100*this.hp_max); } if(this.hp > this.hp_max){ this.hp = this.hp_max; } this.BUFFCOMP.tooltip(2,hp.toFixed(0)); } /** 静止时间 */ in_stop (dt: number) { if(this.stop_cd > 0){ this.stop_cd -= dt; if(this.stop_cd <= 0){ this.stop_cd = 0; this.is_atking = false; } } } do_change(){ this.BUFFCOMP.update_info_ap() this.BUFFCOMP.update_info_hp() this.BUFFCOMP.update_info_lv() } do_update(){ this.BUFFCOMP.update_info_ap() this.BUFFCOMP.update_info_hp() this.BUFFCOMP.update_info_lv() } do_dead(){ this.Friend_alive_cd=new Timer(this.FIGHTCON.Friend_alive_cd) console.log("[HeroViewComp]:角色死亡",this.hero_uuid) if(this.is_master){ console.log("[HeroViewComp]:英雄死亡") oops.message.dispatchEvent(GameEvent.FightEnd,{victory:false}) } } do_atked(remainingDamage:number){ if (this.shield > 0) { this.shield -= 1 this.BUFFCOMP.tooltip(5,"*吸收*"); remainingDamage = 0 if (this.shield <= 0) { if(this == null) return; this.BUFFCOMP.show_shield(false); } }else{ if(this == null) return; this.hp -= remainingDamage; if(this.hp <= 0) { if(this == null) return; this.is_dead=true this.BUFFCOMP.dead() this.do_dead() console.log("[HeroViewComp]:dead,fac => "+(this.fac==FacSet.HERO?"hero":"monster")) if(this.ent == null) return; if(this.fac ==FacSet.HERO){ this.to_grave() }else{ this.ent.destroy(); } } this.BUFFCOMP.update_info_hp() this.showDamage(remainingDamage, true); } } dead(){ this.BUFFCOMP.dead() this.to_drop() } to_grave(){ tween(this.node).to(0.5, { position:v3(-900,this.node.position.y+300,0)},{ onComplete: (target?: object) => { this.node.setPosition(-900,this.node.position.y-300,0) } } ).start() } to_alive(){ this.is_dead=false this.hp=this.hp_max this.BUFFCOMP.update_info_hp() this.node.setPosition(HeroPos[this.fight_pos].pos) this.BUFFCOMP.heathed() } //掉落物品 to_drop(){ // let Drops = getMonsterDrops(1, MonsterType.Normal, 1.2); // if(this.is_boss) Drops =getMonsterDrops(1, MonsterType.Elite, 1.2); // if(this.is_big_boss) Drops =getMonsterDrops(1, MonsterType.Boss, 1.2); } to_console(value:any,value2:any=null,value3:any=null){ console.log("["+this.scale+this.hero_name+']'+value,value2,value3) } reset() { this.is_dead = false; const collider = this.getComponent(Collider2D); if (collider) { collider.off(Contact2DType.BEGIN_CONTACT); } this.scheduleOnce(() => { this.node.destroy(); }, 0.1); } playSkillEffect(skill_id:number) { let skill = SkillSet[skill_id] switch(skill.act){ case "max": this.as.max() this.BUFFCOMP.max_show(skill.fname) this.BUFFCOMP.tooltip(3,skill.name,skill_id) break case "atk": this.as.atk() break } } to_update(){ this.ap=this.ap*this.lv } /** 显示伤害数字 */ showDamage(damage: number, isCrit: boolean) { this.damageQueue.push({ damage, isCrit, delay: this.damageInterval }); } /** 处理伤害队列 */ private processDamageQueue() { if (this.isProcessingDamage || this.damageQueue.length === 0) return; this.isProcessingDamage = true; const damageInfo = this.damageQueue.shift()!; this.showDamageImmediate(damageInfo.damage, damageInfo.isCrit); // 设置延时处理下一个伤害 this.scheduleOnce(() => { this.isProcessingDamage = false; }, this.damageInterval); } /** 立即显示伤害效果 */ private showDamageImmediate(damage: number, isCrit: boolean) { this.BUFFCOMP.in_atked(); this.atked_count++; if (isCrit) { this.BUFFCOMP.tooltip(4, damage.toFixed(0), damage); // console.log("暴击伤害:" + damage); } else { this.BUFFCOMP.tooltip(1, damage.toFixed(0), damage); // console.log("普通伤害:" + damage); } } }