Files
gplan-2/game/presentation/views/ap_bar_view.gd
T
DKChan 6c2dbc37c1 docs: ADR 体系废除 + architecture.md 确立为架构唯一事实源(2026-10-15 用户令:决策记录归 git commit log,不另存决策文档)
- 删除 design/dev/architecture/adr-0001~0007 共 7 份文件(内容留 git 历史可查)
- architecture.md:删「ADR 审计」「ADR 立项清单」两节;清除全文 ADR-000X 注记、QQ 表/S 表 ADR 引用;未决表关闭已落定项(QQ-01/02/03),立项清单在途事项转登记 QQ-11~14;补 A1 生成姿态事实、autoload 四件清单、board_generator 性能姿态;文档状态立「事实源地位」条
- CLAUDE.md:恢复 RNG 单点硬性红线(去 ADR-0007 引用);新增「架构事实唯一源」红线;规范导航架构行标注唯一事实源
- doc-conventions:§5 增「架构事实唯一源」行;§11 活文档清单补架构文档
- registry:architecture.yaml 删 18 处 adr 字段、autoload_set 补 SaveManager/MetaProgression、board_rending 更新为 Node2D 已落地事实;entities.yaml 12 处引用清除
- game/ 代码注释约 60 处清 ADR-000X 引用(事实与日期保留);豁免标记 ADR-0007-exempt → rng-seed-exempt(main.gd/static_scan.sh/architecture.md/06/iter27 五处同步)
- GDD/qa 实现报告/research 卡片/roadmap/tests README 引用全清;死链校验 1206 链接 0 死链、gdd_lint 0 不通过
- 代码中 adr/adr5 等为 adventure_runner 既有局部变量名(非 ADR 引用),未动
2026-10-15 23:52:30 +08:00

265 lines
9.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
# 实现 GDD:design/ux/battle.md(D 区 AP 条 44px——点阵+数字〔pattern 5 点阵资源显示〕、
# 停手按钮居左、图例+弃图刷新按钮居右〔雷图右上角〕;弃图刷新确认微交互与常规确认不同位
# 〔pattern 7 破坏性确认异位:RAP 扣费 · 旧板旗作废显式代价〕)。
# RAP 读数(点阵+数字)在本条、置弃图刷新按钮左邻
# (RAP 唯一消费口 = 弃图刷新——就近原则;RAP 清零反馈/资源拒绝脉冲载体同处)。
# Date: 2026-09-12
# 高内聚边界:纯视图——意图经信号外发(stop_pressed/refresh_confirmed/legend_toggled),
# 状态由组合根经 setter 注入;刷新可用性预判 = RAP≥8 读数(行动经济 无推送信号——每次调用返回后重查)。
class_name ApBarView
extends PanelContainer
signal stop_pressed
signal refresh_confirmed
signal legend_toggled
const COL_GOLD := UiKit.GOLD
const COL_DOT_OFF := UiKit.DOT_OFF
const COL_INK := UiKit.INK
var _dots: HBoxContainer
var _ap_label: Label
var _btn_stop: Button
var _btn_legend: Button
var _btn_refresh: Button
var _refresh_sub: Label
var _confirm_row: HBoxContainer
var _confirm_lab: Label
var _rap_dots: HBoxContainer
var _rap_label: Label
var _rap_feedback: Label
var _last_rap := 0 # 上次投影值(清零反馈判据——禁解析自身 label 文本当状态)
var refresh_cost: int = 0 # 表值驱动(装配经 set_refresh_cost 注入 ActionEconomyTable.rap_refresh_cost)
var _arm_timer := ArmedTimer.new() # 弃图刷新确认窗(T3/D3 P4 乙——tween 秒表机制收口;窗口=REFRESH_CONFIRM_WINDOW_S)
const REFRESH_CONFIRM_WINDOW_S := 4.0 # 弃图刷新确认窗(原 tween_interval 字面量升常量——语义零变化)
func _init() -> void:
custom_minimum_size = Vector2(0, 44)
_arm_timer.expired.connect(_disarm)
var sb := UiKit.panel_flat(UiKit.PANEL_DATA, UiKit.PANEL_BORDER, 0, 1, Vector4(8, 4, 8, 4))
add_theme_stylebox_override("panel", sb)
var row := HBoxContainer.new()
row.add_theme_constant_override("separation", 8)
add_child(row)
_dots = HBoxContainer.new()
_dots.add_theme_constant_override("separation", 3)
_dots.size_flags_vertical = Control.SIZE_SHRINK_CENTER
row.add_child(_dots)
_ap_label = UiKit.label("AP 0/0",UiKit.FS_BODY, true)
_ap_label.size_flags_vertical = Control.SIZE_SHRINK_CENTER
row.add_child(_ap_label)
_btn_stop = UiKit.button("停手")
_btn_stop.custom_minimum_size = Vector2(64, 0)
_btn_stop.size_flags_vertical = Control.SIZE_SHRINK_CENTER
_btn_stop.pressed.connect(_emit_stop_pressed)
row.add_child(_btn_stop)
var spacer := Control.new()
spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
row.add_child(spacer)
# RAP 读数(2026-09-26 信息归属拍板自 C 区迁入):RAP 唯一消费口 = 弃图刷新——资源数字贴消费按钮
# (就近原则);扣费文案「RAP−%d」已在刷新按钮副行,此处不重复代价提示(单一展示面原则)
_rap_dots = HBoxContainer.new()
_rap_dots.add_theme_constant_override("separation", 2)
_rap_dots.size_flags_vertical = Control.SIZE_SHRINK_CENTER
row.add_child(_rap_dots)
_rap_label = UiKit.label("RAP 0",UiKit.FS_HINT, true, UiKit.INK_LABEL) # 显式传色(UI 设计对齐批 N1-7——T0 实测对 PANEL_DATA 10.4:1 已合规,显式化仅为确定性加固,值不变)
_rap_label.size_flags_vertical = Control.SIZE_SHRINK_CENTER
row.add_child(_rap_label)
_rap_feedback = UiKit.label("",UiKit.FS_CAPTION, false, UiKit.STONE_DEEP) # 迭代 26 T3 换墨——旧灰石弱化墨对 PANEL_DATA 2.9:1 越带,深石墨 5.6:1 在案
_rap_feedback.size_flags_vertical = Control.SIZE_SHRINK_CENTER
row.add_child(_rap_feedback)
# 破坏性确认异位(pattern 7):确认 chips 出现在刷新按钮左方——与常规"按钮自身确认"不同位
_confirm_row = HBoxContainer.new()
_confirm_row.add_theme_constant_override("separation", 4)
_confirm_row.visible = false
row.add_child(_confirm_row)
_confirm_lab = UiKit.label("RAP−%d · 旧板旗作废" % refresh_cost,UiKit.FS_HINT, true, COL_INK)
_confirm_row.add_child(_confirm_lab)
var confirm_btn := UiKit.button("确认弃图", 0.0) # HUD 顶条紧凑钮豁免宽度基准
confirm_btn.pressed.connect(_disarm_and_fire)
_confirm_row.add_child(confirm_btn)
_btn_legend = UiKit.button("图例")
_btn_legend.custom_minimum_size = Vector2(56, 0)
_btn_legend.size_flags_vertical = Control.SIZE_SHRINK_CENTER
_btn_legend.pressed.connect(_emit_legend_toggled)
row.add_child(_btn_legend)
var refresh_box := VBoxContainer.new()
refresh_box.add_theme_constant_override("separation", 0)
refresh_box.size_flags_vertical = Control.SIZE_SHRINK_CENTER
row.add_child(refresh_box)
_btn_refresh = UiKit.button("弃图刷新", 0.0) # HUD 顶条紧凑钮豁免宽度基准
_btn_refresh.pressed.connect(_on_refresh_pressed)
refresh_box.add_child(_btn_refresh)
_refresh_sub = UiKit.label("RAP−%d · 剩 0 次" % refresh_cost,UiKit.FS_HINT, false, UiKit.INK_LABEL)
_refresh_sub.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
refresh_box.add_child(_refresh_sub)
# ---- setter 面(组合根每次核心调用返回后重查注入——行动经济 无推送信号) ----
func set_ap(ap: int, ap_max: int) -> void:
while _dots.get_child_count() < ap_max:
_dots.add_child(_make_dot())
while _dots.get_child_count() > ap_max:
var last: Control = _dots.get_child(_dots.get_child_count() - 1)
_dots.remove_child(last)
last.queue_free()
for i in _dots.get_child_count():
var d: Dot = _dots.get_child(i)
d.lit = i < ap
d.queue_redraw()
_ap_label.text = "AP %d/%d" % [ap, ap_max]
func set_refresh_cost(cost: int) -> void:
refresh_cost = cost
_confirm_lab.text = "RAP−%d · 旧板旗作废" % cost
func set_refresh_state(remaining: int, ready: bool) -> void:
_refresh_sub.text = "RAP−%d · 剩 %d 次" % [refresh_cost, remaining]
_btn_refresh.disabled = not ready
if not ready:
_disarm()
func set_stop_enabled(on: bool) -> void:
_btn_stop.disabled = not on
# RAP 活值投影(点阵+数字——pattern 5 双承载);清零反馈分支(行动经济 D1 义务)依赖持续投喂可达
func set_rap(rap: int) -> void:
var prev := _last_rap
_last_rap = rap
_rap_label.text = "RAP %d" % rap
_render_rap_dots(rap)
if prev > 0 and rap == 0:
# battle_over RAP 清零可见反馈(行动经济 D1 义务):数字脉冲 + 微文案(载体自 C 区迁入)
_rap_feedback.text = "随战斗结束消散"
var tw := create_tween()
tw.tween_property(_rap_label, "modulate", Color(1.4, 1.2, 0.7), UiKit.motion(0.12))
tw.tween_property(_rap_label, "modulate", Color(1, 1, 1), UiKit.motion(0.3))
elif rap > 0:
_rap_feedback.text = ""
# 资源读数拒绝脉冲单点(pattern 1 resource_face 腿——RAP/AP 两份逐字重复合并:朱红脉冲一拍回白)
func _pulse(label: Label) -> void:
var tw := create_tween()
tw.tween_property(label, "modulate", Color(1.0, 0.4, 0.3), UiKit.motion(0.1))
tw.tween_property(label, "modulate", Color(1, 1, 1), UiKit.motion(0.25))
func pulse_rap() -> void:
_pulse(_rap_label)
func _render_rap_dots(rap: int) -> void:
var shown := mini(rap, 16)
while _rap_dots.get_child_count() < shown:
_rap_dots.add_child(_make_dot(8.0, true)) # RAP 点阵 8px 窄档(随读数字号)——建点单点共用
for i in _rap_dots.get_child_count():
var d: Dot = _rap_dots.get_child(i)
d.lit = i < shown
d.queue_redraw()
# 探针/装配复用:刷新按钮可用性(预判 = RAP 足额 + 上限未到)
func is_refresh_ready() -> bool:
return not _btn_refresh.disabled
# 探针接缝(合成输入走真实翻译出口口径):刷新按钮点击 → 确认 chips 全链路
func press_refresh_for_probe() -> void:
_on_refresh_pressed()
func confirm_visible() -> bool:
return _confirm_row.visible
func press_confirm_for_probe() -> void:
if _arm_timer.is_armed():
_disarm_and_fire()
func refresh_remaining_text() -> String:
return _refresh_sub.text
# ---- 确认微交互(pattern 7 异位:常规确认 = 按钮自身;本确认 = 左侧独立 chips) ----
func _on_refresh_pressed() -> void:
if _btn_refresh.disabled:
return
_confirm_row.visible = true
_arm_timer.arm(REFRESH_CONFIRM_WINDOW_S)
func _disarm_and_fire() -> void:
_disarm()
refresh_confirmed.emit()
func _disarm() -> void:
_arm_timer.disarm()
_confirm_row.visible = false
# 帧驱动(T3/D3——超时回落走 ArmedTimer;unarmed 零开销直返)
func _process(delta: float) -> void:
_arm_timer.tick(delta)
# 资源面拒绝反馈(pattern 1 resource_face 腿):AP 数字脉冲
func pulse_ap() -> void:
_pulse(_ap_label)
# 点阵建点单点(AP 10px / RAP 8px 两套建点参数化合并;初始色=熄灭档——投影循环当拍覆写)
func _make_dot(px := 10.0, shrink_center := false) -> Dot:
var d := Dot.new(px, shrink_center)
return d
# M8(UI 落码批):点阵样式件——方点+亮心(像素宝石观感 demo ⑦);AP=烛光黄族 / RAP=小人蓝族
class Dot:
extends Control
var px := 10.0
var lit := false
var lit_color := UiKit.CANDLE
var core_color := UiKit.RAP_DOT_CORE_WARM
var off_color := UiKit.DOT_OFF
func _init(p: float, rap := false) -> void:
px = p
custom_minimum_size = Vector2(p, p)
size_flags_vertical = Control.SIZE_SHRINK_CENTER if rap else Control.SIZE_FILL
mouse_filter = Control.MOUSE_FILTER_IGNORE
if rap:
lit_color = UiKit.RAP_DOT_LIT_BLUE
core_color = UiKit.RAP_DOT_CORE_BLUE
func _draw() -> void:
draw_rect(Rect2(Vector2.ZERO, Vector2(px, px)), lit_color if lit else off_color)
if lit:
draw_rect(Rect2(Vector2(px * 0.28, px * 0.28), Vector2(px * 0.3, px * 0.3)), core_color)
func _emit_stop_pressed() -> void:
stop_pressed.emit()
func _emit_legend_toggled() -> void:
legend_toggled.emit()