- 三新件: camp_esc_overlay(modal_shell+三钮,退出=danger_button,零动效零新素材)/main_esc_flow(静态承接件零成员态:is_camp_context+on_esc_input四态路由+_other_modal_open登记册集合查询+三出口动线)/camp_hud_band(48px浮层+keystone_badge,refresh_camp=bus目标册契约面) - 接线: ui_registry contract+node()第六槽(营地层与设置层之间——契约3栈语义正解);ui_camp_modals六枚落满(卡⑥终态);main_ui_build实例化+三出口薄委托接线+bus目标册纳入HUD栏;main.gd _unhandled_input(契约9接线定稿:KEY_ESCAPE配physical/pressed非echo/禁轮询/不挂ui_cancel)+三薄委托零新增成员;presenter.open_camp尾挂刷新单口(契约5时机②);main_overlay_flow._on_settings_closed语境分支(谓词=esc_overlay.visible谁开谁收) - 契约9分支序修正: ①先于②(设置开在浮窗之上态先命中无反馈——浮窗不隔层关闭;首装②先被实机场景证伪,孤检2红溯源后按卡面编号归位) - 断言批: screen_flow Esc步十断言(根态唤起/再按关窗/echo零响应/子界面无反馈/HUD直写显式触发9999/设置开态不误关/关设置回浮窗/返回动线四可见性/菜单语境不唤起)+ui_struct浮窗段(三钮仅三/零动效双件源码+子树AnimPlayer=0/debug_badge零波及) - 验证: 冒烟PASS+system_test 69项0失败+七探针全绿(screen_flow/ui_struct含Esc段/ui_click问题=0/ui_probe/ui_contrast36对/shot);S9/S10/S13归基线
51 lines
2.7 KiB
GDScript
51 lines
2.7 KiB
GDScript
## 组合根 Esc 流程承接件(产品码首个键盘输入入口——main._unhandled_input 同名薄委托落地):
|
|
## Esc 四态路由(契约 9 判据单点=ModalStack 登记册现开集合,禁手枚名单)+三出口动线。
|
|
## 静态承接件零成员态(仿 main_overlay_flow 形态——main 侧留同名薄委托,探针 main.X 路径零改动)。
|
|
class_name MainEscFlow
|
|
extends RefCounted
|
|
|
|
|
|
## 营地语境判据(Q1 甲——场景根 visible;子界面开态抑制由契约 9① 现开集合承载,不并入本谓词)
|
|
static func is_camp_context(root: Variant) -> bool:
|
|
return root.ui.modals.camp.scene != null and root.ui.modals.camp.scene.visible
|
|
|
|
|
|
## Esc 四态优先序(契约 9——①先于②:设置开在浮窗之上态必须先命中「无反馈」,浮窗不隔层关闭):
|
|
## ①除浮窗外任一登记模态开→无反馈(子界面开态/设置开在浮窗之上)→②浮窗开→close(同键单义切换,
|
|
## Q2 甲)→③营地语境→open→④非营地→无反馈(选档/冒险/菜单语境 Esc 零响应——契约 2)
|
|
static func on_esc_input(root: Variant) -> void:
|
|
var esc: Control = root.ui.modals.camp.esc_overlay
|
|
if _other_modal_open(root, esc):
|
|
return # ① 除浮窗外任一登记模态开 → 无反馈
|
|
if esc.visible:
|
|
root.ui.modals.flow.close(esc) # ② 再按 Esc 关窗
|
|
return
|
|
if is_camp_context(root):
|
|
root.ui.modals.flow.open(esc) # ③ 营地语境唤起
|
|
# ④ 非营地语境 → 无反馈
|
|
|
|
|
|
# 登记册现开集合查询(除浮窗与营地场景根本身——场景根=语境层非抑制对象;
|
|
# 迭代登记册遍历=契约 9「判据单点」 sanctioned 读法,禁按层名手枚名单)
|
|
static func _other_modal_open(root: Variant, esc: Control) -> bool:
|
|
for m in root.ui.modals.flow.stack._list:
|
|
if m != esc and m != root.ui.modals.camp.scene and is_instance_valid(m) and m.visible:
|
|
return true
|
|
return false
|
|
|
|
|
|
## 返回主菜单动线(契约 4):首步 close 浮窗(缺此步浮窗残留主菜单上方)→营地与选档层同收+开始层恢复
|
|
static func _on_return_to_menu(root: Variant) -> void:
|
|
root.ui.modals.flow.close(root.ui.modals.camp.esc_overlay)
|
|
root._camp_pres.on_camp_closed() # 关层收闭单口(卡④ T3——营地层与选档层同收+开始层恢复)
|
|
|
|
|
|
## 设置出口(浮窗登记在设置层之下——open 只隐上方层,浮窗由树序遮挡非属性隐藏;关后重现=栈语义)
|
|
static func _on_settings(root: Variant) -> void:
|
|
root.ui.modals.flow.open(root.ui.modals.settings_overlay)
|
|
|
|
|
|
## 退出出口(_quit_game 原样复用——settings_store.save_settings+quit,零语义副作用)
|
|
static func _on_quit(root: Variant) -> void:
|
|
root._quit_game()
|