补提交(布局几何单点化批·代码面+工具面+architecture行·跨会话遗留): battle_layout.tres 新表单行五字段(stage_h/info_panel_w/ap_bar_h/log_band_h_dig/log_band_h_settle)经 schema battle_layout_table.gd+域容器 config_domain_presentation.gd 收进 ConfigDb.presentation(ConfigDB 三容器→四容器,manifest 增 battle_layout 键,B区高度裁决 2026-10-30 用户裁=取代码标准 stage_h);views 五件构造签名增 layout 参(BattleStageView/HeroInfoPanelView/BoardZoneView/ApBarView/BattleLogView 常量高度改表值驱动)+ui_assembler 装配传 layout+probes 两件改址+main.gd 结算带注释去数值;tools/layout_config.py 新件+render_sample_sheet 两版读布局表现算(样张工具面);文档面: architecture.md ConfigDB 行换代(四容器成员 7/7/5/1、类变量 10)+HUD框架.md 三区表/装板不等式/调参表去数值化改指布局表+数据配置.md+interaction-patterns.md 明细带句去数值(battle.md 区表与待办清单登记面已随 1cdef6ba 在库);消费漏网 L1 就地补改九处(构造签名换型与 iter45 断点件收编的测试改址漏网,判据零变化): theme_projection_test:386/player_copy_sweep_test:44,98/adventure_feats_test:772/standee_fx_sweep_test:75/feat_vouchers_test:292 六处补 layout 实参,adventure_feats_test:791/level_shop_economy_test:1480/feat_vouchers_test:81 三处断点成员直读改经 a._bp_store(iter45卡②六成员搬移漏网,02 闸合回后首全量暴露);load_tables 超函数长键清偿(容器装配块抽 _assign_loaded 私有协函数——表行按域收进四容器+resolver 注入单一职责,与 _cross_validate 委托先例同型,S13 新增红修至基线口径内);窄验: 四件修复套件单跑全绿+gdstyle 基线外新违规 0
This commit is contained in:
1 parent
39907d82f6
commit
4b174877be
29 files changed
+231
-118
No files matched your search
@@ -40,7 +40,7 @@ v3.0 口径(方向稿=目检先行闸,冻结归机检):
|
||||
迭代 43 扩展(2026-10-29 战斗一屏样张批):整屏样张两版出口(1280×800 基座 + 1920×1080 全局等比
|
||||
1.35×+左右黑边,§8.2 1920 档策略)+ art-bible §1.4 整屏四项断言(S1–S4)+ 战斗表现五项断言(P1–P5)
|
||||
+ S3b 图类型色板变体第二套 + S5 三组关键帧条 + S6 描边同屏对照与遮挡对照组 + V1 两版尺寸断言
|
||||
+ V10 改前/改后基线并排对拍;B 区高按代码现状 252 出样(art-bible §8.2 文 270 差异只登记不修)。
|
||||
+ V10 改前/改后基线并排对拍;分区几何读 game/data/tables/battle_layout.tres(与游戏侧同源)。
|
||||
"""
|
||||
from PIL import Image, ImageDraw, ImageFilter, ImageChops, ImageFont
|
||||
import os
|
||||
@@ -50,6 +50,8 @@ import re
|
||||
import hashlib
|
||||
from collections import deque
|
||||
|
||||
from layout_config import load as load_layout
|
||||
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
MAIN_ROOT = "D:/code/g-plan2"
|
||||
|
||||
@@ -845,14 +847,22 @@ def draw_standee(canvas, ox, oy, kind, name, enemy_id, order=1, armor="light",
|
||||
canvas.alpha_composite(gray, (ox, oy))
|
||||
|
||||
|
||||
B_H = 252 # B 区高=代码现状(battle_stage_view custom_minimum_size 252;§8.2 文 270 差异只登记不修)
|
||||
CANVAS_W = 1280 # 基座档(art-bible §8.1)
|
||||
CANVAS_H = 800
|
||||
_LAYOUT = load_layout()
|
||||
B_H = _LAYOUT["stage_h"] # B 区高(布局表单点——与游戏侧同源)
|
||||
C_W = _LAYOUT["info_panel_w"] # C 区宽
|
||||
D_X = C_W + 4 # D 区左边 = C 区宽 + 列间距
|
||||
D_W = CANVAS_W - D_X # D 区宽
|
||||
BAND_DIG = _LAYOUT["log_band_h_dig"] # 明细带收起高
|
||||
BAND_SETTLE = _LAYOUT["log_band_h_settle"]
|
||||
AP_H = _LAYOUT["ap_bar_h"] # D 区 AP 条高
|
||||
|
||||
|
||||
def draw_base(canvas_w=CANVAS_W, canvas_h=800, b_h=B_H):
|
||||
"""样张底板(T1):B/C/D 三区骨架——分区数值按 battle.md 指路、B 区按代码 252;格边长=CELL_D 45
|
||||
def draw_base(canvas_w=CANVAS_W, canvas_h=CANVAS_H, b_h=B_H):
|
||||
"""样张底板(T1):B/C/D 三区骨架——分区几何全部读布局表 battle_layout.tres;格边长=CELL_D 45
|
||||
(D 区 10×10 板实比,§8.1)。返回 (img, zones)——zones 供 S/P 断言取样:
|
||||
b=(0,0,w,b_h) 含明细带;band=明细带 24px;c=(0,b_h+4,240,h);d=(244,b_h+4,w,h)。"""
|
||||
b=(0,0,w,b_h) 含明细带;band=明细带收起高;c=(0,b_h+4,C_W,h);d=(D_X,b_h+4,w,h)。"""
|
||||
img = Image.new("RGBA", (canvas_w, canvas_h), (24, 20, 17, 255))
|
||||
d = ImageDraw.Draw(img)
|
||||
c_y = b_h + 4
|
||||
@@ -865,25 +875,26 @@ def draw_base(canvas_w=CANVAS_W, canvas_h=800, b_h=B_H):
|
||||
a = int(26 * (1 - i / 60.0))
|
||||
db.rectangle([bx0 - 46 + i // 3, 0, bx0 + 46 - i // 3, 40 + i * 3], fill=(255, 236, 200, a))
|
||||
img.alpha_composite(beam, (0, 0))
|
||||
# 明细带(挖掘期收起 24px)
|
||||
d.rectangle([0, b_h - 24, canvas_w, b_h], fill=(46, 39, 32))
|
||||
# 明细带(挖掘期收起——高读布局表)
|
||||
d.rectangle([0, b_h - BAND_DIG, canvas_w, b_h], fill=(46, 39, 32))
|
||||
# C 区
|
||||
d.rectangle([0, c_y, 240, canvas_h], fill=UIKIT["PANEL_HERO"], outline=UIKIT["PANEL_BORDER"])
|
||||
d.rectangle([0, c_y, C_W, canvas_h], fill=UIKIT["PANEL_HERO"], outline=UIKIT["PANEL_BORDER"])
|
||||
# D 区
|
||||
d.rectangle([244, c_y, canvas_w, canvas_h], fill=(34, 29, 24), outline=UIKIT["PANEL_BORDER"])
|
||||
# D 区顶行工具件(停手/图例/刷新+AP 点阵+RAP)
|
||||
d.rectangle([252, c_y + 6, 304, c_y + 28], fill=(90, 80, 66), outline=(120, 106, 88))
|
||||
d.text((278, c_y + 17), "停手", font=F_LBL2, fill=(232, 222, 200), anchor="mm")
|
||||
d.rectangle([310, c_y + 6, 354, c_y + 28], fill=(90, 80, 66), outline=(120, 106, 88))
|
||||
d.text((332, c_y + 17), "?图例", font=F_LBL2, fill=(232, 222, 200), anchor="mm")
|
||||
d.rectangle([360, c_y + 6, 428, c_y + 28], fill=(90, 80, 66), outline=(120, 106, 88))
|
||||
d.text((394, c_y + 17), "刷新 8|剩2", font=F_LBL2, fill=(232, 222, 200), anchor="mm")
|
||||
d.rectangle([D_X, c_y, canvas_w, canvas_h], fill=(34, 29, 24), outline=UIKIT["PANEL_BORDER"])
|
||||
# D 区顶行工具件(停手/图例/刷新+AP 点阵+RAP——坐标随 C 区宽平移)
|
||||
dx = D_X + 8
|
||||
d.rectangle([dx, c_y + 6, dx + 52, c_y + 28], fill=(90, 80, 66), outline=(120, 106, 88))
|
||||
d.text((dx + 26, c_y + 17), "停手", font=F_LBL2, fill=(232, 222, 200), anchor="mm")
|
||||
d.rectangle([dx + 58, c_y + 6, dx + 102, c_y + 28], fill=(90, 80, 66), outline=(120, 106, 88))
|
||||
d.text((dx + 80, c_y + 17), "?图例", font=F_LBL2, fill=(232, 222, 200), anchor="mm")
|
||||
d.rectangle([dx + 108, c_y + 6, dx + 176, c_y + 28], fill=(90, 80, 66), outline=(120, 106, 88))
|
||||
d.text((dx + 142, c_y + 17), "刷新 8|剩2", font=F_LBL2, fill=(232, 222, 200), anchor="mm")
|
||||
for i in range(6):
|
||||
col = (232, 200, 120) if i < 4 else (120, 106, 88)
|
||||
d.ellipse([440 + i * 18, c_y + 10, 452 + i * 18, c_y + 22], fill=col)
|
||||
d.text((552, c_y + 17), "RAP 6/6", font=F_LBL2, fill=(200, 180, 140), anchor="lm")
|
||||
zones = {"b": (0, 0, canvas_w, b_h), "band": (0, b_h - 24, canvas_w, b_h),
|
||||
"c": (0, c_y, 240, canvas_h), "d": (244, c_y, canvas_w, canvas_h)}
|
||||
d.ellipse([dx + 188 + i * 18, c_y + 10, dx + 200 + i * 18, c_y + 22], fill=col)
|
||||
d.text((dx + 300, c_y + 17), "RAP 6/6", font=F_LBL2, fill=(200, 180, 140), anchor="lm")
|
||||
zones = {"b": (0, 0, canvas_w, b_h), "band": (0, b_h - BAND_DIG, canvas_w, b_h),
|
||||
"c": (0, c_y, C_W, canvas_h), "d": (D_X, c_y, canvas_w, canvas_h)}
|
||||
return img, zones
|
||||
|
||||
|
||||
@@ -901,24 +912,25 @@ def render_battle_screen(board_img=None):
|
||||
statuses=("alert",))
|
||||
draw_standee(scr, 1128, 34, "enemy", "食人魔酋长", "ogre_chief", order=3, armor="light", hp=1.0, intent="buff")
|
||||
# 明细带摘要行 + 结算语境 hero 剪影 mini(P2 三语境之一;右端贴装不越缘)
|
||||
d.text((10, 240), "── 第 3 轮 ── 地精 受到 4 点伤害(增伤 ×1)· 熊地精 蓄力(重击预告)…", font=F_LBL2,
|
||||
d.text((10, b_h - BAND_DIG // 2), "── 第 3 轮 ── 地精 受到 4 点伤害(增伤 ×1)· 熊地精 蓄力(重击预告)…", font=F_LBL2,
|
||||
fill=(240, 226, 200), anchor="lm")
|
||||
mini = HERO.resize((24, int(24 * HERO.size[1] / HERO.size[0])), Image.NEAREST)
|
||||
scr.alpha_composite(mini, (1236, b_h - 24))
|
||||
# ── C 区内容(次级文对齐 §7.2 ≥4.5:1——STONE_DEEP/GOLD_INK 在册墨) ──
|
||||
d.rectangle([8, 264, 232, 340], outline=(120, 106, 88), width=1) # 攻击数据框(直角细线)
|
||||
d.text((16, 276), "攻击 6", font=ImageFont.truetype(ZH_FONT, 15), fill=(30, 26, 22))
|
||||
d.text((16, 298), "(+50% 增伤 ×1)", font=F_LBL2, fill=(116, 80, 11))
|
||||
d.text((16, 318), "护甲 AC 12", font=ImageFont.truetype(ZH_FONT, 15), fill=(30, 26, 22))
|
||||
d.text((8, 352), "魔法道具槽(预留)", font=F_LBL2, fill=(85, 77, 65))
|
||||
scr.alpha_composite(mini, (CANVAS_W - 44, b_h - BAND_DIG))
|
||||
# ── C 区内容(次级文对齐 §7.2 ≥4.5:1——STONE_DEEP/GOLD_INK 在册墨;y 随 B 区高平移) ──
|
||||
cy = b_h + 4
|
||||
d.rectangle([8, cy + 8, C_W - 8, cy + 84], outline=(120, 106, 88), width=1) # 攻击数据框(直角细线)
|
||||
d.text((16, cy + 20), "攻击 6", font=ImageFont.truetype(ZH_FONT, 15), fill=(30, 26, 22))
|
||||
d.text((16, cy + 42), "(+50% 增伤 ×1)", font=F_LBL2, fill=(116, 80, 11))
|
||||
d.text((16, cy + 62), "护甲 AC 12", font=ImageFont.truetype(ZH_FONT, 15), fill=(30, 26, 22))
|
||||
d.text((8, cy + 96), "魔法道具槽(预留)", font=F_LBL2, fill=(85, 77, 65))
|
||||
for i in range(4):
|
||||
d.rectangle([8 + i * 40, 368, 8 + i * 40 + 34, 402], outline=(120, 106, 88), width=1)
|
||||
d.text((8, 416), "本关强化列表(预留)", font=F_LBL2, fill=(85, 77, 65))
|
||||
d.rectangle([8 + i * 40, cy + 112, 8 + i * 40 + 34, cy + 146], outline=(120, 106, 88), width=1)
|
||||
d.text((8, cy + 160), "本关强化列表(预留)", font=F_LBL2, fill=(85, 77, 65))
|
||||
# ── D 区主样张板(10×10@45px=450×450+悬崖 8)嵌进工具行之下居中 ──
|
||||
board_origin = None
|
||||
if board_img is not None:
|
||||
bx = 244 + (1036 - board_img.size[0]) // 2
|
||||
by = b_h + 4 + 34 + (800 - b_h - 4 - 34 - board_img.size[1]) // 2
|
||||
bx = D_X + (D_W - board_img.size[0]) // 2
|
||||
by = cy + AP_H + (CANVAS_H - cy - AP_H - board_img.size[1]) // 2
|
||||
scr.paste(board_img.convert("RGB"), (bx, by), board_img)
|
||||
board_origin = (bx, by)
|
||||
return scr, zones, board_origin
|
||||
@@ -1644,7 +1656,7 @@ def main():
|
||||
d.text((20, 14), "战斗一屏样张方向稿 v3-draft(2026-09-29,art-bible v3.0;迭代 43 扩展:整屏两版+S1–S4/P1–P5 断言)——机检 %s(方向稿参考,冻结归目检后机检批)" %
|
||||
("全绿" if ok else "有 FAIL"), col=(232, 222, 200), font=F_TITLE)
|
||||
canvas.paste(scr, (20, 52))
|
||||
d.text((20, 866), "三区 mockup(1280×800 实比,B 区按代码 252):B 区站桩(主角立绘 96 朝右/敌字形占位/顺位 FS_HINT/意图素牌/血条=危险红/名行=素底牌+护甲 PNG)",
|
||||
d.text((20, 866), "三区 mockup(1280×800 实比,分区几何读布局表):B 区站桩(主角立绘 96 朝右/敌字形占位/顺位 FS_HINT/意图素牌/血条=危险红/名行=素底牌+护甲 PNG)",
|
||||
col=(225, 215, 195), font=F_LBL)
|
||||
d.text((20, 886), "C 区攻击数据框+预留槽 · D 区主样张板(方案甲拼装/接触带微光/悬停金框/封印印记/危险格巢穴占位)",
|
||||
col=(225, 215, 195), font=F_LBL)
|
||||
@@ -1732,7 +1744,7 @@ def main():
|
||||
with open(OUT_REPORT, "w", encoding="utf-8") as f:
|
||||
f.write("# 样张 v3 机检报告(2026-09-30 批 A 断言定值 + 迭代 43 整屏扩展 S1–S4/P1–P5/V1/V10/A7/A5b)\n\n")
|
||||
f.write("生成:`python tools/render_sample_sheet_v3.py`;v3.5 冻结口径:格底分档/亮墨直画三档/色牌后备/物件级装饰/B 区舞台;A3b 图底分离 Δ≥30;A4 尺寸基线(立绘 46×48/小人源 32×32 硬等)。"
|
||||
"迭代 43 扩展:B 区按代码 252 出样;整屏四项与战斗表现五项断言落 CHECKS;两版样张出口与基线并排对拍。方向稿目检先行,机检冻结归目检通过后。\n\n")
|
||||
"迭代 43 扩展:B 区高读布局表出样;整屏四项与战斗表现五项断言落 CHECKS;两版样张出口与基线并排对拍。方向稿目检先行,机检冻结归目检通过后。\n\n")
|
||||
f.write("## 断言明细\n\n")
|
||||
f.write("| 断言 | 判据 | 结果 | 明细 |\n|---|---|---|---|\n")
|
||||
for cid, name, okk, detail in CHECKS:
|
||||
|
||||
Reference in new issue
Block a user