feat(presentation): B 区战斗舞台壳改造(Phase B T2)——BattleStageView PanelContainer→Control+Node2D 舞台半区(SubViewportContainer/SubViewport/StageWorld 新件)+Control 文本半区三件保留+set_world_font/world_to_shell 挂点+C6 判据实证过+外框几何零漂移+台账 170
This commit is contained in:
1 parent
dc33c09260
commit
87b23a810b
4 files changed
+87
-3
No files matched your search
@@ -4,10 +4,19 @@
|
||||
# 底部结算明细带(布局决策 D1 常驻双舞台分屏))。
|
||||
# Date: 2026-09-12(2026-09-20 站桩改造批:HeroCardView/EnemyCardView 退役,StandeeView 换装;
|
||||
# setter 面契约保持——set_enemies/clear_enemies/on_step_row_fx/gray_all_enemies 签名不变)
|
||||
# 战斗舞台 Node2D 迁移批 Phase B 2026-09-26(循环 1 T2,ADR-0006 / board-node2d-migration-plan §3):
|
||||
# 根壳 PanelContainer → Control(类名/尺寸 252px/树内位置不变),内部拆两半区——
|
||||
# 「Node2D 舞台半区 = SubViewportContainer + SubViewport + StageWorld(站桩本体 T3 迁入,本期空置)」
|
||||
# +「Control 文本半区 = round_label / stage_center / log_view 三件原样保留(C1 永久 Control)」。
|
||||
# SubViewport 逻辑分辨率 = 壳层像素 1:1(stretch,禁任何缩放系数——C2/C5);字体显式注入挂点
|
||||
# set_world_font(C6——SubViewport 不自动继承主场景主题,Phase A BoardView 同款)。
|
||||
# 高内聚边界:容器+组合视图——站桩槽位管理、轮次指示、结算行演出分发改由 setter 面承接;
|
||||
# 结算流水格式化归 BattleLogView,核心状态→文案装配归 hud_presenter.gd。
|
||||
class_name BattleStageView
|
||||
extends PanelContainer
|
||||
extends Control
|
||||
|
||||
const _STAGE_WORLD := preload("res://presentation/views/stage_world.gd")
|
||||
const _CONTENT_MARGINS := Rect2(6, 4, 6, 4) # 原 PanelContainer stylebox 内容边距(子面几何零漂移)
|
||||
|
||||
var hero_standee: StandeeView
|
||||
var round_label: Label
|
||||
@@ -15,14 +24,46 @@ var stage_center: Label
|
||||
var enemy_box: HBoxContainer
|
||||
var log_view: BattleLogView
|
||||
var _cards: Array = []
|
||||
var _svp_container: SubViewportContainer
|
||||
var _viewport: SubViewport
|
||||
var world: Node2D # StageWorld(preload 脚本实例——Node2D 世界根/字体挂点;T3 站桩迁入)
|
||||
|
||||
|
||||
func _init(db_ref) -> void:
|
||||
custom_minimum_size = Vector2(0, 252)
|
||||
# 面板底(PanelContainer 面板样式等价平移——Control 壳不自绘 stylebox,Panel 子面承载)
|
||||
var bg := Panel.new()
|
||||
var sb := UiKit.panel_flat(UiKit.PANEL_STAGE, UiKit.PANEL_BORDER, 0, 1, Vector4(6, 4, 6, 4))
|
||||
add_theme_stylebox_override("panel", sb)
|
||||
bg.add_theme_stylebox_override("panel", sb)
|
||||
bg.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
bg.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
add_child(bg)
|
||||
|
||||
# ── Node2D 舞台半区(ADR-0006 Phase B 同构;stretch 1:1 无缩放系数——C2/C5)──
|
||||
_svp_container = SubViewportContainer.new()
|
||||
_svp_container.stretch = true # 容器尺寸 = 视口逻辑分辨率,恒 1:1
|
||||
_svp_container.mouse_filter = Control.MOUSE_FILTER_IGNORE # B 区零输入(tooltip 归壳层伴随件)
|
||||
_svp_container.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
_svp_container.offset_left = _CONTENT_MARGINS.position.x
|
||||
_svp_container.offset_top = _CONTENT_MARGINS.position.y
|
||||
_svp_container.offset_right = -_CONTENT_MARGINS.size.x
|
||||
_svp_container.offset_bottom = -_CONTENT_MARGINS.size.y
|
||||
add_child(_svp_container)
|
||||
_viewport = SubViewport.new()
|
||||
_viewport.transparent_bg = true # 露出面板底色(与旧空隙同观感)
|
||||
_svp_container.add_child(_viewport)
|
||||
world = _STAGE_WORLD.new()
|
||||
_viewport.add_child(world)
|
||||
|
||||
# ── Control 文本半区(round_label / stage_center / log_view 原样保留——C1 永久 Control;
|
||||
# hero_standee/enemy_box 仍为 Control 站桩,T3 迁世界后仅伴随件留壳层)──
|
||||
var vb := VBoxContainer.new()
|
||||
vb.add_theme_constant_override("separation", 4)
|
||||
vb.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
vb.offset_left = _CONTENT_MARGINS.position.x
|
||||
vb.offset_top = _CONTENT_MARGINS.position.y
|
||||
vb.offset_right = -_CONTENT_MARGINS.size.x
|
||||
vb.offset_bottom = -_CONTENT_MARGINS.size.y
|
||||
add_child(vb)
|
||||
|
||||
round_label = UiKit.label("第 — 轮 · —", 15, true)
|
||||
@@ -58,6 +99,26 @@ func _init(db_ref) -> void:
|
||||
vb.add_child(log_view)
|
||||
|
||||
|
||||
# SubViewport 主题/字体显式注入挂点(C6——Phase A BoardView.set_world_font 同款;
|
||||
# T3 起随站桩本体下发 world_font)
|
||||
func set_world_font(f: Font) -> void:
|
||||
world.world_font = f
|
||||
|
||||
|
||||
# 两套坐标空间换算单点(C4——台账 160 纪律延伸):SubViewport 世界内 = 局部排布;
|
||||
# 壳层/fx 层(结算演出 SettlementFxView 在 SubViewport 之外)= 全局含容器偏移。
|
||||
# 站桩重建/容器重排挂点调用(站桩无逐帧位移,零每帧成本)。
|
||||
func world_to_shell(p: Vector2) -> Vector2:
|
||||
return _svp_container.global_position + p
|
||||
|
||||
|
||||
func _notification(what: int) -> void:
|
||||
if what == NOTIFICATION_RESIZED:
|
||||
# stretch=true 时视口尺寸由容器接管;树外(冒烟直建)才需手设保 1:1(Phase A 同款)
|
||||
if not _svp_container.is_inside_tree():
|
||||
_viewport.size = _svp_container.size
|
||||
|
||||
|
||||
# 敌方站桩投影更新:数量不变 = 就地更新(死亡灰化/受击闪烁等站桩上动画不被逐行刷新重置——禁瞬消纪律);
|
||||
# 数量变化 = 新战斗域,重建站桩槽(轮内不增删,无回流)
|
||||
func set_enemies(cards_data: Array) -> void:
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
# 战斗舞台 Node2D 迁移批 Phase B 2026-09-26(循环 1 T2/T3):StageWorld——B 区战斗舞台 Node2D
|
||||
# 世界根(SubViewport 内站桩本体容器)。ADR-0006 分工:Node2D = D 区棋盘 + B 区战斗舞台;
|
||||
# 与 BoardWorld(Phase A)同构。职责单点:主题/字体显式注入槽位(SubViewport 不自动继承主场景
|
||||
# Control 主题——ADR-0003 Decision 4;set_world_font 同款挂点,null = ThemeDB.fallback_font 与
|
||||
# 旧 Label 缺省主题同源)+ 站桩本体装载面(T3 迁入)。无 class_name(类名缓存面纪律——
|
||||
# BattleStageView 经 preload 使用)。
|
||||
# 坐标空间钉死(台账 160 纪律延伸):世界内 = 局部排布坐标(SubViewport 逻辑分辨率 =
|
||||
# 壳层像素 1:1,无缩放系数——C2/C5);壳层/fx 层 = 全局含容器偏移,换算单点在
|
||||
# BattleStageView.world_to_shell()。
|
||||
extends Node2D
|
||||
|
||||
var world_font: Font = null # 字体注入槽位(null = ThemeDB.fallback_font——BattleStageView.set_world_font 注入)
|
||||
|
||||
# C6 headless 可验判据(ADR-0003 Decision 4):注入字体非空 + 中文字形 has_char + 采样文本宽度 > 0。
|
||||
# 实际光栅观感归批末目检清单。
|
||||
func font_probe() -> Dictionary:
|
||||
var f: Font = world_font if world_font != null else ThemeDB.fallback_font
|
||||
var has_char: bool = f.has_char("人".unicode_at(0))
|
||||
var width: float = f.get_string_size("兑现演出区", HORIZONTAL_ALIGNMENT_LEFT, -1, 14).x
|
||||
return {"font": f, "has_char": has_char, "width": width}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dqo6k0y6ncmov
|
||||
Reference in new issue
Block a user