feat(ux): T3+T4 视觉终稿落码+转场挂点——GOLD_DONE/底栏墨色/血条深底/Boss 双描边+换层 tint 渐变挂点(UiKit.motion 包装)

This commit is contained in:
DKChan committed 2026-09-28 13:56:28 +08:00
1 parent 4ece929315
commit 6dcd40bce8
1 file changed
+33 -5
+33 -5
View File
@@ -40,6 +40,7 @@ const TITLE_FORK := "选择下一节点" # 岔路停点
const NODE_HALF := Vector2(26, 18) # 节点方块半宽高(52×36 占位画布参数——样张批终稿)
const HIT_PAD := 6.0 # 图上命中外扩(指宽容差)
const CONFIRM_WINDOW_S := 3.0 # 放弃确认态窗口(秒——超时回落)
const COL_HP_BAR_BACK := Color8(40, 34, 28) # 迷你血条深底(样张 v1 冻结——对暗面板可辨)
var _runner = null
var _title: Label
@@ -58,6 +59,8 @@ var abandon_btn: Button # 放弃入口(可见性归组合根 set_
var _abandon_armed := false # 二次确认态(首击置位、二击提交、超时/重开回落)
var _confirm_left := 0.0 # 确认态剩余秒数(_process 倒计时+脉冲驱动)
var _node_icons := {} # 节点图标贴图(load_tex 守卫——缺位 null → 字形回退,冒烟/无素材检出安全)
var _noise_rect: TextureRect # 屏底石纹(换层色板渐变承载面——null = 纯色回退无挂点)
var _tint_level := 0 # 当前已应用 tint 的层号(0 = 未应用)
func _init() -> void:
@@ -78,6 +81,7 @@ func _init() -> void:
tex.set_anchors_preset(Control.PRESET_FULL_RECT)
tex.mouse_filter = Control.MOUSE_FILTER_IGNORE
base.add_child(tex)
_noise_rect = tex # 世界侧 tint 承载面(换层色板渐变挂点——§2.7 切片档)
var center := CenterContainer.new()
center.set_anchors_preset(Control.PRESET_FULL_RECT)
base.add_child(center)
@@ -126,8 +130,11 @@ func _init() -> void:
_bonus_row.add_child(bonus_box)
var bonus_inner := VBoxContainer.new()
bonus_box.add_child(bonus_inner)
bonus_inner.add_child(UiKit.label("本关加成", 12, false))
var bonus_cap := UiKit.label("本关加成", 12, false)
bonus_cap.add_theme_color_override("font_color", UiKit.WARM_SOFT)
bonus_inner.add_child(bonus_cap)
_bonus_value = UiKit.label("", 15, true)
_bonus_value.add_theme_color_override("font_color", UiKit.WARM)
bonus_inner.add_child(_bonus_value)
bottom.add_child(_bonus_row)
var spacer := Control.new()
@@ -141,19 +148,23 @@ func _init() -> void:
visible = false
# 状态数据框工厂(直角细线数据框——pattern 5 族;hp_box = 带迷你血条)
# 状态数据框工厂(直角细线数据框——pattern 5 族;hp_box = 带迷你血条。墨色按样张 v1 冻结:
# 暗底标签 WARM_SOFT/读数 WARM——§7.1 数据素面墨来自世界的墨在暗底侧的落法,L3 ≥4.5:1)
func _status_box(caption: String, with_bar: bool) -> PanelContainer:
var panel := PanelContainer.new()
panel.add_theme_stylebox_override("panel", UiKit.panel_flat(UiKit.DARK_UPCOMING, UiKit.PANEL_BORDER, 0, 1))
var inner := VBoxContainer.new()
panel.add_child(inner)
inner.add_child(UiKit.label(caption, 12, false))
var cap := UiKit.label(caption, 12, false)
cap.add_theme_color_override("font_color", UiKit.WARM_SOFT)
inner.add_child(cap)
if with_bar:
_hp_bar = Control.new()
_hp_bar.custom_minimum_size = Vector2(120, 6)
_hp_bar.draw.connect(_draw_hp_bar.bind(_hp_bar))
inner.add_child(_hp_bar)
var value := UiKit.label("", 15, true)
value.add_theme_color_override("font_color", UiKit.WARM)
inner.add_child(value)
if caption == "生命":
_hp_value = value
@@ -163,13 +174,13 @@ func _status_box(caption: String, with_bar: bool) -> PanelContainer:
func _draw_hp_bar(bar: Control) -> void:
# 迷你血条(占位:暗底+金填充——比例 = hero_hp / effective_max_hp)
# 迷你血条(样张 v1 冻结:深底 Color8(40,34,28)(对暗面板可辨)+金填充——比例 = hero_hp / effective_max_hp)
if _runner == null:
return
var max_hp := maxi(1, _runner.effective_max_hp())
var ratio := clampf(float(_runner.hero_hp) / float(max_hp), 0.0, 1.0)
var full := Rect2(Vector2.ZERO, bar.size)
bar.draw_rect(full, UiKit.DARK_UPCOMING)
bar.draw_rect(full, COL_HP_BAR_BACK)
if ratio > 0.0:
bar.draw_rect(Rect2(Vector2.ZERO, Vector2(bar.size.x * ratio, bar.size.y)), UiKit.GOLD)
@@ -233,6 +244,7 @@ func open_choices(cands: Array, runner) -> void:
_cand_ids.append(_id_of(cand))
_fit_canvas(_runner.nodes())
_refresh_status()
_apply_level_tint(int(_runner.level_row.get("level_index", 0)))
visible = true
if not was_visible:
# 独立屏淡入(spec Transitions:约 200ms;alpha 淡入非明度变化——art-bible §2 明度恒定)
@@ -261,6 +273,22 @@ func _fit_canvas(nodes: Array) -> void:
_canvas.custom_minimum_size = _content_size
# 换层色板渐变挂点(art-bible §2.7 下探过渡切片档——关卡结算确认→下一关→独立屏淡入链路上的
# 色相层进预告:屏底世界侧随层进换挡,信息层恒定;tint 明度带归一≈1 只动色相/饱和)。
# tint 候选方向 = art-bible §6.3 三关图类型色板方向(1 dungeon 暖石基准/2 underdark 冷蓝灰/3 deep 灰黑金属),
# 终值归色板样张批——本批只落挂点(level-map.md States 换层进入行承载)。
const BOARD_TINTS := {1: Color(1, 1, 1), 2: Color(0.84, 0.99, 1.28), 3: Color(0.97, 0.99, 1.09)}
func _apply_level_tint(level_index: int) -> void:
if _noise_rect == null or level_index == _tint_level:
return
_tint_level = level_index
var target: Color = BOARD_TINTS.get(level_index, Color(1, 1, 1))
var tw := create_tween()
tw.tween_property(_noise_rect, "modulate", target, UiKit.motion(0.45))
# 状态栏刷新(命令式纪律——组合根打开本屏/兑付确认回执后重查;零推送信号订阅)
func _refresh_status() -> void:
if _runner == null: