Files
gplan-2/game/presentation/views/board_world.gd
T
DKChan 5c9c5f8083 refactor(iter37③): boardview 拆件——瓦片调色板/英雄精灵两族出根(行为等价,golden 逐像素零变)
r2-1 瓦片族(排版+素材装载+墨族判据+查表)→ views/tile_palette.gd;
r2-2 英雄族(贴图/位移/影/朝向/缩放几何)→ views/hero_sprite.gd(Node2D);
r2-3 board_view 改引+直引面换指(terrain_tile_sets_test/ui_contrast_probe),
探针与 main 的组合根直读面经转发属性/常量别名保持零改动。

S13 计数守恒:基线含类变量数/公有方法数两条计数型键,故 board_view 用 13 个转发属性
+2 个组件引用压回原计数(45 变量/27 公有方法);baselined 的 wall_tile_for/
wall_center_tile/digit_ink_mode 以查表/辅助函数重构压回阈值内(非改名保违例),
旧文件级键随函数迁出自然失效——基线文件零改动(用户令:只改代码不改基线)。

验收:terrain_tile_sets_test 19 检查绿(判据读数与迁移前同值);gdstyle 基线外新违规 0;
S9/S10 绿;probe_gate --click 全绿(含 ui_input_probe 十八断言/click 走查 0 问题);
render_gate 棋盘三图+菜单 golden changed=0.00%;撤销证明:测试改引回退旧址符号
→ SCRIPT ERROR(Parse Error: Static function "_normalize_floor_luma()" not found)+
error_scan exit 1,还原后 19 检查复绿、error_scan exit 0。
2026-10-25 06:43:03 +08:00

106 lines
5.3 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## VERTICAL SLICE - NOT FOR PRODUCTION
## BoardWorld——棋盘 Node2D 世界根(SubViewport 内 CellUnit 容器):世界级去饱和材质与字体注入挂点。
## 无 class_name——使用方经 preload 引用。
extends Node2D
var board_font: Font = null # 字体注入槽位(null = ThemeDB.fallback_font)
var hero: Sprite2D = null # 英雄单位精灵(移动实体独立于 CellUnit 格面
# 语义,计划书 §3.A;null = 未创建/随 rebuild 清场,BoardView.refresh 经
# ensure_hero 重建。texture 缺位时 BoardView 不调本方法=字形「人」回退路径)
# 英雄精灵惰性创建(幂等):脚底锚(offset 上移半高——scale.y 弹跳向脚底收敛不悬空)+ z_index=1
# 压格面之上(挥铲特效在 SubViewport 之外恒更上层,满足「格面之上、特效之下」叠序);NEAREST =
# SubViewport 缩放下像素清晰(默认 Linear 会糊);use_parent_material = 随世界去饱和材质灰化
#(结算期与 CellUnit 同口径)。返回值便于 BoardView 即时落位。
# 脚下椭圆影(走 Godot 组件合成、贴图零改动):径向渐变纹理 ×黑色半透明
# modulate 压扁,挂英雄子件(z_index=-1 相对回落格面之上、英雄之下——位移/翻转/弹跳随父件
# 同步免费拿;尺寸换算归 HeroSprite.SHADOW_PX 常量)。纹理 filter 用 LINEAR 保渐变平滑
#(NEAREST 会把渐变打回条带)。
func ensure_hero(tex: Texture2D, shadow_px: Vector2, scale: float) -> Sprite2D:
if hero != null:
return hero
var grad := Gradient.new()
grad.set_color(0, Color(1, 1, 1, 1))
grad.set_color(1, Color(1, 1, 1, 0))
var shadow_tex := GradientTexture2D.new()
shadow_tex.gradient = grad
shadow_tex.width = 64
shadow_tex.height = 64
shadow_tex.fill = GradientTexture2D.FILL_RADIAL
shadow_tex.fill_from = Vector2(0.5, 0.5)
shadow_tex.fill_to = Vector2(0.5, 0.0)
var shadow := Sprite2D.new()
shadow.texture = shadow_tex
shadow.modulate = Color(0, 0, 0, 0.35)
shadow.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR
shadow.scale = shadow_px / (64.0 * scale) # 子件缩放叠父件 scale——目标屏幕尺寸 ÷ (纹理边 × 父档)
shadow.position = Vector2.ZERO # 椭圆中心 = 脚锚点(贴脚)
shadow.z_index = -1 # 相对父件回落:格面(z=0 树序在先)之上、英雄本体之下
shadow.use_parent_material = true # 随英雄链世界去饱和材质
hero = Sprite2D.new()
hero.texture = tex
hero.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
hero.centered = true
# 脚底对齐:素材底部 7 行全透明(内容底 = 源 row 24,自中心 16−7.5=8.5px),故 offset.y = −8.5
# → 内容底恰落 position(脚锚=格底往上 25% 线——头仍越上格沿)
hero.offset = Vector2(0.0, -8.5) # 纹理中心上移 8.5 源 px——position = 视觉脚底中点
hero.z_index = 1
hero.use_parent_material = true
add_child(hero)
hero.add_child(shadow)
return hero
# ── 立体悬崖(BoardView.set_cell_area / _update_world_size 单点驱动;厚度 8px=中档)──
var depth_px := 0.0: # 悬崖厚度(像素;0 = 平面)
set(v):
depth_px = v
queue_redraw()
var slab := Vector2.ZERO: # 网格矩形像素尺寸(不含悬崖外延)
set(v):
slab = v
queue_redraw()
var stride_px := 48.0: # 格步距(cell + SEP——列分隔缝对齐格边界)
set(v):
stride_px = v
queue_redraw()
var cols := 0: # 列数(正面悬崖竖缝数 = cols−1)
set(v):
cols = v
queue_redraw()
var mat: Color = UiKit.BRICK # 材质锚色(掩尘 #C9AF83 与 UiKit.BRICK 同值;侧面由此派生明暗,BoardView 传入可覆写)
func _draw() -> void:
if depth_px <= 0.0 or slab == Vector2.ZERO:
return
var w := slab.x
var h := slab.y
var d := depth_px
var front := mat.darkened(0.55) # 正面悬崖(背光)
var right := mat.darkened(0.38) # 右侧悬崖(微受光)
# 正面悬崖带 + 右侧悬崖带
draw_rect(Rect2(0, h, w, d), front, true)
draw_rect(Rect2(w, 0, d, h + d), right, true)
# 正面列分隔竖缝(对齐格边界——ITB 悬崖列感)
for i in range(1, cols):
var x := float(i) * stride_px - 1.0
draw_rect(Rect2(x, h, 2.0, d), front.darkened(0.25), true)
# 岩层横纹(两条微暗横带——碎石层理)
draw_rect(Rect2(0, h + d * 0.38, w, 1.5), front.darkened(0.18), true)
draw_rect(Rect2(0, h + d * 0.72, w, 1.5), front.darkened(0.12), true)
# 悬崖口沿高光(顶面与悬崖交界 1px 亮线——倒角受光)
draw_rect(Rect2(0, h, w, 1.0), mat.lightened(0.18), true)
draw_rect(Rect2(w, 0, 1.0, h), mat.lightened(0.12), true)
# 顶面接触 AO(网格内侧贴边 2px 暗带——顶面陷进阴影的衔接感)
draw_rect(Rect2(0, h - 2.0, w, 2.0), Color(0, 0, 0, 0.18), true)
draw_rect(Rect2(w - 2.0, 0, 2.0, h), Color(0, 0, 0, 0.14), true)
# 底线(悬崖最底 2px 最暗——收边)
draw_rect(Rect2(0, h + d - 2.0, w + d, 2.0), front.darkened(0.35), true)
# 底部悬浮影(中厚档起——悬浮岛离地感;三层渐隐)
if d >= 8.0:
var layers := [Color(0, 0, 0, 0.16), Color(0, 0, 0, 0.10), Color(0, 0, 0, 0.05)]
for i in layers.size():
var sh := 3.0 + float(i) * 3.0
draw_rect(Rect2(sh, h + d + sh * 0.5, w + d - sh * 1.5, float(2 + i)), layers[i], true)