merge: 棋盘立体三档原型 F9 可切换(用户拍板 2026-09-24,台账 153)

This commit is contained in:
DKChan committed 2026-09-24 05:40:06 +08:00
commit d333a15c35
4 files changed
+117 -4

No files matched your search

+9
View File
@@ -549,6 +549,15 @@ func _on_chord_attempted(_cell: Vector2i) -> void:
_show_hint("本作无双击快开——插旗后轮末自动判定标中;点数字格可移动小人", "chord")
# 立体原型档切换(F9 循环:平面→薄→中→厚——2026-09-24 用户拍板三档实机对比;定稿后此入口退役归表现批)
func _unhandled_key_input(event: InputEvent) -> void:
if event is InputEventKey and event.pressed and not event.echo and event.keycode == KEY_F9:
if board_view == null or board_view.board() == null:
return
var tier: String = board_view.set_depth_mode((board_view.depth_mode + 1) % board_view.DEPTH_NAMES.size())
board_zone.toast.show_toast("棋盘立体档:%s(F9 继续切换)" % tier, "info")
func _show_hint(text: String, hint_id: String) -> void:
_hints_shown[hint_id] = true
logger.log_ux("ux_hint_shown", {"hint_id": hint_id})
@@ -40,6 +40,10 @@ var hl_color := UiKit.GOLD: # 高亮色(金目标/旗朱/禁入灰禁
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 # ② 变异纹带
@@ -56,6 +60,17 @@ func _draw() -> void:
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)
+36 -4
View File
@@ -47,6 +47,13 @@ const CURSOR_MOVE_SEM := Input.CURSOR_ARROW # 移动——箭头(命名
const CHORD_WINDOW_MS := 350
const SEP := 2 # 格间距(旧 GridContainer v/h_separation 同值——格尺寸公式与命中换算共用)
# 立体原型档位(2026-09-24 用户拍板三档实机对比——F9 循环切换;定稿参数归格子样张批 §1.4 冻结)
const DEPTH_NAMES := ["平面(现行)", "薄(缩小帽档)", "中", "厚(纸雕织梦岛档)"]
const DEPTH_PX := [0.0, 4.0, 8.0, 14.0] # 悬崖厚度(像素)
const DEPTH_BEVEL := [0.0, 0.35, 0.6, 1.0] # 顶面倒角强度
var depth_mode := 0 # 当前立体档(0..3——平面/薄/中/厚)
var _wrap: CenterContainer
var _svp_container: SubViewportContainer
var _viewport: SubViewport
@@ -141,17 +148,40 @@ func set_cell_area(avail: Vector2) -> void:
return
var n: int = maxi(_board.width, _board.height)
var sep := SEP # 格间距(_init 同值)
var reserve := 24.0 # 垂直总预留(上 12 + 下 12:棋盘底部不贴 D 区边框)
var cell := int(floor((minf(avail.x - 12.0, avail.y - reserve) - float((n - 1) * sep)) / float(n)))
var d := float(DEPTH_PX[depth_mode])
var reserve := 24.0 + d # 垂直总预留(上 12 + 下 12 + 悬崖外延——立体原型批:悬崖占预算防溢出)
var cell := int(floor((minf(avail.x - 12.0 - d, avail.y - reserve) - float((n - 1) * sep)) / float(n)))
_cell = float(clampi(cell, 26, 46))
var stride := _cell + float(SEP)
for c in _cells:
var u: Node2D = _cells[c]
u.edge = _cell
u.position = Vector2(c) * stride
_refresh_slab()
_update_world_size()
# 立体档切换(F9 组合根入口;返回档名供 toast)
func set_depth_mode(m: int) -> String:
depth_mode = clampi(m, 0, DEPTH_NAMES.size() - 1)
for c in _cells:
_cells[c].bevel = float(DEPTH_BEVEL[depth_mode])
_refresh_slab()
set_cell_area(size)
return DEPTH_NAMES[depth_mode]
# 悬崖参数下发(网格像素尺寸/步距/列数/材质锚色——BoardWorld._draw 消费)
func _refresh_slab() -> void:
if _board == null or _board.width == 0:
return
_world.depth_px = float(DEPTH_PX[depth_mode])
_world.slab = Vector2(_board.width, _board.height) * (_cell + float(SEP)) - Vector2(SEP, SEP)
_world.stride_px = _cell + float(SEP)
_world.cols = _board.width
_world.mat = COL_BRICK
# 战斗启动/换板:按板尺寸重建格单元(minesweeper 引用随之更新)
func rebuild(board: BoardData, minesweeper) -> void:
_board = board
@@ -173,6 +203,7 @@ func rebuild(board: BoardData, minesweeper) -> void:
u.cell = c
u.edge = _cell
u.position = Vector2(c) * stride
u.bevel = float(DEPTH_BEVEL[depth_mode]) # 立体原型批——新建格单元继承当前档倒角
u.use_parent_material = true # 去饱和材质挂 BoardWorld——单元随世界材质灰化
u.font = _world.board_font
_world.add_child(u)
@@ -225,11 +256,12 @@ func cell_center_local(c: Vector2i) -> Vector2:
return _svp_container.position + Vector2(c) * (_cell + float(SEP)) + Vector2.ONE * (_cell * 0.5)
# 视口逻辑分辨率 = 板像素尺寸(stretch=true 且容器 min 尺寸同步——缩放比恒 1:1)
# 视口逻辑分辨率 = 板像素尺寸 + 悬崖外延(stretch=true 且容器 min 尺寸同步——缩放比恒 1:1)
func _update_world_size() -> void:
if _board == null or _board.width == 0:
return
var px := Vector2(_board.width, _board.height) * (_cell + float(SEP)) - Vector2(SEP, SEP)
var d := float(DEPTH_PX[depth_mode])
var px := Vector2(_board.width, _board.height) * (_cell + float(SEP)) - Vector2(SEP, SEP) + Vector2(d, d)
_svp_container.custom_minimum_size = px
# 树内 stretch=true 时 SubViewport 尺寸由容器接管(手设被引擎拒绝并刷警告);树外(冒烟直建)才需手设保 1:1
if not _svp_container.is_inside_tree():
+57
View File
@@ -4,6 +4,63 @@
# use_parent_material 链下随世界灰化)+ 主题/字体显式注入槽位(SubViewport 不自动继承主场景
# Control 主题——ADR-0006 Negative 项;Phase B 两舞台共用骨架,ADR-0006 Decision 5)。
# 无 class_name(类名缓存面纪律——BoardView 经 preload 使用)。
# 立体原型批 2026-09-24(用户拍板「三档厚度实机对比」):板块伪立体绘制——正俯视纸雕风,
# 顶面方格不变(数字可读性硬指标不受伤),厚度全部画在网格矩形外的正面/右侧悬崖带:
# 正面(背光暗)+右侧(微受光)+列分隔缝(ITB 悬崖列感)+岩层横纹+底部悬浮影(厚档)+
# 顶面接触 AO。零布局/命中改动(悬崖向网格外延展,世界尺寸由 BoardView._update_world_size 加 D)。
extends Node2D
var board_font: Font = null # 字体注入槽位(null = ThemeDB.fallback_font——与旧 Button 缺省主题字体同源)
# ── 立体原型(BoardView.set_depth_mode / set_cell_area 单点驱动)──
var depth_px := 0.0: # 悬崖厚度(0 = 平面现行;档位 4/8/14)
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 := Color8(201, 175, 131) # 材质锚色(掩尘 #C9AF83——侧面由此派生明暗;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)