feat(ui): T2 框材组 8 件换皮接线批(样张 v2 冻结色板量化)——UiKit 单点工厂+五视图接线
♻ 复用件审阅+量化改色(tools/quantize_ui_skin.py,全 CC0,闸①色板 token 渐变带重映射/闸②token 天然合规/闸③图标四形互异/闸④授权干净):panel_stone/button_stone 两态/backdrop_stone/border_stone/营地图标四件(钥石金+柜台暖白)九件入 game/assets/art/ui/(PNG 不入 git,缺位 load_tex null 回退)。 接线=UiKit 单点:panel_skinned(B 区舞台 tint PANEL_STAGE/C 区主面板/图例面板+墨字随行改色 §7.2)+_apply_button_skin(全站按钮两态皮+墨字,UiKit.button 消费点零改)+frame_skinned(营地仪式石框容器)+icon_rect(营地钥石行/三柜台头图标,缺位纯文本回退)+开始界面石纹底噪底层(ui_assembler,z 序 dim 之上内容之下)。数据框/暗卡/结算回看保持素面或暗底(§7.1 数据素面纪律)。 ✦ B 区背景横幅不生图列缺料清单(归 T5 交付)。8 件=面板九宫格/按钮常态/按钮按压/石纹底噪/仪式石框/钥石图标/柜台图标组/B 区横幅(缺料)。轻闸=冒烟 557/0+四探针 PASS(带素材模式)+编辑器导入 9 件零报错。
This commit is contained in:
1 parent
f9b0765412
commit
0ad16747fc
7 files changed
+244
-12
No files matched your search
@@ -95,6 +95,16 @@ static func build_overlays(host: Control, db, base_atk: int, base_hp: int) -> Di
|
||||
# 单场遭遇用户入口已删(2026-09-13 用户裁决——单场原语仅探针经 debug_session.start_single 使用))
|
||||
static func build_start_overlay(host: Control, db = null) -> Dictionary:
|
||||
var overlay := overlay_bg(host, UiKit.BG_OVERLAY)
|
||||
# 石纹底噪底层(样张 v2 冻结批 T2——z 序=dim 之上/内容之下;缺位不挂即回退平色)
|
||||
var bd_tex := UiKit.load_tex(UiKit.TEX_BACKDROP_STONE)
|
||||
if bd_tex != null:
|
||||
var bd := TextureRect.new()
|
||||
bd.texture = bd_tex
|
||||
bd.stretch_mode = TextureRect.STRETCH_TILE
|
||||
bd.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
bd.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
bd.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
overlay.add_child(bd)
|
||||
var box := overlay_box(overlay)
|
||||
var title := UiKit.label("Dungeon Sweeper", 34, true)
|
||||
title.add_theme_color_override("font_color", UiKit.WARM)
|
||||
|
||||
@@ -41,9 +41,10 @@ var world: Node2D # StageWorld(preload 脚本实例——Node2D 世
|
||||
|
||||
func _init(db_ref) -> void:
|
||||
custom_minimum_size = Vector2(0, 252)
|
||||
# 面板底(PanelContainer 面板样式等价平移——Control 壳不自绘 stylebox,Panel 子面承载)
|
||||
# 面板底(PanelContainer 面板样式等价平移——Control 壳不自绘 stylebox,Panel 子面承载;
|
||||
# 石板皮 = 样张 v2 冻结批 T2——缺位回退 PANEL_DATA flat,渲染观感不变)
|
||||
var bg := Panel.new()
|
||||
var sb := UiKit.panel_flat(UiKit.PANEL_STAGE, UiKit.PANEL_BORDER, 0, 1, Vector4(6, 4, 6, 4))
|
||||
var sb := UiKit.panel_skinned(Vector4(6, 4, 6, 4), Color(0.956, 0.952, 0.945)) # tint=PANEL_STAGE 对 PANEL_DATA 比值
|
||||
bg.add_theme_stylebox_override("panel", sb)
|
||||
bg.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
bg.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
|
||||
@@ -34,30 +34,39 @@ func _init() -> void:
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.add_child(center)
|
||||
var frame := PanelContainer.new()
|
||||
frame.add_theme_stylebox_override("panel", UiKit.frame_skinned(Vector4(26, 22, 26, 22))) # 仪式石框(T2;缺位回退暗面板)
|
||||
center.add_child(frame)
|
||||
var box := VBoxContainer.new()
|
||||
box.add_theme_constant_override("separation", 6)
|
||||
center.add_child(box)
|
||||
frame.add_child(box)
|
||||
var title := UiKit.label("营地 · 永久强化", 24, true)
|
||||
title.add_theme_color_override("font_color", UiKit.WARM)
|
||||
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
box.add_child(title)
|
||||
var bal_row := HBoxContainer.new()
|
||||
bal_row.add_theme_constant_override("separation", 6)
|
||||
bal_row.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
var keystone_icon := UiKit.icon_rect(UiKit.TEX_ICON_KEYSTONE, 18) # 缺位 null → 纯文本回退
|
||||
if keystone_icon != null:
|
||||
bal_row.add_child(keystone_icon)
|
||||
_balance_label = UiKit.label("钥石 0", 18, true)
|
||||
_balance_label.add_theme_color_override("font_color", UiKit.GOLD)
|
||||
_balance_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
box.add_child(_balance_label)
|
||||
bal_row.add_child(_balance_label)
|
||||
box.add_child(bal_row)
|
||||
box.add_child(HSeparator.new())
|
||||
|
||||
box.add_child(_counter_header("属性锻造(钥石直购 · 每级 flat 整数 · 价格几何递增)"))
|
||||
box.add_child(_counter_header("属性锻造(钥石直购 · 每级 flat 整数 · 价格几何递增)", UiKit.TEX_ICON_FORGE))
|
||||
_forge_holder = VBoxContainer.new()
|
||||
_forge_holder.add_theme_constant_override("separation", 4)
|
||||
box.add_child(_forge_holder)
|
||||
|
||||
box.add_child(_counter_header("道具工坊(累计通关次数解锁 · 局内效果排 Alpha 魔法道具重设计批)"))
|
||||
box.add_child(_counter_header("道具工坊(累计通关次数解锁 · 局内效果排 Alpha 魔法道具重设计批)", UiKit.TEX_ICON_WORKSHOP))
|
||||
_workshop_holder = VBoxContainer.new()
|
||||
_workshop_holder.add_theme_constant_override("separation", 4)
|
||||
box.add_child(_workshop_holder)
|
||||
|
||||
box.add_child(_counter_header("奖励格图鉴"))
|
||||
box.add_child(_counter_header("奖励格图鉴", UiKit.TEX_ICON_ATLAS))
|
||||
var lock_l := UiKit.label(" —— 柜台结构位预留:内容排 Alpha(地图战斗资源差异化批)", 13, false)
|
||||
lock_l.add_theme_color_override("font_color", UiKit.WARM_FAINT)
|
||||
box.add_child(lock_l)
|
||||
@@ -80,10 +89,17 @@ func _init() -> void:
|
||||
visible = false
|
||||
|
||||
|
||||
func _counter_header(text: String) -> Label:
|
||||
func _counter_header(text: String, icon_path := "") -> Control:
|
||||
var row := HBoxContainer.new()
|
||||
row.add_theme_constant_override("separation", 6)
|
||||
if icon_path != "":
|
||||
var ic := UiKit.icon_rect(icon_path, 16) # 缺位 null → 纯文本回退
|
||||
if ic != null:
|
||||
row.add_child(ic)
|
||||
var l := UiKit.label(text, 15, true)
|
||||
l.add_theme_color_override("font_color", UiKit.WARM_SOFT)
|
||||
return l
|
||||
row.add_child(l)
|
||||
return row
|
||||
|
||||
|
||||
# ---- 柜台行构建(open_camp 重建;行结构仿 ShopOverlay 商品卡)----
|
||||
|
||||
@@ -22,7 +22,8 @@ var _bonus_list: VBoxContainer
|
||||
func _init() -> void:
|
||||
custom_minimum_size = Vector2(240, 0)
|
||||
clip_contents = true
|
||||
var sb := UiKit.panel_flat(UiKit.PANEL_HERO, UiKit.PANEL_BORDER, 0, 1, Vector4(8, 6, 8, 6))
|
||||
# 主面板穿石板戏服(样张 v2 冻结批 T2——纹理本色≈PANEL_HERO;数据框仍素面 §7.1;缺位回退 flat)
|
||||
var sb := UiKit.panel_skinned(Vector4(8, 6, 8, 6))
|
||||
add_theme_stylebox_override("panel", sb)
|
||||
var col := VBoxContainer.new()
|
||||
col.add_theme_constant_override("separation", 14) # 布局充实(2026-09-26 反馈③:区段间距放大)
|
||||
|
||||
@@ -33,12 +33,15 @@ func _init() -> void:
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.add_child(center)
|
||||
_panel = PanelContainer.new()
|
||||
_panel.add_theme_stylebox_override("panel", UiKit.panel_skinned(Vector4(12, 10, 12, 10))) # 石板皮(T2;缺位回退 flat)
|
||||
center.add_child(_panel)
|
||||
var box := VBoxContainer.new()
|
||||
box.custom_minimum_size = Vector2(520, 0)
|
||||
box.add_theme_constant_override("separation", 6)
|
||||
_panel.add_child(box)
|
||||
box.add_child(UiKit.label("图例 · 格态", 20, true))
|
||||
var title := UiKit.label("图例 · 格态", 20, true)
|
||||
title.add_theme_color_override("font_color", UiKit.INK_TITLE) # 亮底墨字(§7.2 数据素面)
|
||||
box.add_child(title)
|
||||
box.add_child(HSeparator.new())
|
||||
for e in ENTRIES:
|
||||
var row := HBoxContainer.new()
|
||||
@@ -48,6 +51,7 @@ func _init() -> void:
|
||||
chip.color = Color(e[0])
|
||||
row.add_child(chip)
|
||||
var lab := UiKit.label("%s —— %s" % [e[1], e[2]], 13, false)
|
||||
lab.add_theme_color_override("font_color", UiKit.INK_LABEL) # 亮底墨字(§7.2 数据素面)
|
||||
lab.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
lab.custom_minimum_size = Vector2(440, 0)
|
||||
row.add_child(lab)
|
||||
|
||||
@@ -98,6 +98,18 @@ const TEX_ENEMY_DUERGAR := "res://assets/art/character/character_enemy_duergar.p
|
||||
const TEX_ENEMY_HOOK_HORROR := "res://assets/art/character/character_enemy_hook_horror.png" # 钩爪恐魔
|
||||
const TEX_ENEMY_DUERGAR_KING := "res://assets/art/character/character_enemy_duergar_king.png" # 灰矮人石君王
|
||||
|
||||
# 框材组纹理槽(样张 v2 冻结批 T2 2026-09-28——♻ 复用件量化改色入包,产物 = tools/quantize_ui_skin.py,
|
||||
# 全 CC0;缺位 = load_tex null → 程序化回退原路径,冒烟安全)
|
||||
const TEX_PANEL_STONE := "res://assets/art/ui/panel_stone.png" # 石板亮面板九宫格 48×48
|
||||
const TEX_BUTTON_STONE := "res://assets/art/ui/button_stone.png" # 按钮九宫格·常态(可按的砖)
|
||||
const TEX_BUTTON_STONE_PRESSED := "res://assets/art/ui/button_stone_pressed.png" # 按钮九宫格·按压(下沉一档)
|
||||
const TEX_BACKDROP_STONE := "res://assets/art/ui/backdrop_stone.png" # 石纹底噪 256×256 无缝
|
||||
const TEX_BORDER_STONE := "res://assets/art/ui/border_stone.png" # 仪式石框(空心角括框)
|
||||
const TEX_ICON_KEYSTONE := "res://assets/art/ui/icon_keystone.png" # 钥石图标(奖励金)
|
||||
const TEX_ICON_FORGE := "res://assets/art/ui/icon_forge.png" # 柜台一·属性锻造
|
||||
const TEX_ICON_WORKSHOP := "res://assets/art/ui/icon_workshop.png" # 柜台二·道具工坊
|
||||
const TEX_ICON_ATLAS := "res://assets/art/ui/icon_atlas.png" # 柜台三·奖励格图鉴
|
||||
|
||||
|
||||
# 素材纹理守卫装载(exists 检查避开缺位树上 ResourceLoader 报错刷屏——冒烟/无素材检出静默回退)
|
||||
static func load_tex(path: String) -> Texture2D:
|
||||
@@ -133,4 +145,76 @@ static func label(text: String, size: int, bold: bool) -> Label:
|
||||
static func button(text: String) -> Button:
|
||||
var b := Button.new()
|
||||
b.text = text
|
||||
_apply_button_skin(b)
|
||||
return b
|
||||
|
||||
|
||||
# ── 框材纹理工厂(样张 v2 冻结批 T2——§7.1 容器穿戏服、数据素面;缺位回退 flat/主题默认) ──
|
||||
# 九宫格 StyleBoxTexture(texture_margin 8px——quantize 脚本同值);tint 供消费点微调色调
|
||||
static func _tex_sb(tex: Texture2D, margin: float, tint := Color.WHITE) -> StyleBoxTexture:
|
||||
var sb := StyleBoxTexture.new()
|
||||
sb.texture = tex
|
||||
sb.texture_margin_left = margin
|
||||
sb.texture_margin_top = margin
|
||||
sb.texture_margin_right = margin
|
||||
sb.texture_margin_bottom = margin
|
||||
sb.modulate_color = tint
|
||||
return sb
|
||||
|
||||
|
||||
# 石板亮面板(B 区舞台/C 区主面板/图例——容器穿戏服;数据框仍 panel_flat 素面 §7.1)
|
||||
static func panel_skinned(margin: Vector4 = Vector4.ZERO, tint := Color.WHITE) -> StyleBox:
|
||||
var tex := load_tex(TEX_PANEL_STONE)
|
||||
if tex == null:
|
||||
return panel_flat(PANEL_DATA, PANEL_BORDER, 4, 1, margin)
|
||||
var sb := _tex_sb(tex, 8.0, tint)
|
||||
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 frame_skinned(margin: Vector4 = Vector4.ZERO) -> StyleBox:
|
||||
var tex := load_tex(TEX_BORDER_STONE)
|
||||
if tex == null:
|
||||
return panel_flat(BG_OVERLAY, PANEL_BORDER, 6, 1, margin)
|
||||
var sb := _tex_sb(tex, 12.0)
|
||||
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
|
||||
|
||||
|
||||
# 图标槽(营地钥石/柜台件——缺位返回 null,消费点不挂 TextureRect 即回退纯文本)
|
||||
static func icon_rect(tex_path: String, px: float) -> TextureRect:
|
||||
var t := load_tex(tex_path)
|
||||
if t == null:
|
||||
return null
|
||||
var tr := TextureRect.new()
|
||||
tr.texture = t
|
||||
tr.custom_minimum_size = Vector2(px, px)
|
||||
tr.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||
tr.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
tr.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
return tr
|
||||
|
||||
|
||||
# 按钮皮(常态/按压两态+墨字——缺位 = 引擎默认主题,素材批前逐位一致)
|
||||
static func _apply_button_skin(b: Button) -> void:
|
||||
var tex_n := load_tex(TEX_BUTTON_STONE)
|
||||
if tex_n == null:
|
||||
return
|
||||
var tex_p := load_tex(TEX_BUTTON_STONE_PRESSED)
|
||||
b.add_theme_stylebox_override("normal", _tex_sb(tex_n, 8.0))
|
||||
b.add_theme_stylebox_override("hover", _tex_sb(tex_n, 8.0))
|
||||
if tex_p != null:
|
||||
b.add_theme_stylebox_override("pressed", _tex_sb(tex_p, 8.0))
|
||||
b.add_theme_stylebox_override("disabled", _tex_sb(tex_p, 8.0))
|
||||
b.add_theme_color_override("font_color", INK)
|
||||
b.add_theme_color_override("font_hover_color", INK)
|
||||
b.add_theme_color_override("font_pressed_color", INK)
|
||||
b.add_theme_color_override("font_focus_color", INK)
|
||||
b.add_theme_color_override("font_disabled_color", Color(INK, 0.45))
|
||||
Reference in new issue
Block a user