From 648ad57a9b4f3012369769c1a3446c5bd37dd2ee Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Sun, 20 Sep 2026 14:24:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(presentation):=20=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E6=94=B6=E6=95=9B=E6=89=B9=E2=80=94=E2=80=94=E5=85=A8=E7=AB=99?= =?UTF-8?q?=E8=89=B2=E6=9D=BF=E4=B8=8E=20StyleBox=20=E5=8D=95=E7=82=B9?= =?UTF-8?q?=E5=8C=96=E8=BF=9B=20ui=5Fkit=20+=20=E9=A1=BA=E5=B8=A6=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=A5=96=E5=8A=B1=E5=BE=BD=E7=AB=A0=20action=20?= =?UTF-8?q?=E9=94=AE=E6=BC=8F=E7=BD=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ① ui_kit.gd 扩为全站取色/描边唯一出口:语义色板 6 族(墨/面板/金/旗朱/蓝紫/暖白灰石)+棋盘格底+深底+BBCode 十六进制+panel_flat 工厂(bg/border/corner/border_w/margin 一站式)——美术批换皮只改本文件 ② 16 个视图/装配文件内联 Color8/StyleBoxFlat 字面量全部清零(含 4 个浮点字面色 toast 底/tooltip 底/遮罩灰收编;棋盘悬停高亮框保留 draw_center=false 特例挂点);battle_log_view 行级 BBCode 染色属文本标记层保留原地 ③ 零视觉变化:layout_probe 布局转储与 master 逐字节一致;冒烟 355 项 0 失败 ④ 顺带修复(master 既有缺陷,非本批引入):格面八型批 cell_type=action 无徽章键——board_view REWARD_BADGE 补「行」,ui_click_probe 91 次 fail-fast 断言清零(问题=0) --- .../presentation/main.gd | 2 +- .../presentation/ui_assembler.gd | 14 ++-- .../presentation/views/ap_bar_view.gd | 16 +--- .../presentation/views/battle_end_overlay.gd | 14 ++-- .../presentation/views/battle_log_view.gd | 6 +- .../presentation/views/battle_stage_view.gd | 12 +-- .../presentation/views/board_fx_view.gd | 8 +- .../presentation/views/board_view.gd | 37 ++++----- .../presentation/views/enemy_card_view.gd | 26 +++--- .../presentation/views/hero_card_view.gd | 14 +--- .../views/hero_info_panel_view.gd | 22 ++--- .../presentation/views/legend_overlay.gd | 2 +- .../presentation/views/level_strip_view.gd | 32 ++++---- .../presentation/views/node_overlay.gd | 2 +- .../presentation/views/route_overlay.gd | 18 ++--- .../views/settlement_review_overlay.gd | 2 +- .../presentation/views/status_slot_row.gd | 38 +++------ .../presentation/views/toast_stack.gd | 15 +--- .../presentation/views/tune_panel.gd | 6 +- .../presentation/views/ui_kit.gd | 81 ++++++++++++++++++- 20 files changed, 184 insertions(+), 183 deletions(-) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd index 318b0af2..f324c24f 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd @@ -149,7 +149,7 @@ func _build_ui() -> void: func _fatal_screen(msg: String) -> void: var l := UiKit.label(msg, 20, true) - l.add_theme_color_override("font_color", Color8(200, 60, 48)) + l.add_theme_color_override("font_color", UiKit.RED_ALERT) l.set_anchors_preset(Control.PRESET_CENTER) add_child(l) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/ui_assembler.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/ui_assembler.gd index 86910cf6..53de7db6 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/ui_assembler.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/ui_assembler.gd @@ -18,9 +18,7 @@ static func build_battle_ui(root: Control, db) -> Dictionary: # A 区:关卡进度条(全宽 × 28px 顶栏) var strip_panel := PanelContainer.new() strip_panel.custom_minimum_size = Vector2(0, 28) - var sb := StyleBoxFlat.new() - sb.bg_color = Color8(30, 25, 20) - sb.set_corner_radius_all(0) + var sb := UiKit.panel_flat(UiKit.BG_ROOT, UiKit.BG_ROOT, 0, 0) strip_panel.add_theme_stylebox_override("panel", sb) root.add_child(strip_panel) var strip_view := LevelStripView.new() @@ -85,13 +83,13 @@ static func build_overlays(host: Control, db, base_atk: int, base_hp: int) -> Di # 开始覆盖层(返回 {overlay, box, seed_edit, lvbtn, tunebtn, dbgbtn}——按钮接线归组合根; # 单场遭遇用户入口已删(2026-09-13 用户裁决——单场原语仅探针经 debug_session.start_single 使用)) static func build_start_overlay(host: Control, db = null) -> Dictionary: - var overlay := overlay_bg(host, Color8(28, 22, 18)) + var overlay := overlay_bg(host, UiKit.BG_OVERLAY) var box := overlay_box(overlay) var title := UiKit.label("Dungeon Sweeper", 34, true) - title.add_theme_color_override("font_color", Color8(240, 226, 200)) + title.add_theme_color_override("font_color", UiKit.WARM) box.add_child(title) var sub := UiKit.label("战斗屏战斗屏改造批 —— 扫雷的因,逐行兑现的果", 16, false) - sub.add_theme_color_override("font_color", Color8(200, 188, 166)) + sub.add_theme_color_override("font_color", UiKit.WARM_SOFT) box.add_child(sub) box.add_child(HSeparator.new()) @@ -116,7 +114,7 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary: var help_text := "玩法:每轮 %d AP——挖开(1AP)/插旗(1AP)/移动(免费)/连锁(免费)。\n每个非封锁格都藏一种格面资源(增伤/护甲强化/回血/爆裂/削弱)。开安全格、标中雷 = 正向兑付;\n开雷格、标错安全格 = 负向兑付——全部在轮末结算逐行兑现;吃掷点的基础攻击按护甲等级判定,无 miss、最低保底 1 点。\n停手:剩余 AP 转存 RAP;弃图刷新:RAP−%d 当场换图继续挖(每轮剩 %d 次)。\n敌人全灭胜、主角倒下负。悬停可看三态光标与可挖域微光。" % [ int(db.action_economy.ap_per_round), int(db.action_economy.rap_refresh_cost), int(db.action_economy.refresh_cap_per_round)] var help := UiKit.label(help_text, 13, false) - help.add_theme_color_override("font_color", Color8(178, 166, 146)) + help.add_theme_color_override("font_color", UiKit.WARM_FAINT) box.add_child(help) return {"overlay": overlay, "box": box, "seed_edit": seed_edit, @@ -128,7 +126,7 @@ static func build_inter_overlay(host: Control) -> Dictionary: var overlay := overlay_bg(host, Color(0, 0, 0, 0.6)) var box := overlay_box(overlay) var label := UiKit.label("", 24, true) - label.add_theme_color_override("font_color", Color8(240, 226, 200)) + label.add_theme_color_override("font_color", UiKit.WARM) box.add_child(label) var next_btn := UiKit.button("进入下一层") box.add_child(next_btn) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/ap_bar_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/ap_bar_view.gd index 7396baac..4da72546 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/ap_bar_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/ap_bar_view.gd @@ -12,9 +12,9 @@ signal stop_pressed signal refresh_confirmed signal legend_toggled -const COL_GOLD := Color8(240, 168, 40) -const COL_DOT_OFF := Color8(120, 106, 88) -const COL_INK := Color8(51, 38, 27) +const COL_GOLD := UiKit.GOLD +const COL_DOT_OFF := UiKit.DOT_OFF +const COL_INK := UiKit.INK var _dots: HBoxContainer var _ap_label: Label @@ -31,15 +31,7 @@ var _arm_tween: Tween func _init() -> void: custom_minimum_size = Vector2(0, 44) - var sb := StyleBoxFlat.new() - sb.bg_color = Color8(226, 210, 182) - sb.set_corner_radius_all(0) - sb.set_border_width_all(1) - sb.border_color = Color8(120, 106, 88) - sb.content_margin_left = 8.0 - sb.content_margin_right = 8.0 - sb.content_margin_top = 4.0 - sb.content_margin_bottom = 4.0 + var sb := UiKit.panel_flat(UiKit.PANEL_DATA, UiKit.PANEL_BORDER, 0, 1, Vector4(8, 4, 8, 4)) add_theme_stylebox_override("panel", sb) var row := HBoxContainer.new() diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_end_overlay.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_end_overlay.gd index aae0d2e6..836b9c91 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_end_overlay.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_end_overlay.gd @@ -9,9 +9,9 @@ extends Control signal review_pressed signal continue_pressed -const COL_GOLD := Color8(240, 168, 40) -const COL_DUSK := Color8(90, 108, 140) # 暮蓝 #5A6C8C(全作唯一暮蓝档) -const COL_WARM := Color8(240, 226, 200) +const COL_GOLD := UiKit.GOLD +const COL_DUSK := UiKit.DUSK # 暮蓝(全作唯一暮蓝档) +const COL_WARM := UiKit.WARM var _dim: ColorRect var _seal: Panel @@ -45,11 +45,7 @@ func _init() -> void: # 金蜡封占位(胜利):圆形色块落于扫雷图区中央——位置由 set_board_rect 注入 _seal = Panel.new() _seal.mouse_filter = Control.MOUSE_FILTER_IGNORE - var sb := StyleBoxFlat.new() - sb.bg_color = COL_GOLD - sb.set_corner_radius_all(200) - sb.set_border_width_all(4) - sb.border_color = Color8(176, 122, 20) + var sb := UiKit.panel_flat(COL_GOLD, UiKit.GOLD_DEEP, 200, 4) _seal.add_theme_stylebox_override("panel", sb) _seal.size = Vector2(72, 72) _seal.visible = false @@ -62,7 +58,7 @@ func _init() -> void: func open_victory(verdict_line: String, continue_label: String, board_rect: Rect2) -> void: _dim.color = Color(COL_WARM, 0.28) _verdict.text = verdict_line - _verdict.add_theme_color_override("font_color", Color8(60, 44, 20)) + _verdict.add_theme_color_override("font_color", UiKit.INK_ON_GOLD) _btn.text = continue_label _board_rect = board_rect visible = true diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_log_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_log_view.gd index 74f08b07..d0f7e91e 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_log_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_log_view.gd @@ -16,8 +16,8 @@ signal review_requested const BAND_H_DIG := 24 const BAND_H_SETTLE := 84 const AGG_TYPES := ["reward_ineffective"] -const COL_GOLD := "#f0a828" -const COL_INK := "#33261b" +const COL_GOLD := UiKit.HEX_GOLD +const COL_INK := UiKit.HEX_INK var _db var _log: RichTextLabel @@ -150,7 +150,7 @@ func _source_label(src_key: String) -> String: func _gold_frame(text: String) -> String: # highlight 金框强调(形状+色彩双通道:■ 前缀 + 金底) - return "[bgcolor=%s][color=#3a2a08]■ %s[/color][/bgcolor]" % [COL_GOLD, text] + return "[bgcolor=%s][color=#%s]■ %s[/color][/bgcolor]" % [COL_GOLD, UiKit.HEX_ON_GOLD, text] func _format_row(row: Dictionary, agg_count := -1) -> String: diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_stage_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_stage_view.gd index 3ccf7d22..72219654 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_stage_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/battle_stage_view.gd @@ -18,15 +18,7 @@ var _cards: Array = [] func _init(db_ref) -> void: custom_minimum_size = Vector2(0, 252) - var sb := StyleBoxFlat.new() - sb.bg_color = Color8(216, 200, 172) - sb.set_corner_radius_all(0) - sb.set_border_width_all(1) - sb.border_color = Color8(120, 106, 88) - sb.content_margin_left = 6.0 - sb.content_margin_right = 6.0 - sb.content_margin_top = 4.0 - sb.content_margin_bottom = 4.0 + var sb := UiKit.panel_flat(UiKit.PANEL_STAGE, UiKit.PANEL_BORDER, 0, 1, Vector4(6, 4, 6, 4)) add_theme_stylebox_override("panel", sb) var vb := VBoxContainer.new() vb.add_theme_constant_override("separation", 4) @@ -50,7 +42,7 @@ func _init(db_ref) -> void: center_col.alignment = BoxContainer.ALIGNMENT_CENTER center.add_child(center_col) stage_center = UiKit.label("兑现演出区\n(结算期:光带 → 弹道 → 受击)", 13, false) - stage_center.add_theme_color_override("font_color", Color8(140, 124, 100)) + stage_center.add_theme_color_override("font_color", UiKit.STONE_FAINT) stage_center.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER center_col.add_child(stage_center) row.add_child(center) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_fx_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_fx_view.gd index 578ecb43..f9bd3dae 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_fx_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_fx_view.gd @@ -6,10 +6,10 @@ class_name BoardFxView extends Control -const COL_GOLD := Color8(240, 168, 40) -const COL_BOSS := Color8(143, 47, 106) # 紫赤 #8F2F6A -const COL_FLAG := Color8(198, 61, 34) # 旗朱 -const CONFETTI_COLS := [Color8(240, 168, 40), Color8(198, 61, 34), Color8(46, 110, 142), Color8(240, 226, 200)] +const COL_GOLD := UiKit.GOLD +const COL_BOSS := UiKit.BOSS_PURPLE # 紫赤 #8F2F6A +const COL_FLAG := UiKit.FLAG_RED # 旗朱 +const CONFETTI_COLS := [UiKit.GOLD, UiKit.FLAG_RED, UiKit.HERO_BLUE, UiKit.WARM] var _banner: Label diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_view.gd index 3b8f387d..5c175f76 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/board_view.gd @@ -15,17 +15,18 @@ signal action_requested(cell: Vector2i, kind: String) # kind ∈ {dig, move, f signal hover_forbidden(cell: Vector2i) # 非相邻未开格悬停(首遇 toast 归组合根去重) signal chord_attempted(cell: Vector2i) # 双击快开尝试(chord 肌肉记忆提示锚) -const COL_BRICK := Color8(201, 175, 131) # 未开——掩尘完整地砖(色板原语 #C9AF83) -const COL_FLOOR := Color8(179, 154, 120) # 已开——裸土 #B39A78(碎裂裸露地面) -const COL_DIGIT := Color8(51, 38, 27) # 数字——墨族 #33261B(对格底 ≥4.5:1 硬指标) -const COL_HERO := Color8(46, 110, 142) # 小人边框——小人蓝 #2E6E8E -const COL_FLAG := Color8(198, 61, 34) # 旗朱 #C63D22 -const COL_GOLD := Color8(240, 168, 40) # 奖励金 #F0A828 -const COL_PATH := Color8(46, 110, 142) # 路径预览点迹——小人蓝细线 -const COL_DIG_EDGE := Color8(120, 190, 120) # 可挖域呼吸微光基色(绿相,明度贴格底) -const COL_HL_TARGET := Color8(240, 168, 40) # 悬停目标格边框(金) -const REWARD_BADGE := { # 已开格格面资源身份 icon(cell_type 五型键;极性视觉归批 2) +const COL_BRICK := UiKit.BRICK # 未开——掩尘完整地砖(色板原语 #C9AF83) +const COL_FLOOR := UiKit.FLOOR # 已开——裸土 #B39A78(碎裂裸露地面) +const COL_DIGIT := UiKit.INK # 数字——墨族 #33261B(对格底 ≥4.5:1 硬指标) +const COL_HERO := UiKit.HERO_BLUE # 小人边框——小人蓝 #2E6E8E +const COL_FLAG := UiKit.FLAG_RED # 旗朱 #C63D22 +const COL_GOLD := UiKit.GOLD # 奖励金 #F0A828 +const COL_PATH := UiKit.HERO_BLUE # 路径预览点迹——小人蓝细线 +const COL_DIG_EDGE := UiKit.DIG_EDGE # 可挖域呼吸微光基色(绿相,明度贴格底) +const COL_HL_TARGET := UiKit.GOLD # 悬停目标格边框(金) +const REWARD_BADGE := { # 已开格格面资源身份 icon(cell_type 八型键;极性视觉归批 2) "attack": "攻", "defense": "守", "heal": "医", "blast": "爆", "weaken": "弱", "pierce": "穿", "magic": "魔", # 穿/魔 = 伤害道具批 2026-09-18 + "action": "行", # 行 = 行动点型(八型批 2026-09-20——ap_up/ap_drain 两行;徽章键漏网补齐,ui_click_probe 91 断言修复) } const BADGE_PLACEHOLDER := "?" # 未知图标键占位纹样(HUD框架:禁静默空图标) const CURSOR_DIG := Input.CURSOR_CROSS # 挖——镐形自绘纹理载体 @@ -237,7 +238,7 @@ func _apply_hover_visuals(c: Vector2i) -> void: _set_cursor_shape(c, Input.CURSOR_FORBIDDEN) else: hl.visible = true - _set_hl_color(hl, Color8(120, 60, 50)) # 不可及域灰禁框(禁止光标+首遇 toast 双通道) + _set_hl_color(hl, UiKit.RED_FORBID) # 不可及域灰禁框(禁止光标+首遇 toast 双通道) _set_cursor_shape(c, Input.CURSOR_FORBIDDEN) hover_forbidden.emit(c) @@ -315,7 +316,7 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: if rec.get("kind", "") == "mine": bg = COL_FLOOR text = "雷" - digit_col = Color8(150, 44, 36) + digit_col = UiKit.RED_MINE else: bg = COL_FLOOR var d: int = rec.get("digit", 0) @@ -331,11 +332,7 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: digit_col = COL_FLAG else: bg = COL_BRICK - var sb := StyleBoxFlat.new() - sb.bg_color = bg - sb.set_corner_radius_all(3) - sb.set_border_width_all(1) - sb.border_color = bg.darkened(0.15) + var sb := UiKit.panel_flat(bg, bg.darkened(0.15), 3) if is_hero: sb.set_border_width_all(3) sb.border_color = COL_HERO @@ -376,7 +373,7 @@ func _process(delta: float) -> void: return _breath_t += delta var k := 0.5 + 0.5 * sin(_breath_t * 3.0) # 3 rad/s≈0.48Hz——无 >3 次/秒频闪(AC 基线) - var col := COL_DIG_EDGE.lerp(Color8(46, 80, 60), 0.55 - 0.35 * k) + var col := COL_DIG_EDGE.lerp(UiKit.DIG_EDGE_DEEP, 0.55 - 0.35 * k) for c in _diggable: if not _cell_sb.has(c): continue @@ -414,10 +411,8 @@ func _build_markers(btn: Button) -> Dictionary: var hl := Panel.new() hl.set_anchors_preset(Control.PRESET_FULL_RECT) hl.mouse_filter = Control.MOUSE_FILTER_IGNORE - var hl_sb := StyleBoxFlat.new() + var hl_sb := UiKit.panel_flat(Color.TRANSPARENT, COL_HL_TARGET, 0, 2) hl_sb.draw_center = false - hl_sb.set_border_width_all(2) - hl_sb.border_color = COL_HL_TARGET hl.add_theme_stylebox_override("panel", hl_sb) hl.visible = false btn.add_child(hl) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/enemy_card_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/enemy_card_view.gd index cab4365c..5abb66d2 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/enemy_card_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/enemy_card_view.gd @@ -10,16 +10,16 @@ class_name EnemyCardView extends PanelContainer -const COL_INK := Color8(51, 38, 27) +const COL_INK := UiKit.INK # 摇定动作呈现映射(敌人技能池批 §2.4 三档可见性;新效应词汇批 2026-09-19 扩四档):键 = pending_type(快照投影)。 # 普通攻击零表示("—" 中性色——完全不可预测);伤害特殊技 = 攻击系 ⚔(朱红); # 增益特殊技 = 防御/增益系 ✦(蓝);妨害特殊技 = 妨害系 ☠(紫——对主角施减益,proposal-status-vocabulary §1.4)。 # nat20 暴击无前置表示(掷点层,与技能重击严格区分)。 const PENDING_STYLE := { - "basic": ["—", Color8(120, 106, 88)], - "damage": ["⚔", Color8(198, 61, 34)], - "buff": ["✦", Color8(46, 110, 142)], - "debuff": ["☠", Color8(122, 66, 148)], + "basic": ["—", UiKit.PANEL_BORDER], + "damage": ["⚔", UiKit.FLAG_RED], + "buff": ["✦", UiKit.HERO_BLUE], + "debuff": ["☠", UiKit.DEBUFF_PURPLE], } # 蓄力档技能集(2026-09-18 用户拍板:重击类独立蓄力提示——伤害技 ⚔ / 增益技 ✦ / 重击类 蓄力 三档占位) const CHARGE_SKILL_IDS := ["heavy"] @@ -39,21 +39,13 @@ var _dead := false func _init() -> void: custom_minimum_size = Vector2(190, 176) - var sb := StyleBoxFlat.new() - sb.bg_color = Color8(226, 212, 190) - sb.set_corner_radius_all(4) - sb.set_border_width_all(1) - sb.border_color = Color8(150, 60, 48) - sb.content_margin_left = 8.0 - sb.content_margin_right = 8.0 - sb.content_margin_top = 6.0 - sb.content_margin_bottom = 6.0 + var sb := UiKit.panel_flat(UiKit.PANEL_ENEMY, UiKit.RED_DEEP, 4, 1, Vector4(8, 6, 8, 6)) add_theme_stylebox_override("panel", sb) var row := HBoxContainer.new() row.add_theme_constant_override("separation", 8) add_child(row) _portrait = UiKit.label("敌", 34, true) - _portrait.add_theme_color_override("font_color", Color8(150, 60, 48)) + _portrait.add_theme_color_override("font_color", UiKit.RED_DEEP) _portrait.custom_minimum_size = Vector2(48, 0) _portrait.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER _portrait.vertical_alignment = VERTICAL_ALIGNMENT_CENTER @@ -109,7 +101,7 @@ func _set_order(i: int) -> void: func set_pending(ptype: String, pid: String) -> void: if _dead: return - var style: Array = PENDING_STYLE.get(ptype, ["—", Color8(120, 106, 88)]) + var style: Array = PENDING_STYLE.get(ptype, ["—", UiKit.PANEL_BORDER]) _intent_badge.add_theme_color_override("font_color", style[1]) if ptype == "" or ptype == "basic": _intent_badge.text = "意图:—" # 普通攻击零表示(不可预测——§2.4) @@ -137,7 +129,7 @@ func mark_dead() -> void: tw.tween_property(self, "rotation_degrees", 0.0, 0.08) _portrait.text = "✕" _intent_badge.text = "—— 击破 ——" - _intent_badge.add_theme_color_override("font_color", Color8(120, 110, 98)) + _intent_badge.add_theme_color_override("font_color", UiKit.STONE) _armor_line.text = "" _status_label.text = "" _hp_bar.value = 0 diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/hero_card_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/hero_card_view.gd index 2f18a079..029679e2 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/hero_card_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/hero_card_view.gd @@ -5,8 +5,8 @@ class_name HeroCardView extends PanelContainer -const COL_INK := Color8(51, 38, 27) -const COL_HERO := Color8(46, 110, 142) +const COL_INK := UiKit.INK +const COL_HERO := UiKit.HERO_BLUE var _portrait: Label var _hp_bar: ProgressBar @@ -18,15 +18,7 @@ var _status_label: Label func _init() -> void: custom_minimum_size = Vector2(216, 176) - var sb := StyleBoxFlat.new() - sb.bg_color = Color8(232, 220, 196) - sb.set_corner_radius_all(4) - sb.set_border_width_all(1) - sb.border_color = Color8(120, 106, 88) - sb.content_margin_left = 8.0 - sb.content_margin_right = 8.0 - sb.content_margin_top = 6.0 - sb.content_margin_bottom = 6.0 + var sb := UiKit.panel_flat(UiKit.PANEL_HERO, UiKit.PANEL_BORDER, 4, 1, Vector4(8, 6, 8, 6)) add_theme_stylebox_override("panel", sb) var row := HBoxContainer.new() row.add_theme_constant_override("separation", 8) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/hero_info_panel_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/hero_info_panel_view.gd index 5df41818..4082063b 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/hero_info_panel_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/hero_info_panel_view.gd @@ -8,9 +8,9 @@ class_name HeroInfoPanelView extends PanelContainer -const COL_INK := Color8(51, 38, 27) -const COL_GOLD := Color8(240, 168, 40) -const COL_DOT_OFF := Color8(120, 106, 88) +const COL_INK := UiKit.INK +const COL_GOLD := UiKit.GOLD +const COL_DOT_OFF := UiKit.DOT_OFF var _hp_bar: ProgressBar var _hp_label: Label @@ -26,15 +26,7 @@ var _last_rap := 0 # 上次投影值(清零反馈判据—— func _init() -> void: custom_minimum_size = Vector2(240, 0) clip_contents = true - var sb := StyleBoxFlat.new() - sb.bg_color = Color8(232, 220, 196) - sb.set_corner_radius_all(0) - sb.set_border_width_all(1) - sb.border_color = Color8(120, 106, 88) - sb.content_margin_left = 8.0 - sb.content_margin_right = 8.0 - sb.content_margin_top = 6.0 - sb.content_margin_bottom = 6.0 + var sb := UiKit.panel_flat(UiKit.PANEL_HERO, UiKit.PANEL_BORDER, 0, 1, Vector4(8, 6, 8, 6)) add_theme_stylebox_override("panel", sb) var col := VBoxContainer.new() col.add_theme_constant_override("separation", 6) @@ -60,19 +52,19 @@ func _init() -> void: _rap_label = UiKit.label("RAP 0", 13, true) rap_head.add_child(_rap_label) _rap_feedback = UiKit.label("", 12, false) - _rap_feedback.add_theme_color_override("font_color", Color8(140, 124, 100)) + _rap_feedback.add_theme_color_override("font_color", UiKit.STONE_FAINT) col.add_child(_rap_feedback) col.add_child(UiKit.label("状态效果", 14, true)) slot_row = StatusSlotRow.new() col.add_child(slot_row) _status_feedback = UiKit.label("", 12, false) - _status_feedback.add_theme_color_override("font_color", Color8(140, 124, 100)) + _status_feedback.add_theme_color_override("font_color", UiKit.STONE_FAINT) col.add_child(_status_feedback) # 小人立绘占位(程序化色块——真实立绘归 战斗表现) var portrait := ColorRect.new() - portrait.color = Color8(46, 110, 142, 56) + portrait.color = Color(UiKit.HERO_BLUE, 56.0 / 255.0) # 原 Color8(46, 110, 142, 56) portrait.custom_minimum_size = Vector2(0, 120) portrait.size_flags_vertical = Control.SIZE_EXPAND_FILL col.add_child(portrait) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/legend_overlay.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/legend_overlay.gd index 85d2dd9a..bd44e72e 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/legend_overlay.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/legend_overlay.gd @@ -23,7 +23,7 @@ var _panel: PanelContainer func _init() -> void: var dim := ColorRect.new() - dim.color = Color(0.08, 0.06, 0.05, 0.55) + dim.color = Color(UiKit.DIM, 0.55) dim.set_anchors_preset(Control.PRESET_FULL_RECT) dim.gui_input.connect(func(ev: InputEvent): if ev is InputEventMouseButton and ev.pressed: diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/level_strip_view.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/level_strip_view.gd index 8397d6ea..5ca33fad 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/level_strip_view.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/level_strip_view.gd @@ -7,11 +7,11 @@ class_name LevelStripView extends HBoxContainer -const COL_DONE := Color8(140, 116, 60) # 已过——暗金 -const COL_CURRENT := Color8(240, 168, 40) # 当前——奖励金高亮 -const COL_UPCOMING := Color8(64, 58, 52) -const COL_CANDIDATE := Color8(230, 190, 90) # 候选下一跳——亮金边框 -const COL_BOSS_BORDER := Color8(198, 61, 34) # Boss 边框——旗朱 +const COL_DONE := UiKit.GOLD_DIM # 已过——暗金 +const COL_CURRENT := UiKit.GOLD # 当前——奖励金高亮 +const COL_UPCOMING := UiKit.DARK_UPCOMING +const COL_CANDIDATE := UiKit.GOLD_LIT # 候选下一跳——亮金边框 +const COL_BOSS_BORDER := UiKit.FLAG_RED # Boss 边框——旗朱 const NODE_LABELS := {"battle": "战", "reward": "赏", "rest": "疗", "boss": "王"} @@ -63,7 +63,7 @@ func refresh_graph(runner) -> void: func _arrow() -> Label: var arrow := UiKit.label("→", 13, false) - arrow.add_theme_color_override("font_color", Color8(120, 110, 98)) + arrow.add_theme_color_override("font_color", UiKit.STONE) return arrow @@ -79,24 +79,20 @@ func _node_color(i: int, runner) -> Color: func _node_chip(type: String, col: Color, candidate_border: bool, node_id: int = -1) -> PanelContainer: var p := PanelContainer.new() - var sb := StyleBoxFlat.new() - sb.set_corner_radius_all(4) - sb.content_margin_left = 9.0 - sb.content_margin_right = 9.0 - sb.content_margin_top = 2.0 - sb.content_margin_bottom = 2.0 - sb.bg_color = col + var border := col + var border_w := 0 if type == "boss": - sb.set_border_width_all(2) - sb.border_color = COL_BOSS_BORDER + border = COL_BOSS_BORDER + border_w = 2 elif candidate_border: - sb.set_border_width_all(2) - sb.border_color = COL_CANDIDATE + border = COL_CANDIDATE + border_w = 2 + var sb := UiKit.panel_flat(col, border, 4, border_w, Vector4(9, 2, 9, 2)) p.add_theme_stylebox_override("panel", sb) var text := String(NODE_LABELS.get(type, "?")) if node_id >= 0: text += str(node_id) var l := UiKit.label(text, 15, true) - l.add_theme_color_override("font_color", Color8(30, 26, 22) if col != COL_UPCOMING else Color8(160, 150, 138)) + l.add_theme_color_override("font_color", UiKit.INK_TITLE if col != COL_UPCOMING else UiKit.DARK_TEXT_FAINT) p.add_child(l) return p diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/node_overlay.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/node_overlay.gd index 1b74301c..dcdd64ca 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/node_overlay.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/node_overlay.gd @@ -23,7 +23,7 @@ func _init() -> void: box.add_theme_constant_override("separation", 12) center.add_child(box) _label = UiKit.label("", 20, true) - _label.add_theme_color_override("font_color", Color8(240, 226, 200)) + _label.add_theme_color_override("font_color", UiKit.WARM) _label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER box.add_child(_label) _btn = UiKit.button("继续") diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/route_overlay.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/route_overlay.gd index 4fcbec19..e0708714 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/route_overlay.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/route_overlay.gd @@ -10,12 +10,12 @@ extends Control signal route_chosen(node_id: int) -const COL_ROOM_DONE := Color8(140, 116, 60) # 已到——暗金 -const COL_ROOM_CURRENT := Color8(240, 168, 40) # 当前——奖励金 -const COL_ROOM_FUTURE := Color8(64, 58, 52) # 未达——暗 -const COL_PASSAGE := Color8(120, 110, 98) # 通道——石灰 -const COL_PASSAGE_LIT := Color8(230, 190, 90) # 候选通道——亮金 -const COL_BOSS_BORDER := Color8(198, 61, 34) # Boss 边框——旗朱 +const COL_ROOM_DONE := UiKit.GOLD_DIM # 已到——暗金 +const COL_ROOM_CURRENT := UiKit.GOLD # 当前——奖励金 +const COL_ROOM_FUTURE := UiKit.DARK_UPCOMING # 未达——暗 +const COL_PASSAGE := UiKit.STONE # 通道——石灰 +const COL_PASSAGE_LIT := UiKit.GOLD_LIT # 候选通道——亮金 +const COL_BOSS_BORDER := UiKit.FLAG_RED # Boss 边框——旗朱 const NODE_LABELS := {"battle": "战", "reward": "赏", "rest": "疗", "boss": "王"} var _runner = null @@ -35,7 +35,7 @@ func _init() -> void: box.add_theme_constant_override("separation", 10) center.add_child(box) _title = UiKit.label("选择下一跳", 18, true) - _title.add_theme_color_override("font_color", Color8(240, 226, 200)) + _title.add_theme_color_override("font_color", UiKit.WARM) _title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER box.add_child(_title) var canvas := Control.new() @@ -131,8 +131,8 @@ func _draw_graph(canvas: Control) -> void: canvas.draw_rect(rect, COL_PASSAGE_LIT, false, 2.0) var font := ThemeDB.fallback_font var label := String(NODE_LABELS.get(t, "?")) - canvas.draw_string(font, p + Vector2(-6, 2), label, HORIZONTAL_ALIGNMENT_LEFT, -1, 16, Color8(24, 20, 16)) - canvas.draw_string(font, p + Vector2(10, 14), str(nid), HORIZONTAL_ALIGNMENT_LEFT, -1, 10, Color8(210, 196, 170)) + canvas.draw_string(font, p + Vector2(-6, 2), label, HORIZONTAL_ALIGNMENT_LEFT, -1, 16, UiKit.INK_ROUTE) + canvas.draw_string(font, p + Vector2(10, 14), str(nid), HORIZONTAL_ALIGNMENT_LEFT, -1, 10, UiKit.WARM_ROUTE_SUB) func _layout(nodes: Array, canvas: Control) -> Dictionary: diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/settlement_review_overlay.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/settlement_review_overlay.gd index 3f3e25ca..13d888c4 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/settlement_review_overlay.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/settlement_review_overlay.gd @@ -12,7 +12,7 @@ var _log: RichTextLabel func _init() -> void: var dim := ColorRect.new() - dim.color = Color(0.08, 0.06, 0.05, 0.62) + dim.color = Color(UiKit.DIM, 0.62) dim.set_anchors_preset(Control.PRESET_FULL_RECT) dim.gui_input.connect(func(ev: InputEvent): if ev is InputEventMouseButton and ev.pressed: diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/status_slot_row.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/status_slot_row.gd index 88c92943..fefe0490 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/status_slot_row.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/status_slot_row.gd @@ -16,15 +16,15 @@ const MAX_SLOTS := 4 # (2026-09-15 格面资源批补 sapped;2026-09-16 护甲等级掷点批 defense_up → ac_up 换装; # 同日 敌人技能池批补 empower/fortify 敌方增益两键——敌方增益显示 = 敌卡状态行文本 + 本图标键词汇)。 const EFFECT_ICON := { - "attack_up": ["▲", Color8(176, 122, 20), "益"], - "ac_up": ["◇", Color8(46, 110, 142), "益"], - "weaken": ["▼", Color8(46, 110, 142), "益"], - "alert": ["◎", Color8(198, 61, 34), "害"], - "enrage": ["⚔", Color8(198, 61, 34), "害"], - "off_guard": ["✕", Color8(198, 61, 34), "害"], - "sapped": ["☾", Color8(198, 61, 34), "害"], - "empower": ["⇧", Color8(198, 61, 34), "害"], - "fortify": ["▣", Color8(120, 106, 88), "害"], + "attack_up": ["▲", UiKit.GOLD_DEEP, "益"], + "ac_up": ["◇", UiKit.HERO_BLUE, "益"], + "weaken": ["▼", UiKit.HERO_BLUE, "益"], + "alert": ["◎", UiKit.FLAG_RED, "害"], + "enrage": ["⚔", UiKit.FLAG_RED, "害"], + "off_guard": ["✕", UiKit.FLAG_RED, "害"], + "sapped": ["☾", UiKit.FLAG_RED, "害"], + "empower": ["⇧", UiKit.FLAG_RED, "害"], + "fortify": ["▣", UiKit.PANEL_BORDER, "害"], } const EFFECT_SEMANTIC := { "attack_up": "主角攻击加成(hero_offense 池加算)", @@ -39,7 +39,7 @@ const EFFECT_SEMANTIC := { } const SOURCE_NAMES := {"safe_cell": "安全格", "flag_hit": "标中旗", "mine_hit": "踩雷", "clear_reward": "清图奖励"} # 未知图标键的占位纹样(HUD框架:占位也要可见,禁静默空图标) -const ICON_PLACEHOLDER := ["?", Color8(120, 106, 88), "?"] +const ICON_PLACEHOLDER := ["?", UiKit.PANEL_BORDER, "?"] var _tip: PanelContainer var _tip_label: Label @@ -53,18 +53,10 @@ func _init() -> void: _tip.z_index = 10 _tip.mouse_filter = Control.MOUSE_FILTER_IGNORE _tip.visible = false - var sb := StyleBoxFlat.new() - sb.bg_color = Color(0.16, 0.12, 0.09, 0.96) - sb.set_corner_radius_all(2) - sb.set_border_width_all(1) - sb.border_color = Color8(240, 168, 40) - sb.content_margin_left = 6.0 - sb.content_margin_right = 6.0 - sb.content_margin_top = 3.0 - sb.content_margin_bottom = 3.0 + var sb := UiKit.panel_flat(UiKit.TIP_BG, UiKit.GOLD, 2, 1, Vector4(6, 3, 6, 3)) _tip.add_theme_stylebox_override("panel", sb) _tip_label = UiKit.label("", 13, false) - _tip_label.add_theme_color_override("font_color", Color8(240, 226, 200)) + _tip_label.add_theme_color_override("font_color", UiKit.WARM) _tip_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART _tip_label.custom_minimum_size = Vector2(210, 0) _tip.add_child(_tip_label) @@ -106,11 +98,7 @@ func _sync_slots(n: int) -> void: func _make_slot() -> PanelContainer: var slot := PanelContainer.new() slot.custom_minimum_size = Vector2(50, 46) - var sb := StyleBoxFlat.new() - sb.bg_color = Color8(226, 210, 182) - sb.set_corner_radius_all(0) - sb.set_border_width_all(1) - sb.border_color = Color8(120, 106, 88) + var sb := UiKit.panel_flat(UiKit.PANEL_DATA, UiKit.PANEL_BORDER) slot.add_theme_stylebox_override("panel", sb) slot.mouse_entered.connect(_on_slot_hover.bind(slot)) slot.mouse_exited.connect(func(): _tip.visible = false) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/toast_stack.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/toast_stack.gd index 8736fbee..acb18084 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/toast_stack.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/toast_stack.gd @@ -8,9 +8,9 @@ extends Control const LIFE_SEC := 2.5 const MAX_SLOTS := 3 -const COL_INFO := Color8(51, 38, 27) -const COL_WARN := Color8(198, 61, 34) # 旗朱族——拒绝/作废 -const COL_GOLD := Color8(176, 122, 20) # 奖励金族——提示/达成 +const COL_INFO := UiKit.INK +const COL_WARN := UiKit.FLAG_RED # 旗朱族——拒绝/作废 +const COL_GOLD := UiKit.GOLD_DEEP # 奖励金族——提示/达成(深金档) var _slot_box: VBoxContainer @@ -35,14 +35,7 @@ func show_toast(text: String, tone: String = "info") -> void: row.mouse_filter = Control.MOUSE_FILTER_IGNORE row.clip_contents = true # 缺陷①约束:固定槽高裁剪,不回流布局 row.custom_minimum_size = Vector2(0, 24) - var sb := StyleBoxFlat.new() - sb.bg_color = Color(0.94, 0.91, 0.84, 0.95) - sb.set_corner_radius_all(2) - sb.set_border_width_all(1) - sb.content_margin_left = 8.0 - sb.content_margin_right = 8.0 - sb.content_margin_top = 2.0 - sb.content_margin_bottom = 2.0 + var sb := UiKit.panel_flat(UiKit.TOAST_BG, COL_INFO, 2, 1, Vector4(8, 2, 8, 2)) var col := COL_INFO if tone == "warn": col = COL_WARN diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/tune_panel.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/tune_panel.gd index e5c753fa..e9283b77 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/tune_panel.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/tune_panel.gd @@ -121,7 +121,7 @@ func effective_max_hp() -> int: func _build() -> void: var dim := ColorRect.new() - dim.color = Color8(28, 22, 18) + dim.color = UiKit.BG_OVERLAY dim.set_anchors_preset(Control.PRESET_FULL_RECT) add_child(dim) var center := CenterContainer.new() @@ -133,12 +133,12 @@ func _build() -> void: center.add_child(box) var title := UiKit.label("测试用 · 角色数值调整板", 26, true) - title.add_theme_color_override("font_color", Color8(240, 226, 200)) + title.add_theme_color_override("font_color", UiKit.WARM) box.add_child(title) var desc := UiKit.label( "模拟玩家在循环中解锁天赋获得的属性提升(仅测试工具,不落盘)。\n百分比叠加基础值:攻击 %d / 生命 %d。影响所有模式(手动与模拟)。" % [_base_atk, _base_hp], 13, false) - desc.add_theme_color_override("font_color", Color8(200, 188, 166)) + desc.add_theme_color_override("font_color", UiKit.WARM_SOFT) box.add_child(desc) box.add_child(HSeparator.new()) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/ui_kit.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/ui_kit.gd index 4d5cb6fb..12411c3d 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/ui_kit.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/ui_kit.gd @@ -1,16 +1,91 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-11 -# 呈现层共享小部件工厂(各视图视图复用;避免每个视图类重复六行工厂函数)。 +# Date: 2026-09-11(2026-09-20 样式收敛批:全站色板与 StyleBox 工厂单点化) +# 呈现层共享小部件工厂 + 全站取色/描边唯一出口——各视图禁再内联 Color8/StyleBoxFlat +# 字面量;美术批换皮只改本文件(值 = 收敛时各视图现值快照,本批零视觉变化)。 class_name UiKit extends RefCounted +# ── 色板(语义族;值 = 2026-09-20 收敛时现值) ── +const INK := Color8(51, 38, 27) # 墨族——正文/数字(对格底 ≥4.5:1) +const INK_LABEL := Color8(46, 34, 24) # 标签深墨 +const INK_TITLE := Color8(30, 26, 22) # 亮底标题墨 +const INK_ROUTE := Color8(24, 20, 16) # 节点图最深墨 +const INK_ON_GOLD := Color8(60, 44, 20) # 金底上的深墨 + +const PANEL_HERO := Color8(232, 220, 196) # 面板底·主角侧(英雄卡/角色信息框) +const PANEL_ENEMY := Color8(226, 212, 190) # 面板底·敌方卡 +const PANEL_DATA := Color8(226, 210, 182) # 面板底·数据框(AP 条/状态槽) +const PANEL_STAGE := Color8(216, 200, 172) # 面板底·战斗画面区 +const PANEL_BORDER := Color8(120, 106, 88) # 面板细线框;兼熄灭点阵(DOT_OFF 别名) + +const GOLD := Color8(240, 168, 40) # 奖励金 +const GOLD_DEEP := Color8(176, 122, 20) # 深金(金框描边/达意金) +const GOLD_LIT := Color8(230, 190, 90) # 亮金(候选高亮) +const GOLD_DIM := Color8(140, 116, 60) # 暗金(已过节点) + +const FLAG_RED := Color8(198, 61, 34) # 旗朱 +const RED_DEEP := Color8(150, 60, 48) # 深朱(敌卡框/敌像) +const RED_MINE := Color8(150, 44, 36) # 引爆雷字朱(已开雷格"雷"字) +const RED_FORBID := Color8(120, 60, 50) # 禁止框朱 +const RED_ALERT := Color8(200, 60, 48) # 报错朱 + +const HERO_BLUE := Color8(46, 110, 142) # 小人蓝 +const BOSS_PURPLE := Color8(143, 47, 106) # 紫赤(Boss 专属) +const DEBUFF_PURPLE := Color8(122, 66, 148) # 妨害紫(意图 ☠) + +const DUSK := Color8(90, 108, 140) # 暮蓝(全作唯一暮蓝档——失败终局) + +const WARM := Color8(240, 226, 200) # 暖白(暗底正文) +const WARM_SOFT := Color8(200, 188, 166) # 暖白次级(说明文) +const WARM_FAINT := Color8(178, 166, 146) # 暖白弱化(帮助文) +const WARM_ROUTE_SUB := Color8(210, 196, 170) # 节点图编号暖白 + +const STONE := Color8(120, 110, 98) # 灰石(通道/箭头/失效) +const STONE_FAINT := Color8(140, 124, 100) # 灰石弱化(占位提示文) +const DARK_UPCOMING := Color8(64, 58, 52) # 未达暗字(底/文同值) +const DARK_TEXT_FAINT := Color8(160, 150, 138)# 未达节点文字 + +const BRICK := Color8(201, 175, 131) # 棋盘·未开掩尘地砖 #C9AF83 +const FLOOR := Color8(179, 154, 120) # 棋盘·已开裸土 #B39A78 +const DIG_EDGE := Color8(120, 190, 120) # 可挖域呼吸微光绿 +const DIG_EDGE_DEEP := Color8(46, 80, 60) # 可挖域呼吸暗端(lerp 目标) + +const BG_ROOT := Color8(30, 25, 20) # 屏幕根底 +const BG_OVERLAY := Color8(28, 22, 18) # 模态遮罩底 +const DIM := Color(0.08, 0.06, 0.05) # 遮罩基色(用时乘 alpha) +const TOAST_BG := Color(0.94, 0.91, 0.84, 0.95) # toast 面底 +const TIP_BG := Color(0.16, 0.12, 0.09, 0.96) # tooltip 深底 + +# BBCode 十六进制(RichTextLabel 用;与上同值) +const HEX_GOLD := "f0a828" +const HEX_INK := "33261b" +const HEX_ON_GOLD := "3a2a08" + +# 语义别名(同值异名——语义站点用别名,值仍单点) +const DOT_OFF := PANEL_BORDER + + +# ── StyleBox 工厂 ── +# margin = (左, 上, 右, 下);border_w = 0 即无边框(根底/遮罩用) +static func panel_flat(bg: Color, border: Color, corner: int = 0, border_w: int = 1, margin: Vector4 = Vector4.ZERO) -> StyleBoxFlat: + var sb := StyleBoxFlat.new() + sb.bg_color = bg + sb.set_corner_radius_all(corner) + sb.set_border_width_all(border_w) + sb.border_color = border + sb.content_margin_left = margin.x + sb.content_margin_top = margin.y + sb.content_margin_right = margin.z + sb.content_margin_bottom = margin.w + return sb + static func label(text: String, size: int, bold: bool) -> Label: var l := Label.new() l.text = text l.add_theme_font_size_override("font_size", size) if bold: - l.add_theme_color_override("font_color", Color8(46, 34, 24)) + l.add_theme_color_override("font_color", INK_LABEL) return l