## VERTICAL SLICE - NOT FOR PRODUCTION ## 悬停预承诺呈现域件(BoardView 拆件——单一变化原因=悬停反馈语义): ## 三语义光标、目标格边框、BFS 路径预览、chord 双击首遇锚的唯一承载(自 board_view 收编 11 函数族)。 ## 无 class_name(类名缓存面纪律)——经宿主 board_view preload 引用;构造=引用束注入 ## (cells/minesweeper/diggable 共享引用+格命中换算/壳级光标写入/hover_forbidden 与 chord 发射注入 Callable—— ## 输入经宿主三入站口委托,禁反向持宿主引用);_r0 出生展开区成员留宿主。 extends RefCounted const COL_HL_TARGET := UiKit.GOLD # 悬停目标格边框(金) const COL_SEAL := UiKit.SEAL_BLACK # 封印黑(与宿主 :658 双侧服役——各自 alias UiKit 单源) const CURSOR_DIG := Input.CURSOR_CROSS # 挖——镐形自绘纹理载体 const CURSOR_MOVE_SEM := Input.CURSOR_ARROW # 移动——箭头(命名避开 Control.CURSOR_MOVE 原生成员遮蔽) const CHORD_WINDOW_MS := 350 var _cells := {} # 共享引用(宿主容器同对象——rebuild 只 clear 不重绑) var _minesweeper = null # 排雷玩法 只读查询引用(宿主 rebuild 重绑时同拍回写本成员) var _diggable := {} # 共享引用(可挖域——呼吸微光作用集同源) var _cb_cell_at: Callable # 格命中换算(宿主 _cell_at——整图公式单点留宿主) var _cb_cursor: Callable # 壳级光标写入(宿主 mouse_default_cursor_shape 单点) var _cb_forbidden: Callable # hover_forbidden 信号发射(首遇 toast 去重归组合根) var _cb_chord: Callable # chord_attempted 信号发射(chord 肌肉记忆提示锚) var _hover := Vector2i(-9, -9) var _last_click := {"cell": Vector2i(-9, -9), "ms": -100000} func _init(bundle: Dictionary) -> void: _cells = bundle["cells"] _minesweeper = bundle["minesweeper"] _diggable = bundle["diggable"] _cb_cell_at = bundle["cell_at"] _cb_cursor = bundle["cursor"] _cb_forbidden = bundle["forbidden"] _cb_chord = bundle["chord"] # ---- 公开操作面(pres封装 A2——宿主经此驱动,字段保持私有)---- # 每战重绑(排雷玩法对象随战更替——宿主 rebuild 同拍调用) func rebind(minesweeper: Variant) -> void: _minesweeper = minesweeper # 硬复位悬停锚(无 unhover 视觉清理——宿主 rebuild 前提下视觉随重建清零) func reset() -> void: _hover = Vector2i(-9, -9) # 悬停现值读口(宿主呈现查询) func hover_pos() -> Vector2i: return _hover func hover_at(pos: Vector2) -> void: var c: Vector2i = _cb_cell_at.call(pos) if c.x < 0: if _hover.x >= 0: _on_cell_unhover(_hover) elif c != _hover: if _hover.x >= 0: _on_cell_unhover(_hover) _on_cell_hover(c) func on_shell_mouse_exited() -> void: if _hover.x >= 0: _on_cell_unhover(_hover) # chord 肌肉记忆首遇锚:同格双左击快开尝试(350ms 窗)——每 run 一次提示由组合根去重 func detect_chord(c: Vector2i) -> void: var now := Time.get_ticks_msec() if _last_click.cell == c and now - int(_last_click.ms) <= CHORD_WINDOW_MS: _cb_chord.call(c) _last_click.ms = -100000 return _last_click = {"cell": c, "ms": now} func _on_cell_hover(c: Vector2i) -> void: _hover = c _apply_hover_visuals(c) func _on_cell_unhover(c: Vector2i) -> void: if _hover == c: _hover = Vector2i(-9, -9) _clear_hover_visuals(c) func refresh_after_paint() -> void: # 状态随 refresh 变化后光标/边框语义需重算(悬停格四格态可能已变) if _hover.x >= 0 and _cells.has(_hover): _apply_hover_visuals(_hover) func _apply_hover_visuals(c: Vector2i) -> void: if _minesweeper == null or not _cells.has(c): return _clear_hover_visuals(c) var u: Node2D = _cells[c] var revealed: bool = _minesweeper.is_revealed(c) var seal: bool = _minesweeper.has_seal(c) var adjacent: bool = _diggable.has(c) if revealed: u.face.hl_visible = true u.face.hl_color = COL_HL_TARGET # 移动目标格边框(金) _set_cursor_shape(c, CURSOR_MOVE_SEM) _show_path_preview(c) elif adjacent: u.face.hl_visible = true u.face.hl_color = COL_HL_TARGET # 挖掘目标格边框(相邻封印格同此——左键直接挖) _set_cursor_shape(c, CURSOR_DIG) elif seal: u.face.hl_visible = true u.face.hl_color = COL_SEAL # 已承诺封印标记(封印黑;无交互可供) _set_cursor_shape(c, Input.CURSOR_FORBIDDEN) else: u.face.hl_visible = true u.face.hl_color = UiKit.RED_FORBID # 不可及域灰禁框(禁止光标+首遇 toast 双通道) _set_cursor_shape(c, Input.CURSOR_FORBIDDEN) _cb_forbidden.call(c) func _clear_hover_visuals(c: Vector2i) -> void: if not _cells.has(c): return _cells[c].face.hl_visible = false _hide_path_preview() func _set_cursor_shape(c: Vector2i, shape: int) -> void: _cb_cursor.call(shape) # 壳级光标(悬停格语义决定——单格悬停恒一) func _show_path_preview(c: Vector2i) -> void: # 合法性指示:悬停已开格 → BFS 路径蓝细线点迹(compute_move_path 只读面) if _minesweeper == null: return var path: Array[Variant] = _minesweeper.compute_move_path(c) for pc in path: if _cells.has(pc): _cells[pc].face.dot_visible = true func _hide_path_preview() -> void: for c in _cells: _cells[c].face.dot_visible = false