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
|
||||
@@ -456,4 +456,5 @@
|
||||
164. **高墙瓦片 v9.3 定稿交付+备选案清场批(2026-09-26,本会话——用户验收 v9.3 后指令「直接移入游戏本体+备选案打包挪走」;零代码、素材不入 git,worktree 不适用)**:**定稿交付**=21 枚入 `game/assets/art/board/`(16 唯一墙瓦片〔center/center_crack/center_speckle/n/s/w/nw/sw/hrun/vrun/end_n/end_s/end_w/lone/in_nw/in_sw〕+5 地面瓦片变体,`terrain_*_dungeon.png`;东/NE/SE/端头E/凹角NE/SE=运行时 flip_h 镜像不出文件,旧 beast-cave 砖零触碰)。**终版路线**=材质归模型(用户 Gemini 生图①岩石/④泥土→周期对齐无缝裁剪+BOX 降采样 32×32+环绕混合+量化 12 色)+结构归程序(v9 墨线纪律:全开缘 1px 深墨线直线零抖动/北缘内侧 1px 就地提亮/南缘立面窄暗条 11px/凹角角点+立面侧 1px 齐平收头——v9.1 悬空/v9.2 突出/v9.3 齐平三轮定位,前后对比+逐行像素审计存 `_work/corner_cmp_v91_v93_5x.png`)。**术语共识(用户立)**:未开格=墙瓦片,已开格=地面瓦片。**备选案清场**=v1–v9.2 全迭代+被否素材(含 v7 程序砌石/v3 生图 5×5 表)打包 `备选案-terrain-walls-v1-v9_2-2026-09-26.zip`(383 项 7.5MB,用户挪出库),`_work/` 仅留生图①④源图+风格参考+终版证据+定稿件。**复盘机制落记忆**(pixel-structure-verify-discipline):先抄后造/验收口径写像素级视觉判据/±1px 一律坐标推导/修复默认附前后对比。**遗留**:underdark/deep_underdark 换色(AI 纹理色调映射)+实机查表合成器(BoardWorld 接线,含镜像翻转)归后续批;任务书验收单逐条结果以本批 v9.3 终测为准(图底分离 67.6/无死黑/墨线周界闭合/覆盖层可读)。
|
||||
|
||||
168. **战斗舞台 Node2D 循环 1 · T0 开工批(2026-09-26,本会话——计划书 .zcode/plans/battle-stage-node2d-loop-plan-2026-09-26.md 已批准从 T0 自治开跑;worktree battle-stage-node2d-20260926)**:worktree 自 master 70d2320 建+editor --quit 刷缓存 0 error;git status 归属核对=主区脏文件(.gitignore/.zcode config/ui-reuse 指引/playnote/project.godot/loop-dashboard/active.md 165-167 未提交并行登记+untracked 美术文档组)均非本批只标旗不碰。**基线复读全绿记档**——冒烟 557/0+五探针 PASS(ui_probe cells=144 board=12x12/ui_click 问题=0/ui_tune 全链/ui_layout dump:stage 1280×252·board_view 1036×965·info_panel 240×1028/ui_input 十一断言)+static_scan exit0+文档三闸基线存档(死链 7/退役词命中/gdd_lint 8 文件 8 不通过 69 项级)+MC 12 局 both(max 路由) 24 行 RUNSUM sha256=de8225b3 存 /tmp 供 T7 逐位对拍。**§2 现状事实逐条 grep 复核零漂移**——battle_stage_view(PanelContainer/252px/五成员/setter 面)+standee_view(Control/行为面 17 方法/slot_row compact/字形占位)+hud_presenter 53-54/79-80 单投喂+main 309/441/503+ui_assembler 23+ui_probe 95-129/ui_click 223 穿透面+ui_input_probe 零 B 区耦合(grep stage/standee/enemy=0 命中)+TEX_HERO_PORTRAIT 素材 worktree 缺位=C7 回退字形路径预期。**Alpha 清单初稿落盘** production/alpha-acceptance-battle-screen.md——六源拼装(battle.md AC+§13 义务表/HUD框架 验收标准+基线表/art-bible §8 判据/07§⑨ 试玩指引/06 挂 Alpha 条目备查/工程回归面),七节 30 条=判据+验法三档(headless/真机渲染/人)+状态列,销项归 Alpha 验收批。轻闸全绿,进入 T1。
|
||||
169. **样张 v1 制作与机检批(2026-09-26,本会话——循环 1 T1;worktree battle-stage-node2d-20260926 批次本提交)**:①**四源对照表先行** production/mockups/画法参数四源对照表-2026-09-26.md(battle.md 布局/机制代码〔0 格无字形 board_view:586·旗只插未开 :589·脚锚自底 25%〕/引擎常量〔45px·1.5× 档·96px 盒〕/art-bible §1.2-§4.6 画法)——候选值偏差两笔登记(小人蓝 #2E86DE 候选 vs UiKit #2E6E8E=样张批冻结项非矛盾;格底 L≥0.30 系换皮槽参数域不复裁已验收 dungeon 瓦片)。②**脚本重写** tools/render_sample_sheet.py v1:方案甲词表查表拼装(16 情形+对角回落 nw>ne>sw>se+flip 镜像+变体 60/20/20 哈希)+三区全内容 1280×800 实比 mockup+S2 数字档 0.5× 抽检+S3 underdark 四槽换色+S4 图例;素材两级回退(worktree→主检出,素材不入 git)。③**机检 12 断言生成即验全绿**——F1 词表拼装零错位 15 种用件/F2 旗∈未开/F3 脚锚自底 25%(两态)〔预筛抓出素材底部 7 行全透明→裁除留白后锚定,视觉脚=锚线;**游戏内 BoardWorld.ensure_hero 同病(视觉脚浮锚线 ~10px)=呈现缺陷登记移交循环 2/接线批**〕/F4 0 格无字形/F5a 接触带微光⊆英雄格/F5b 类型微光禁整格染色(中心 50% 区零像素——角嵌臂长两轮收紧 L9→L5 留白砖心)/A1 色板对表+禁入带 300-345° 零命中(腐蚀两轮滤 AA 混色)/A2 周界闭合(墙侧 2px 带墨线存在性 min<55——45px 非整数缩放下均值判误报改最暗值判)/A3 墨×牌 11.8-12.0:1+图底分离 113 vs 51/A4 混排在库原件/A5 画布四缘净空(溢出永久断言)。④**visual-judge 预筛三轮**(≤3 预算内):R1 四 FATAL→triage=站桩横向重叠/小人脚浮(素材留白)/同格态色牌被小人盖(改 §1.2 栈序数字>小人)/缘件裸拼误报(1px 墨线逐像素 zoom 自证 end_n 三向墨线俱在+15 种用件机检反证,判官 3-6px 采样带均值漏 1px 线)+地精无徽标误报(普攻零表示=设计);R2 两 FATAL=画布右缘溢出×2(说明行+S4 末项)→画布 1560+A5 断言化;R3 窄域复核 pass。⑤**交付**=样张 v1+机检报告+对照表三件已拷主区 production/mockups/(评审产物不入 git 同 v0 先例),**用户异步终审**(过=冻结为循环 2 输入;不过=对表改参重出);终审不阻塞 T2-T7。轻闸全绿(当轮基线=T0 记档),进入 T2。
|
||||
169. **样张 v1 制作与机检批(2026-09-26,本会话——循环 1 T1;worktree battle-stage-node2d-20260926 批次本提交)**:①**四源对照表先行** production/mockups/画法参数四源对照表-2026-09-26.md(battle.md 布局/机制代码〔0 格无字形 board_view:586·旗只插未开 :589·脚锚自底 25%〕/引擎常量〔45px·1.5× 档·96px 盒〕/art-bible §1.2-§4.6 画法)——候选值偏差两笔登记(小人蓝 #2E86DE 候选 vs UiKit #2E6E8E=样张批冻结项非矛盾;格底 L≥0.30 系换皮槽参数域不复裁已验收 dungeon 瓦片)。②**脚本重写** tools/render_sample_sheet.py v1:方案甲词表查表拼装(16 情形+对角回落 nw>ne>sw>se+flip 镜像+变体 60/20/20 哈希)+三区全内容 1280×800 实比 mockup+S2 数字档 0.5× 抽检+S3 underdark 四槽换色+S4 图例;素材两级回退(worktree→主检出,素材不入 git)。③**机检 12 断言生成即验全绿**——F1 词表拼装零错位 15 种用件/F2 旗∈未开/F3 脚锚自底 25%(两态)〔预筛抓出素材底部 7 行全透明→裁除留白后锚定,视觉脚=锚线;**游戏内 BoardWorld.ensure_hero 同病(视觉脚浮锚线 ~10px)=呈现缺陷登记移交循环 2/接线批**〕/F4 0 格无字形/F5a 接触带微光⊆英雄格/F5b 类型微光禁整格染色(中心 50% 区零像素——角嵌臂长两轮收紧 L9→L5 留白砖心)/A1 色板对表+禁入带 300-345° 零命中(腐蚀两轮滤 AA 混色)/A2 周界闭合(墙侧 2px 带墨线存在性 min<55——45px 非整数缩放下均值判误报改最暗值判)/A3 墨×牌 11.8-12.0:1+图底分离 113 vs 51/A4 混排在库原件/A5 画布四缘净空(溢出永久断言)。④**visual-judge 预筛三轮**(≤3 预算内):R1 四 FATAL→triage=站桩横向重叠/小人脚浮(素材留白)/同格态色牌被小人盖(改 §1.2 栈序数字>小人)/缘件裸拼误报(1px 墨线逐像素 zoom 自证 end_n 三向墨线俱在+15 种用件机检反证,判官 3-6px 采样带均值漏 1px 线)+地精无徽标误报(普攻零表示=设计);R2 两 FATAL=画布右缘溢出×2(说明行+S4 末项)→画布 1560+A5 断言化;R3 窄域复核 pass。⑤**交付**=样张 v1+机检报告+对照表三件已拷主区 production/mockups/(评审产物不入 git 同 v0 先例),**用户异步终审**(过=冻结为循环 2 输入;不过=对表改参重出);终审不阻塞 T2-T7。轻闸全绿(当轮基线=T0 记档),进入 T2。
|
||||
170. **B 区战斗舞台壳改造批(Phase B T2,2026-09-26,本会话——循环 1;worktree battle-stage-node2d-20260926)**:BattleStageView 根壳 PanelContainer→**Control**(类名/252px/树内位置不变;面板样式=Panel 子面+原 stylebox 等价平移,子面几何沿原内容边距 Rect2(6,4,6,4));内部拆两半区——**Node2D 舞台半区**=SubViewportContainer(stretch=true 1:1 禁缩放系数)+SubViewport(transparent_bg)+**StageWorld**(新件 presentation/views/stage_world.gd,无 class_name 经 preload 接线,BoardWorld 同构:world_font 字体注入槽位+font_probe() C6 判据出口〔注入非空+has_char+宽度>0〕;T2 期世界空置待 T3 站桩迁入)+**Control 文本半区**=round_label/stage_center/log_view 三件原样保留(C1 永久 Control),hero_standee/enemy_box 本期仍 Control 原位。新挂点=set_world_font(f)(Phase A BoardView 同款,无调用方纯挂点)+world_to_shell(p) 坐标换算单点(C4——世界=局部排布/壳层=全局含容器偏移)。**C6 判据实证**(临时脚本跑完即删):未注入=回退字体 has_char=false(引擎默认无 CJK=文档既有口径);注入 fusion-pixel ja TTF(内存 load_dynamic_font 零素材入工程——C7)后 has_char=true 宽度 70>0 PASS。**验收**=轻闸全绿:editor --quit 0 error+冒烟 557/0(=基线)+五探针全绿+ui_layout_probe 外框逐位零漂移(stage pos=(0,0) size=(1280,252) min=(0,252)=T0 基线同值;B 区内部树结构变化记录:PanelContainer 自动布局→Control 锚点+VBox 同边距)+static_scan exit0+文档三闸零漂移。进入 T3。
|
||||
Reference in new issue
Block a user