import { _decorator, Vec3,Animation, instantiate, Prefab, Node, ProgressBar, Label } 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 { MonsterCost, MonType, calculateMonsterGold, getLevelExp, calculateMonsterExp, SpecialMonsterSchedule } 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"; import { mLogger } from "../common/Logger"; const { ccclass, property } = _decorator; //@todo 需要关注 当boss死亡的时候的动画播放完成后,需要触发事件,通知 MissionComp 进行奖励处理 /** 视图层对象 */ @ccclass('MissionComp') @ecs.register('MissionComp', false) export class MissionComp extends CCComp { @property({ tooltip: "是否启用调试日志" }) private debugMode: boolean = false; // VictoryComp:any = null; // reward:number = 0; // reward_num:number = 0; @property(Node) coins_node:Node = null! @property(Node) lv_node:Node = null! @property(Node) chou_node:Node = null! @property(Node) time_node:Node = null! @property(Node) hero_info_node:Node = null! @property(Node) update_node:Node = null! FightTime:number = FightSet.FiIGHT_TIME /** 剩余复活次数 */ revive_times: number = 1; rewards:any[]=[] game_data:any={ exp:0, gold:0, diamond:0 } private lastTimeStr: string = ""; // 记录已触发的特殊刷怪索引 private spawnedSpecialIndices: Set = new Set(); onLoad(){ this.on(GameEvent.MissionStart,this.mission_start,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) } protected update(dt: number): void { if(!smc.mission.play) return if(smc.mission.pause) return if(smc.mission.in_fight){ if(smc.mission.stop_mon_action) return smc.vmdata.mission_data.fight_time+=dt this.FightTime-=dt // 检查特殊刷怪时间 this.checkSpecialSpawns(smc.vmdata.mission_data.fight_time); this.update_time(); } } update_time(){ let time = Math.max(0, this.FightTime); let m = Math.floor(time / 60); let s = Math.floor(time % 60); let str = `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`; if(str != this.lastTimeStr){ this.time_node.getChildByName("time").getComponent(Label).string = str; this.lastTimeStr = str; } } private checkSpecialSpawns(fightTime: number) { SpecialMonsterSchedule.forEach((item, index) => { if (!this.spawnedSpecialIndices.has(index) && fightTime >= item.time) { this.spawnedSpecialIndices.add(index); mLogger.log(this.debugMode, 'MissionComp', ` 触发特殊刷怪: ${item.desc}`); oops.message.dispatchEvent("SpawnSpecialMonster", { uuid: item.uuid, type: item.type, level: item.level }); } }); } //奖励发放 do_reward(){ // 奖励发放 } cal_gold_reward(data: any, type: MonType) { const cost = MonsterCost[data.uuid] || 1; const level = data.lv || 1; let add_gold = calculateMonsterGold(data.uuid, level, type); smc.updateGold(add_gold, false); } do_hero_dead(event:any,data:any){ } 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(); 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 监听刷怪 } open_Victory(e:any,is_hero_dead: boolean = false){ // 暂停游戏循环和怪物行为 // smc.mission.play = false; smc.mission.pause = true; // oops.message.dispatchEvent(GameEvent.FightEnd,{victory:false}) mLogger.log(this.debugMode, '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 }) } fight_end(){ // mLogger.log(this.debugMode, 'MissionComp', "任务结束") // 延迟0.5秒后执行任务结束逻辑 this.scheduleOnce(() => { smc.mission.play=false this.cleanComponents() }, 0.5) } mission_end(){ // mLogger.log(this.debugMode, 'MissionComp', " mission_end") // 合并 FightEnd 逻辑:清理组件、停止游戏循环 smc.mission.play=false this.cleanComponents() this.node.active=false } data_init(){ // 重置金币为初始值 (如果需要保留金币,请注释掉此行) smc.vmdata.gold = 0; //局内数据初始化 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 this.FightTime=FightSet.FiIGHT_TIME this.rewards=[] // 改为数组,用于存储掉落物品列表 this.revive_times = 1; // 每次任务开始重置复活次数 this.spawnedSpecialIndices.clear(); // 重置特殊刷怪记录 // 重置全局属性加成和主角引用 (确保新一局数据干净) // smc.role = null; // 重置英雄数据,确保新一局是初始状态 // mLogger.log(this.debugMode, '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(); } }