diff --git a/assets/resources/gui/element/victory.prefab b/assets/resources/gui/element/victory.prefab index 6c6d6d50..b805e489 100644 --- a/assets/resources/gui/element/victory.prefab +++ b/assets/resources/gui/element/victory.prefab @@ -314,8 +314,8 @@ }, "_lscale": { "__type__": "cc.Vec3", - "x": 1.2, - "y": 1.2, + "x": 1.8, + "y": 1.8, "z": 1 }, "_mobility": 0, @@ -4654,7 +4654,9 @@ "confirm_btn": { "__id__": 25 }, - "settle_title": null, + "settle_title": { + "__id__": 14 + }, "_id": "" }, { diff --git a/assets/script/game/common/config/GameEvent.ts b/assets/script/game/common/config/GameEvent.ts index 0d92ae1b..8407c171 100644 --- a/assets/script/game/common/config/GameEvent.ts +++ b/assets/script/game/common/config/GameEvent.ts @@ -110,5 +110,7 @@ export enum GameEvent { ChapterEnd = "ChapterEnd", /** 结算弹窗点击"下一节"(payload 为空,MissionComp 据此推进到下一小节) */ NextSection = "NextSection", + /** 结算弹窗点击"再来一次"(payload 为空,MissionComp 据此重开本关) */ + RestartMission = "RestartMission", } diff --git a/assets/script/game/map/MissionComp.ts b/assets/script/game/map/MissionComp.ts index fea89458..120ec472 100644 --- a/assets/script/game/map/MissionComp.ts +++ b/assets/script/game/map/MissionComp.ts @@ -214,6 +214,8 @@ export class MissionComp extends CCComp { this.on(GameEvent.DO_AD_BACK, this.do_ad, this) // 结算弹窗"下一节"按钮推进关卡 this.on(GameEvent.NextSection, this.onNextSection, this) + // 结算弹窗"再来一次"按钮重开本关 + this.on(GameEvent.RestartMission, this.onRestartMission, this) this.start_btn?.on(NodeEventType.TOUCH_END, this.onStartFightBtnClick, this) // 开局免费三选一选完后自动进入战斗 oops.message.on("OpeningPicksDone", this.onOpeningPicksDone, this); @@ -765,6 +767,12 @@ export class MissionComp extends CCComp { this.advanceToNextSection(); } + /** 结算弹窗"再来一次"事件:关闭弹窗并重开本关 */ + private onRestartMission() { + oops.gui.remove(UIID.Victory); + this.restartCurrentMission(); + } + /** 开局免费三选一选完,自动进入战斗(等效于点击开始按钮) */ private onOpeningPicksDone() { if (this.currentPhase !== MissionPhase.Prepare) return; @@ -973,6 +981,34 @@ export class MissionComp extends CCComp { `[StageProgress] 进入小节: ${getProgressText(this.currentChapter, this.currentStage, this.currentSection)}`); } + /** + * 重开本关:清理战场并重置数据,从当前小节重新开始 + * 与 advanceToNextSection 的区别:不推进小节进度,保持当前 section 不变 + */ + private restartCurrentMission() { + // 清理战场与局内数据 + this.cleanComponents(); + this.clearBattlePools(); + this.data_init(); + // 重置结算状态 + this._victory = false; + this._settleType = "defeat"; + this._settleTitle = ""; + // 进入准备阶段 + this.changePhase(MissionPhase.Prepare); + // 触发 MissionStart 重置开局免费抽卡 + oops.message.dispatchEvent(GameEvent.MissionStart, {}); + oops.message.dispatchEvent(GameEvent.FightReady); + // 触发 SectionStart 重新生成当前小节怪物 + oops.message.dispatchEvent(GameEvent.SectionStart, { + chapter: this.currentChapter, + stage: this.currentStage, + section: this.currentSection, + }); + mLogger.log(this.debugMode, 'MissionComp', + `[StageProgress] 重开本关: ${getProgressText(this.currentChapter, this.currentStage, this.currentSection)}`); + } + // ======================== 回合管理 ======================== /** diff --git a/assets/script/game/map/VictoryComp.ts b/assets/script/game/map/VictoryComp.ts index 7614f071..4cde9fec 100644 --- a/assets/script/game/map/VictoryComp.ts +++ b/assets/script/game/map/VictoryComp.ts @@ -172,19 +172,18 @@ export class VictoryComp extends CCComp { /** 是否可以复活(由 MissionComp 传入,取决于剩余复活次数) */ private canRevive: boolean = false; - /** - * 结算类型(由 MissionComp 传入,驱动主按钮行为): - * section - 小节胜利(主按钮"下一节",派发 NextSection) - * 其余 - 末关通关 / 失败(主按钮确认退出,走原结算退出流程) - */ + /** 结算类型:section=小节胜利, victory=末关通关, defeat=失败 */ private settleType: string = "defeat"; + /** 是否胜利场(驱动主按钮文案与行为) */ + private isVictory: boolean = false; /** 加载时隐藏 loading 遮罩并绑定按钮事件 */ protected onLoad(): void { this.node.getChildByName("loading").active = false // 代码绑定按钮点击事件,替代编辑器 Click Events 配置 - this.bindButtonClick(this.next_section_btn, this.on_next_section); + // next 按钮按状态分发:小节胜利→下一节,失败→再来一次 + this.bindButtonClick(this.next_section_btn, this.on_next_btn_click); this.bindButtonClick(this.confirm_btn, this.victory_end); } @@ -219,14 +218,15 @@ export class VictoryComp extends CCComp { this.game_data = args.game_data } - // 结算类型:缺省按失败处理 + // 结算类型与胜负状态:缺省按失败处理 this.settleType = args.settle_type ?? "defeat"; + this.isVictory = !!args.victory; // 根据是否可复活决定按钮显示 this.node.getChildByName("btns").getChildByName("next").active = !args.can_revive - // 下一节按钮:仅小节胜利时显示 - this.updateNextButtonState(); + // 按钮显隐与文案:下一节 / 再来一次 / 确认 + this.updateButtonStates(); // 通关标题:仅末关通关时显示 this.updateSettleTitle(args.settle_title ? String(args.settle_title) : ""); @@ -765,12 +765,37 @@ export class VictoryComp extends CCComp { // ======================== 操作入口 ======================== /** - * 下一节按钮显隐:仅小节胜利(settleType === "section")时显示。 - * 该按钮为 @property 绑定节点,编辑器中已设计好样式与位置。 + * 统一更新按钮显隐与文案: + * section(小节胜利)→ next="下一节",btn 隐藏 + * victory(末关通关)→ btn="确认",next 隐藏 + * defeat(失败) → btn="确认",next="再来一次" */ - private updateNextButtonState() { - if (this.next_section_btn && this.next_section_btn.isValid) { - this.next_section_btn.active = this.settleType === "section"; + private updateButtonStates() { + const btns = this.node.getChildByName("btns"); + if (!btns) return; + + const btnNode = btns.getChildByName("btn"); + const nextNode = btns.getChildByName("next"); + + // btn 确认按钮:仅小节胜利时隐藏 + if (btnNode) { + btnNode.active = this.settleType !== "section"; + const label = btnNode.getChildByName("Label")?.getComponent(Label); + if (label) label.string = "确认"; + } + + // next 按钮:小节胜利→"下一节",失败→"再来一次",末关通关隐藏 + if (nextNode) { + nextNode.active = this.settleType !== "victory"; + const label = nextNode.getChildByName("Label")?.getComponent(Label); + if (label) { + label.string = this.settleType === "section" ? "下一节" : "再来一次"; + } + } + + // 属性绑定的确认按钮同步显隐 + if (this.confirm_btn && this.confirm_btn.isValid) { + this.confirm_btn.active = this.settleType !== "section"; } } @@ -787,17 +812,21 @@ export class VictoryComp extends CCComp { } /** - * 下一节按钮点击(编辑器 Click Events 绑定): - * 派发 NextSection,由 MissionComp 关窗并推进下一小节。 + * next 按钮点击分发: + * 小节胜利 → 派发 NextSection 推进下一节 + * 失败场 → 派发 RestartMission 重开本关 */ - on_next_section() { - oops.message.dispatchEvent(GameEvent.NextSection); + on_next_btn_click() { + if (this.settleType === "section") { + oops.message.dispatchEvent(GameEvent.NextSection); + } else { + oops.message.dispatchEvent(GameEvent.RestartMission); + } } /** - * 主按钮点击(编辑器 Click Events 绑定,btns/next): - * 确认结算退出(原有退出流程)。 - * 注:下一节按钮为独立节点,不经过本方法。 + * 确认按钮点击(代码绑定,btns/btn): + * 清理数据 → 派发 MissionEnd → 关闭结算弹窗 */ victory_end() { this.clear_data() @@ -820,22 +849,9 @@ export class VictoryComp extends CCComp { } - /** - * 重新开始: - * 1. 清理数据。 - * 2. 触发 MissionEnd 事件重置状态。 - * 3. 显示 loading 遮罩,延迟 0.5 秒后触发 MissionStart。 - * 4. 关闭弹窗。 - */ + /** 再来一次(已迁移至 MissionComp.restartCurrentMission,保留空实现兼容旧引用) */ restart() { - this.clear_data() - oops.message.dispatchEvent(GameEvent.MissionEnd) - this.node.getChildByName("loading").active = true - this.scheduleOnce(() => { - oops.gui.open(UIID.Mission) - this.node.getChildByName("loading").active = false - oops.gui.removeByNode(this.node) - }, 0.5) + oops.message.dispatchEvent(GameEvent.RestartMission); } /** 物品展示回调(预留) */