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

177 lines
6.6 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(C 区角色信息 240×548〔底行 520→548——停点前移批 2026-09-23,
# 原 A 区顶栏空间并入〕——HP/攻击(+修正)/RAP 直角细线数据框
# 〔修正来源角标〕、状态效果槽 ×4、小人立绘占位;RAP 清零可见反馈〔行动经济 义务〕;
# 状态槽空态 = 槽隐藏上移补位〔EC12〕)。
# Date: 2026-09-12
# 高内聚边界:纯视图 setter 面——装配(含修正文案)归 hud_presenter.gd;定长槽 + clip_contents
# (缺陷①回归约束)。
class_name HeroInfoPanelView
extends PanelContainer
const COL_INK := UiKit.INK
const COL_GOLD := UiKit.GOLD
const COL_DOT_OFF := UiKit.DOT_OFF
var _hp_bar: ProgressBar
var _hp_label: Label
var _atk_label: Label
var _rap_dots: HBoxContainer
var _rap_label: Label
var _rap_feedback: Label
var _status_feedback: Label
var slot_row: StatusSlotRow
var gp_label: Label # 冒险钱包余额常驻位(停点前移批 2026-09-23——原 A 区顶栏迁入 C 区底行)
var keystone_label: Label # 钥石余额常驻位(同上——文案装配归 HudPresenter)
var _last_rap := 0 # 上次投影值(清零反馈判据——禁解析自身 label 文本当状态)
func _init() -> void:
custom_minimum_size = Vector2(240, 0)
clip_contents = true
var sb := UiKit.panel_flat(UiKit.PANEL_HERO, UiKit.PANEL_BORDER, 0, 1, Vector4(8, 6, 8, 6))
add_theme_stylebox_override("panel", sb)
var col := VBoxContainer.new()
col.add_theme_constant_override("separation", 6)
add_child(col)
col.add_child(UiKit.label("探险者", 16, true))
_hp_bar = ProgressBar.new()
_hp_bar.custom_minimum_size = Vector2(0, 12)
_hp_bar.show_percentage = false
col.add_child(_hp_bar)
_hp_label = _data_line()
col.add_child(_hp_label)
_atk_label = _data_line()
col.add_child(_atk_label)
# RAP 框(pattern 5 点阵资源显示——点阵图形 + 数字精确值双承载)
var rap_head := HBoxContainer.new()
rap_head.add_theme_constant_override("separation", 6)
col.add_child(rap_head)
_rap_dots = HBoxContainer.new()
_rap_dots.add_theme_constant_override("separation", 2)
rap_head.add_child(_rap_dots)
_rap_label = UiKit.label("RAP 0", 13, true)
rap_head.add_child(_rap_label)
_rap_feedback = UiKit.label("", 12, false)
_rap_feedback.add_theme_color_override("font_color", UiKit.STONE_FAINT)
col.add_child(_rap_feedback)
col.add_child(UiKit.label("状态效果", 14, true))
slot_row = StatusSlotRow.new()
col.add_child(slot_row)
_status_feedback = UiKit.label("", 12, false)
_status_feedback.add_theme_color_override("font_color", UiKit.STONE_FAINT)
col.add_child(_status_feedback)
# 小人立绘占位(程序化色块——真实立绘归 战斗表现)
var portrait := ColorRect.new()
portrait.color = Color(UiKit.HERO_BLUE, 56.0 / 255.0) # 原 Color8(46, 110, 142, 56)
portrait.custom_minimum_size = Vector2(0, 120)
portrait.size_flags_vertical = Control.SIZE_EXPAND_FILL
col.add_child(portrait)
var portrait_glyph := UiKit.label("小人立绘占位", 13, false)
portrait_glyph.add_theme_color_override("font_color", COL_INK)
portrait_glyph.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
portrait_glyph.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
portrait_glyph.mouse_filter = Control.MOUSE_FILTER_IGNORE
portrait_glyph.set_anchors_preset(Control.PRESET_FULL_RECT)
portrait.add_child(portrait_glyph)
# 钱包行(停点前移批 2026-09-23:A 区 28px 顶栏退役——GP/钥石余额常驻位迁本面板底行,
# 建节点归视图、文案装配归 HudPresenter,句柄经 ui_assembler 透传组合根)
var wallet_row := HBoxContainer.new()
wallet_row.add_theme_constant_override("separation", 10)
col.add_child(wallet_row)
gp_label = UiKit.label("金币 0", 15, true)
gp_label.add_theme_color_override("font_color", UiKit.GOLD_DEEP)
wallet_row.add_child(gp_label)
keystone_label = UiKit.label("钥石 0", 15, true)
keystone_label.add_theme_color_override("font_color", UiKit.GOLD)
keystone_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
keystone_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
wallet_row.add_child(keystone_label)
func set_hero(hp: int, max_hp: int) -> void:
_hp_bar.max_value = maxi(1, max_hp)
_hp_bar.value = hp
_hp_label.text = "HP %d / %d" % [hp, max_hp]
func set_attack(atk: int, mod_text: String) -> void:
# 修正来源角标:mod_text 形如「(+50% 增伤)」——来源 = 效果 display_name(增益状态 投影)
_atk_label.text = "攻击 %d %s" % [atk, mod_text]
func set_rap(rap: int, cap_hint: int) -> void:
var prev := _last_rap
_last_rap = rap
_rap_label.text = "RAP %d(攒 %d 刷图)" % [rap, cap_hint]
_render_rap_dots(rap)
if prev > 0 and rap == 0:
# battle_over RAP 清零可见反馈(行动经济 D1 义务):数字滚动归零 + 微文案占位
_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 = ""
func set_status_effects(effects: Array) -> void:
slot_row.set_effects(effects)
_status_feedback.text = ""
# battle_over:状态槽全清可见反馈(逐槽化光 + 微文案——增益状态×4④)
func set_status_cleared_feedback() -> void:
slot_row.set_cleared_feedback()
_status_feedback.text = "状态随战斗结束消散"
func set_idle() -> void:
_hp_bar.value = 0
_hp_label.text = "HP —"
_atk_label.text = "攻击 —"
_last_rap = 0
_render_rap_dots(0)
_rap_label.text = "RAP —"
slot_row.set_effects([])
func hp_text() -> String:
return _hp_label.text
func rap_text() -> String:
return _rap_label.text
# 资源面拒绝反馈(pattern 1 resource_face 腿):RAP 数字脉冲
func pulse_rap() -> void:
var tw := create_tween()
tw.tween_property(_rap_label, "modulate", Color(1.0, 0.4, 0.3), UiKit.motion(0.1))
tw.tween_property(_rap_label, "modulate", Color(1, 1, 1), UiKit.motion(0.25))
func _render_rap_dots(rap: int) -> void:
var shown := mini(rap, 16)
while _rap_dots.get_child_count() < shown:
var d := ColorRect.new()
d.custom_minimum_size = Vector2(8, 8)
d.size_flags_vertical = Control.SIZE_SHRINK_CENTER
d.mouse_filter = Control.MOUSE_FILTER_IGNORE
_rap_dots.add_child(d)
for i in _rap_dots.get_child_count():
var d: ColorRect = _rap_dots.get_child(i)
d.color = COL_GOLD if i < shown else COL_DOT_OFF
func _data_line() -> Label:
var l := UiKit.label("", 14, false)
l.clip_text = true
l.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
return l