Files
gplan-2/game/presentation/views/board_cell_unit.gd
T

118 lines
5.7 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
# 棋盘 Node2D 迁移批 Phase A 2026-09-23:CellUnit——BoardView SubViewport 世界内逐格渲染件(Node2D)。
# 固定叠层序(ADR-0006 Decision 4):砖面底 < 变异纹带 < 数字/徽章 < 旗 < 焦点高亮——本批全部程序化
# _draw 等价平移现行占位视觉;每层留 texture 槽位(art-bible §8.2 格面 32×32 暂定档——终稿 1:1 换入,
# 本批不实现纹理加载)。无 class_name(类名缓存面纪律——BoardView 经 preload 使用)。
# 字体:font 槽位缺省 = ThemeDB.fallback_font(与旧 Button 缺省主题字体同源);注入挂点归
# BoardView.set_world_font(SubViewport 内主题不自动继承主场景,Phase B 复用面)。
# 行为等价(缺陷①回归约束):格件常驻定长、逐格重绘由 BoardView 驱动,本类零游戏状态——渲染数据
# 全部由 BoardView 每次 paint 写入(bg_sb/glyph/badge),呼吸微光由 BoardView 就地改 bg_sb 边框。
extends Node2D
var cell := Vector2i.ZERO # 板坐标(诊断观测面)
var edge := 46.0: # 格边长(BoardView.set_cell_area 单点驱动)
set(v):
edge = v
queue_redraw()
var bg_sb: StyleBoxFlat = null # 格底 StyleBox(BoardView 每次 paint 重建;呼吸微光就地改边框)
var glyph := "": # 文字位——数字/雷/旗/人/?(现行视觉旗与数字互斥,同位承载)
set(v):
glyph = v
queue_redraw()
var glyph_color := UiKit.INK: # 文字色(墨族/雷朱/旗朱/小人蓝)
set(v):
glyph_color = v
queue_redraw()
var badge_glyph := "": # 奖励徽章文字(右下角金——旗之下、变异纹之上、不进数字区)
set(v):
badge_glyph = v
queue_redraw()
var dot_visible := false: # BFS 路径预览点迹(中心 6×6 小人蓝——旧 ColorRect 等价)
set(v):
dot_visible = v
queue_redraw()
var hl_visible := false: # 焦点高亮(悬停态边框覆盖层)
set(v):
hl_visible = v
queue_redraw()
var hl_color := UiKit.GOLD: # 高亮色(金目标/旗朱/禁入灰禁红)
set(v):
hl_color = v
queue_redraw()
var font: Font = null # 字体槽位(null = ThemeDB.fallback_font——BoardView.set_world_font 注入)
var bevel := 0.0: # 顶面倒角强度(0=关——立体原型批 2026-09-24;档位 0/0.35/0.6/1.0)
set(v):
bevel = v
queue_redraw()
# ── 素材槽位(本批全 null = 程序化占位服役;art-bible §8.2 格面 32×32 暂定档)──
var tex_base: Texture2D = null # ① 砖面底
var tex_mutation: Texture2D = null # ② 变异纹带
var tex_glyph: Texture2D = null # ③ 数字
var tex_badge: Texture2D = null # ③' 徽章
var tex_flag: Texture2D = null # ④ 旗
func _draw() -> void:
var rect := Rect2(Vector2.ZERO, Vector2(edge, edge))
# ① 砖面底(占位 = StyleBoxFlat:格底色 + 暗化描边 + 3px 圆角——旧 Button normal 样式等价;
# 呼吸微光/主角蓝框由 BoardView 改 bg_sb 后触发重绘)
if tex_base != null:
draw_texture_rect(tex_base, rect, false)
elif bg_sb != null:
draw_style_box(bg_sb, rect)
# 顶面倒角(立体原型批:光源左上——上/左内沿受光 2px、下/右内沿背光 2px;内缩 2px 让
# 呼吸微光/主角蓝边框保持最外沿可见;强度随档位)
if bevel > 0.0:
var base: Color = bg_sb.bg_color
var lit: Color = base.lightened(0.22 * bevel)
var dark: Color = base.darkened(0.22 * bevel)
var t := 2.0
draw_rect(Rect2(t, t, edge - t * 2.0, t), lit, true)
draw_rect(Rect2(t, t, t, edge - t * 2.0), lit, true)
draw_rect(Rect2(t, edge - t * 2.0, edge - t * 2.0, t), dark, true)
draw_rect(Rect2(edge - t * 2.0, t, t, edge - t * 2.0), dark, true)
# ② 变异纹带(占位批次无程序化纹带——槽位先行,终稿换入即用)
if tex_mutation != null:
draw_texture_rect(tex_mutation, rect, false)
# ③ 数字/徽章(数字 ≥ 格高 50% 墨族对格底 ≥4.5:1;徽章右下角金,遮蔽态 = "?")
if glyph != "":
if tex_glyph != null:
draw_texture_rect(tex_glyph, rect, false)
else:
_draw_glyph(glyph, glyph_color, maxi(14, int(edge * 0.5)))
if badge_glyph != "":
if tex_badge != null:
draw_texture_rect(tex_badge, rect, false)
else:
_draw_badge(badge_glyph)
# ④ 旗(现行视觉旗文字在 ③ 文字位承载——独立槽位留给终稿旗图)
if tex_flag != null:
draw_texture_rect(tex_flag, rect, false)
# ⑤ 路径点迹 + 焦点高亮(悬停态覆盖层,不参与命中)
if dot_visible:
var ds := 6.0
draw_rect(Rect2(Vector2((edge - ds) * 0.5, (edge - ds) * 0.5), Vector2(ds, ds)), UiKit.HERO_BLUE, true)
if hl_visible:
draw_rect(Rect2(1, 1, edge - 2.0, edge - 2.0), hl_color, false, 2.0) # 2px 内描边(旧 hl Panel 等价)
# 文字位绘制:水平居中 + 垂直居中(基线 = (格高 − 字高)/2 + 上伸部——旧 Button 居中对齐等价)
func _draw_glyph(g: String, col: Color, fs: int) -> void:
var f := font if font != null else ThemeDB.fallback_font
if f == null:
return
var asc := f.get_ascent(fs)
var desc := f.get_descent(fs)
draw_string(f, Vector2(0.0, (edge - (asc + desc)) * 0.5 + asc), g,
HORIZONTAL_ALIGNMENT_CENTER, edge, fs, col)
# 徽章绘制:右下角金(旧 Label BOTTOM_RIGHT 锚点等价——文字贴角内缩 2–3px)
func _draw_badge(g: String) -> void:
var f := font if font != null else ThemeDB.fallback_font
if f == null:
return
var fs := maxi(10, int(edge * 0.28))
var sz := f.get_string_size(g, HORIZONTAL_ALIGNMENT_LEFT, -1, fs)
draw_string(f, Vector2(edge - sz.x - 2.0, edge - 3.0), g, HORIZONTAL_ALIGNMENT_LEFT, -1, fs, UiKit.GOLD)