feat(任务): 增加准备阶段与战斗阶段的切换逻辑

- 在准备阶段显示卡牌面板和开始战斗按钮,并发放金币奖励
- 进入战斗阶段时隐藏卡牌面板并禁用按钮
- 根据波数动态计算准备阶段金币奖励
- 修复金币同步和初始化问题
This commit is contained in:
walkpan
2026-03-26 23:07:54 +08:00
parent 4fdb424bc4
commit 76ca17ccdf
3 changed files with 1441 additions and 828 deletions

View File

@@ -1,4 +1,4 @@
import { _decorator, Vec3,Animation, instantiate, Prefab, Node, ProgressBar, Label } from "cc";
import { _decorator, Vec3,Animation, instantiate, Prefab, Node, NodeEventType, 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";
@@ -30,11 +30,19 @@ export class MissionComp extends CCComp {
private maxMonsterCount: number = 5;
@property({ tooltip: "恢复刷怪阈值" })
private resumeMonsterCount: number = 3;
@property({ tooltip: "准备阶段基础金币奖励" })
private prepareBaseCoinReward: number = 10;
@property({ tooltip: "每波准备阶段额外金币" })
private prepareCoinWaveGrow: number = 1;
@property({ tooltip: "准备阶段金币奖励上限" })
private prepareCoinRewardCap: number = 20;
// VictoryComp:any = null;
// reward:number = 0;
// reward_num:number = 0;
@property(Node)
start_btn:Node = null!
@property(Node)
time_node:Node = null!
FightTime:number = FightSet.FiIGHT_TIME
@@ -61,6 +69,7 @@ export class MissionComp extends CCComp {
private heapTrendBaseMB: number = -1;
private monsterCountSyncTimer: number = 0;
private currentWave: number = 0;
private lastPrepareCoinWave: number = 0;
private readonly heroViewMatcher = ecs.allOf(HeroViewComp);
private readonly skillViewMatcher = ecs.allOf(SkillView);
private readonly heroAttrsMatcher = ecs.allOf(HeroAttrsComp);
@@ -75,8 +84,12 @@ export class MissionComp extends CCComp {
this.on(GameEvent.MissionEnd,this.mission_end,this)
this.on(GameEvent.NewWave,this.onNewWave,this)
this.on(GameEvent.DO_AD_BACK,this.do_ad,this)
this.start_btn?.on(NodeEventType.TOUCH_END, this.onStartFightBtnClick, this)
this.removeMemoryPanel()
}
onDestroy(){
this.start_btn?.off(NodeEventType.TOUCH_END, this.onStartFightBtnClick, this)
}
protected update(dt: number): void {
if(!smc.mission.play) return
if(smc.mission.pause) return
@@ -131,22 +144,35 @@ export class MissionComp extends CCComp {
this.node.active=true
this.data_init()
oops.message.dispatchEvent(GameEvent.FightReady)
this.enterPreparePhase()
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.stop_spawn_mon = false;
smc.mission.in_fight=true
if (this.start_btn && this.start_btn.isValid) this.start_btn.active = false;
oops.message.dispatchEvent(GameEvent.FightStart) //GameSetMonComp 监听刷怪
}
private enterPreparePhase() {
smc.mission.in_fight = false;
smc.mission.stop_spawn_mon = true;
if (this.start_btn && this.start_btn.isValid) this.start_btn.active = true;
}
private onStartFightBtnClick() {
if (!smc.mission.play) return;
if (smc.mission.pause) return;
if (smc.mission.in_fight) return;
this.to_fight();
}
open_Victory(e:any,is_hero_dead: boolean = false){
// 暂停游戏循环和怪物行为
@@ -181,14 +207,13 @@ export class MissionComp extends CCComp {
smc.mission.play=false
smc.mission.pause = false;
smc.mission.in_fight = false;
if (this.start_btn && this.start_btn.isValid) this.start_btn.active = false;
this.cleanComponents()
this.clearBattlePools()
this.node.active=false
}
data_init(){
// 重置金币为初始值 (如果需要保留金币,请注释掉此行)
smc.vmdata.gold = 0;
//局内数据初始化 smc 数据初始化
smc.mission.play = true;
smc.mission.pause = false;
@@ -215,6 +240,8 @@ export class MissionComp extends CCComp {
this.heapTrendTimer = 0;
this.heapTrendBaseMB = -1;
this.monsterCountSyncTimer = 0;
this.lastPrepareCoinWave = 0;
smc.vmdata.mission_data.coin = 0;
// 重置全局属性加成和主角引用 (确保新一局数据干净)
// smc.role = null;
@@ -229,10 +256,28 @@ export class MissionComp extends CCComp {
if (wave <= 0) return;
this.currentWave = wave;
smc.vmdata.mission_data.level = wave;
this.grantPrepareCoinByWave(wave);
this.lastTimeSecond = -1;
this.update_time();
}
private grantPrepareCoinByWave(wave: number) {
if (wave <= 0) return;
if (wave <= this.lastPrepareCoinWave) return;
const base = Math.max(0, Math.floor(this.prepareBaseCoinReward));
const grow = Math.max(0, Math.floor(this.prepareCoinWaveGrow));
const cap = Math.max(0, Math.floor(this.prepareCoinRewardCap));
const reward = Math.min(cap, base + (wave - 1) * grow);
if (reward <= 0) {
this.lastPrepareCoinWave = wave;
return;
}
smc.vmdata.mission_data.coin = Math.max(0, Math.floor((smc.vmdata.mission_data.coin ?? 0) + reward));
this.lastPrepareCoinWave = wave;
oops.message.dispatchEvent(GameEvent.CoinAdd, { delta: reward, syncOnly: true });
mLogger.log(this.debugMode, 'MissionComp', "prepare coin reward", { wave, reward, coin: smc.vmdata.mission_data.coin });
}
private getMonsterThresholds(): { max: number; resume: number } {
const max = Math.max(1, Math.floor(this.maxMonsterCount));
const resume = Math.min(max - 1, Math.max(0, Math.floor(this.resumeMonsterCount)));