Files
gplan-2/game/presentation/views/ap_bar_view.gd
T
DKChan 9a72394652 chore(代码卫生): 头注存量清偿批——82 文件按两类白名单改写为 ## 文档注释载体
按 code-conventions §1.4.1 第三轮定稿执行:core 22+schemas 18+presentation 根 14+views 28,全部头注 #→##、删日期/变更叙事/GDD 与架构反向链接/字段与域清单/机制描述,保留职责摘要+真实使用约束(防事故禁令/单一入口/信号契约每信号一行)。main.gd 31→5 行、save_manager 45→5 行、adventure_runner 37→5 行为最大单件。子代理分模块执行(波一 core+schemas、波二 presentation+views,并发≤2)。验收=tools/verify_comment_only_change.py 逐字节校验(82 文件头注区外逐行一致=零行为变更)+audit_file_headers 全绿;纯注释批免冒烟(先例 5843270)
2026-10-16 23:28:07 +08:00

259 lines
9.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
## D 区 AP 条:AP/RAP 点阵读数与停手、图例、弃图刷新入口(弃图刷新为二段确认——RAP 扣费·旧板旗作废显式代价)。
## RAP 读数贴弃图刷新消费口(RAP 唯一消费口=弃图刷新);无推送信号——组合根每次核心调用返回后经 setter 重查注入。
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()