import { _decorator, Vec3,Animation, instantiate, Prefab, Node, ProgressBar } 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 { smc } from "../common/SingletonModuleComp"; import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops"; import { HeroAttrsComp } from "../hero/HeroAttrsComp"; import { getLevelExp, getMonsterExp, MonsterCost, MonType } from "./RogueConfig"; import { GameEvent } from "../common/config/GameEvent"; import { HeroViewComp } from "../hero/HeroViewComp"; import { UIID } from "../common/config/GameUIConfig"; import { SkillView } from "../skill/SkillView"; import { FightSet } from "../common/config/GameSet"; const { ccclass, property } = _decorator; //@todo this is a test /** 视图层对象 */ @ccclass('MissionComp') @ecs.register('MissionComp', false) export class MissionComp extends CCComp { // VictoryComp:any = null; // reward:number = 0; // reward_num:number = 0; /** 剩余复活次数 */ revive_times: number = 1; rewards:any[]=[] game_data:any={ exp:0, gold:0, diamond:0 } onLoad(){ this.on(GameEvent.MissionStart,this.mission_start,this) this.on(GameEvent.MonDead,this.do_mon_dead,this) this.on(GameEvent.HeroDead,this.do_hero_dead,this) // this.on(GameEvent.FightEnd,this.fight_end,this) this.on(GameEvent.MissionEnd,this.mission_end,this) this.on(GameEvent.DO_AD_BACK,this.do_ad,this) this.on(GameEvent.CanUpdateLv,this.onLevelUp,this) this.on(GameEvent.ReviveSuccess, this.onReviveSuccess, this) } protected update(dt: number): void { if(!smc.mission.play) return if(smc.mission.pause) return if(smc.mission.in_fight){ smc.vmdata.mission_data.fight_time+=dt smc.vmdata.mission_data.time-=dt } } // 升级奖励触发 onLevelUp(event: string, args: any) { console.log(`[MissionComp] 英雄升级到 ${args.lv} 级!`); oops.message.dispatchEvent(GameEvent.TalentSelect) // 触发奖励选择界面 (暂时留空) // this.showLevelUpReward(); } showLevelUpReward() { // TODO: 显示三选一技能/属性奖励界面 console.log("[MissionComp] 显示升级奖励界面 (TODO)"); } //奖励发放 do_reward(){ // 奖励发放 } do_drop(drop_item:any[],game_data:any={exp:0,gold:0,diamond:0}){ // console.log("[MissionComp] do_drop",drop_item,game_data) } do_mon_dead(event:any,data:any){ // console.log("[MissionComp] do_mon_dead",event,data) smc.vmdata.mission_data.mon_num-- // 计算并增加经验 // data 应该是怪物组件或包含怪物信息的对象 if (data && data.uuid) { // 默认值处理 const level = data.lv || 1; // 类型推断 let type = MonType.NORMAL; if (data.is_boss) { type = MonType.BOSS; } else if (data.is_elite) { type = MonType.ELITE; } else { // 兜底策略:根据Cost判断是否为精英怪 const cost = MonsterCost[data.uuid] || 1; if (cost >= 10) { type = MonType.ELITE; } } // 获取怪物经验 const exp = getMonsterExp(data.uuid, level, type); smc.updateHeroExp(exp); } } do_hero_dead(event:any,data:any){ // console.log("[MissionComp] do_hero_dead",event,data) // 收到 HeroDead 说明已经没有复活次数了,打开失败界面,等待玩家选择(复活或结束) // oops.message.dispatchEvent(GameEvent.FightEnd,{victory:false}) // 暂时不分发结束事件 this.open_Victory(null,true) } do_ad(){ if(this.ad_back()){ oops.message.dispatchEvent(GameEvent.AD_BACK_TRUE) smc.vmdata.mission_data.refresh_count+=FightSet.MORE_RC }else{ oops.message.dispatchEvent(GameEvent.AD_BACK_FALSE) } } ad_back(){ return true } async mission_start(){ // 防止上一局的 fight_end 延迟回调干扰新局 this.unscheduleAllCallbacks(); // 确保清理上一局的残留实体 this.cleanComponents(); // console.log("[MissionComp] ** 1 ** mission_start") oops.message.dispatchEvent(GameEvent.FightReady) this.node.active=true this.data_init() let loading=this.node.parent.getChildByName("loading") loading.active=true this.scheduleOnce(()=>{ loading.active=false },0.5) this.scheduleOnce(()=>{ this.to_fight() },0.1) } to_fight(){ smc.mission.in_fight=true oops.message.dispatchEvent(GameEvent.FightStart) //GameSetMonComp 监听刷怪 oops.message.dispatchEvent(GameEvent.TalentSelect) } open_Victory(e:any,is_hero_dead: boolean = false){ // 暂停游戏循环和怪物行为 // smc.mission.play = false; smc.mission.pause = true; // oops.message.dispatchEvent(GameEvent.FightEnd,{victory:false}) console.log("[MissionComp] open_Victory",is_hero_dead,this.revive_times) oops.gui.open(UIID.Victory,{ victory:false, rewards:this.rewards, game_data:this.game_data, can_revive: is_hero_dead && this.revive_times > 0 }) } /** 复活成功回调,扣除次数 */ onReviveSuccess() { if (this.revive_times > 0) { this.revive_times--; console.log(`[MissionComp] 玩家复活,剩余次数: ${this.revive_times}`); } } fight_end(){ // console.log("任务结束") // 延迟0.5秒后执行任务结束逻辑 this.scheduleOnce(() => { smc.mission.play=false this.cleanComponents() }, 0.5) } mission_end(){ // console.log("[MissionComp] mission_end") // 合并 FightEnd 逻辑:清理组件、停止游戏循环 smc.mission.play=false this.cleanComponents() this.node.active=false } data_init(){ //局内数据初始化 smc 数据初始化 smc.mission.play = true; smc.mission.pause = false; smc.mission.stop_mon_action = false; smc.vmdata.mission_data.in_fight=false smc.vmdata.mission_data.fight_time=0 smc.vmdata.mission_data.level=0 smc.vmdata.mission_data.time=15*60 this.rewards=[] // 改为数组,用于存储掉落物品列表 this.revive_times = 1; // 每次任务开始重置复活次数 // 重置英雄数据,确保新一局是初始状态 smc.vmdata.hero = { name:'', path:'', as:0, type:0, lv:0, exp:0, exp_max:100, exp_pre:0, hp:50, hp_max:100, mp:50, mp_max:100, def:0, ap:0, dis:0, crt:0, speed:0, skills:[], buff:[], tal:[], info:'', }; // 重置金币为初始值 (如果需要保留金币,请注释掉此行) smc.vmdata.gold = 200; // console.log("[MissionComp]局内数据初始化",smc.vmdata.mission_data) } private cleanComponents() { // 优化销毁顺序:直接销毁实体,让ECS系统自动处理组件清理 // 这样可以避免在组件reset方法中访问已经被销毁的实体引用 ecs.query(ecs.allOf(HeroViewComp)).forEach(entity => { entity.destroy(); }); ecs.query(ecs.allOf(SkillView)).forEach(entity => { entity.destroy(); }); } /** 视图层逻辑代码分离演示 */ /** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */ reset() { this.node.destroy(); } }