这三处都是「精灵或按钮已在清单里定案,但配置层缺东西」,不补的话 C/D/E 阶段
写渲染代码时会发现没有布局节点,极易就地硬编码坐标(违反零裸值红线)。
1) 底栏「扣底」按钮没有精灵(清单 §2.6 列了 5 个功能按钮,只登记了 4 个)
- 新增 BTN_BURY_CARDS(1056) / BTN_BURY_CARDS_TEXT(1057),群组 205 号段内空闲号,
资源沿用 BTN_BOTTOM_FUNC,与其余四个按钮同构。
- FOOTER_FUNC_BUTTONS 的 items 由 4 项扩到 5 项,扣底紧邻底牌(照 §2.6 表序)。
扣底宽 78 是【估值】:清单未给,取同为两字按钮的「底牌」实测值,已在配置与清单里注明。
- 扣底看【埋牌底牌】(burycards)、底牌看【底牌】(bottomcards),两批不同的牌,
JSDoc 里补了防写反的提示(对应验收清单第 13 条)。
2) 出牌阶段「提示」按钮有精灵、无布局槽位
- PLAY_OPERATION_BAR.items 补上 PLAY_BTN_TIP,顺序照清单 §1.7 行文:倒计时 / 出牌 / 提示。
- 宽 180 是【估值】:清单 §6.8 自身漏了该项;与埋牌条的提示按钮同资源 BTN_TIP
(§3.3 实测 180×63),埋牌条 items 首项亦取 180,故沿用。
- 顺带记下一处待裁定项:本条 itemHeight 为 55(对齐 BTN_PLAY 157×55),
而 BTN_TIP 原生高 63,高度差待设计稿定。
3) AccountView / HistoryView / MingPaiView 一个布局节点都没有
- AccountView(§6.9a 新增):外壳 6 个节点 + 玩家栏「容器 ACC_ROW_CONTAINER +
行节点 ACC_ROW(itemHeight 即行高,行数由 ctx.count 给出)+ 行内模板贴附到行矩形」
+ 面板外 4 按钮,共 14 个节点。行内节点求出的是相对容器的坐标,可直接喂
SpriteCopyUtils.create(与 §5.6a 冲关牌同一用法)。
- HistoryView / MingPaiView(§6.9c 新增):遮罩 + 容器 + 每家一排牌(fan) + 座位标签,
各 4 个节点。照 CHONGGUAN_FAN 同构、锚点沿用 §6.7 冲关牌的三家落点;
差别只在张数上限——出牌历史摊平后可达 28 张以上,故 maxWidth 放宽到 500、
spacingMin 收到 -96【估值】。MING_* 只有 LEFT/RIGHT 两个 bySeat 变体(明牌不看自己)。
- 坐标来源:大局结算.png / 冲关牌型显示.png 目视实测,w/h 取资源尺寸;
配置与清单里均已注明「目视实测估值,待设计稿复核」。
- 运行时才确定的字段(动态文字宽高、随行浮动的 anchorY、数字精灵宽)一律
runtime 显式声明。
钉死断言按实际重新数并更新:精灵总数 378 → 380,布局节点总数 61 → 83。
另把 ACC_TPL_SCORE_NUM 加进 NUM_STYLE 同源校验表(与 RESULT_SCORE_NUM 同一套资源)。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
155 lines
7.8 KiB
JavaScript
155 lines
7.8 KiB
JavaScript
///////////////////////////////////////////////////////////////
|
||
////////// EQW_Layout: 常驻区 + 玩家位(清单 §6.5 / §6.6)//////
|
||
///////////////////////////////////////////////////////////////
|
||
// 【纯数据文件】无函数、无副作用;依赖 LayoutConstants.js 先加载
|
||
// (引用其 EQW_Layout.TEXT_STYLE.*,属 EQW_Layout 内部自引用)。
|
||
var EQW_Layout = EQW_Layout || {};
|
||
|
||
//===== 常驻区(清单 §6.5)=====
|
||
|
||
//顶部信息条底
|
||
EQW_Layout.TOP_INFO_BG = { kind: 'point', x: 486, y: 4, w: 276, h: 68 };
|
||
|
||
//顶部 · 花色图标:贴信息条内部左下角(资源 SUIT_ICON_S 30×30,清单 §3)
|
||
EQW_Layout.TOP_SUIT_ICON = {
|
||
kind: 'attach', targetKind: 'layout', target: 'TOP_INFO_BG',
|
||
hAlign: 'left', vAlign: 'bottom', offsetX: 20, offsetY: -8, w: 30, h: 30
|
||
};
|
||
|
||
//顶部 · 叫分数值文字 / 抓分数值文字:【清单 §6.5 未给出位置】——那张表只列了两个角标底与角标
|
||
//文字,而角标底又必须贴在这两段数值文字身上。此处显式占位:坐标与宽高全部标为运行时注入,
|
||
//由调用方按信息条内的三列表格实际排布给出;设计稿补齐后把 x/y/w/h 回填成固定值即可。
|
||
//显式占位是为了避免 C 阶段在渲染代码里就地硬编码一组坐标——那样这两处位置就再也无从统一修改
|
||
EQW_Layout.TOP_CALL_TEXT = { kind: 'point', runtime: ['x', 'y', 'w', 'h'] };
|
||
EQW_Layout.TOP_GRADE_TEXT = { kind: 'point', runtime: ['x', 'y', 'w', 'h'] };
|
||
|
||
//顶部 · 叫分角标底:贴叫分数值文字右上角(资源 BADGE_MULTIPLE 帧1 34×18)。
|
||
//角标数值文字复用同一矩形,不单独配置(清单未给独立位置,下同)
|
||
EQW_Layout.TOP_CALL_BADGE_BG = {
|
||
kind: 'attach', targetKind: 'layout', target: 'TOP_CALL_TEXT',
|
||
corner: 'topRight', offsetX: 4, offsetY: 6, w: 34, h: 18
|
||
};
|
||
|
||
//顶部 · 抓分角标底:贴抓分数值文字右上角(资源 BADGE_MULTIPLE 帧2 34×18)
|
||
EQW_Layout.TOP_GRADE_BADGE_BG = {
|
||
kind: 'attach', targetKind: 'layout', target: 'TOP_GRADE_TEXT',
|
||
corner: 'topRight', offsetX: 4, offsetY: 6, w: 34, h: 18
|
||
};
|
||
|
||
//自己的主牌统计条(手牌上方「x对 x主」,群组 206)。
|
||
//2026-08-27 由 LIANGPAI_BG 改名:与 design §8.2 的「亮牌」同名异实,后者是遮罩面板(群组 242)
|
||
EQW_Layout.ZHU_STAT_BG = { kind: 'point', x: 35, y: 400, w: 210, h: 35 };
|
||
|
||
//底栏条
|
||
EQW_Layout.FOOTER_BG = { kind: 'point', x: 0, y: 648, w: 1280, h: 72 };
|
||
|
||
//底栏 · 局数文字「1/4 局」
|
||
EQW_Layout.FOOTER_ASET_TEXT = {
|
||
kind: 'point', x: 635, y: 672, w: 65, h: 26, textStyle: EQW_Layout.TEXT_STYLE.ASET_COUNT
|
||
};
|
||
|
||
//底栏 · 功能钮组(明牌/已出牌/上一轮/扣底/底牌):逐项不等宽(清单 §6.1 T-25)。
|
||
//2026-08-27 补上「扣底」项(清单 §2.6 列的是 5 个按钮,此处原只排了 4 个)——
|
||
//排序按 §2.6 表:扣底紧邻底牌(两者分别看埋牌底牌 / 底牌,成对但不同批,勿写反)。
|
||
//【估值】扣底 78:清单未给该项宽度;同为两字按钮的「底牌」实测 78、「明牌」74,
|
||
//故取同类两字按钮的 78,待设计稿复核(其余四项 74/87/93/78 为清单 §6.5 实测值)
|
||
EQW_Layout.FOOTER_FUNC_BUTTONS = {
|
||
kind: 'line', direction: 'horizontal', anchorX: 1250, anchorY: 672,
|
||
itemHeight: 30, spacing: 15, anchor: 'right',
|
||
items: [
|
||
{ key: 'BTN_MINGPAI', width: 74 },
|
||
{ key: 'BTN_HISTORY', width: 87 },
|
||
{ key: 'BTN_LAST_ROUND', width: 93 },
|
||
{ key: 'BTN_BURY_CARDS', width: 78 },
|
||
{ key: 'BTN_BOTTOM_CARDS', width: 78 }
|
||
]
|
||
};
|
||
|
||
//底栏 · 提示按钮组(踩/有分/没分):count 由运行时同时可见的按钮数给出,不进配置
|
||
EQW_Layout.FOOTER_TISHI_BUTTONS = {
|
||
kind: 'line', direction: 'horizontal', anchorX: 335, anchorY: 672,
|
||
itemWidth: 52, itemHeight: 30, spacing: 26, anchor: 'left'
|
||
};
|
||
|
||
//右侧语音钮(平台):坐标仅登记供 01_SubGame_modify.js 配置区人工同步核对(清单 §6.11 同类处理)
|
||
EQW_Layout.VOICE_BTN_REF = { kind: 'point', x: 1210, y: 310, w: 56, h: 56 };
|
||
|
||
//右侧聊天钮(平台):同上
|
||
EQW_Layout.CHAT_BTN_REF = { kind: 'point', x: 1210, y: 385, w: 56, h: 56 };
|
||
|
||
//===== 玩家位(清单 §6.6)=====
|
||
|
||
//头像框(平台提供):仅登记坐标供 attach 参考与 Game_Modify.PLAYER_INFO_LAYOUT 人工同步(清单 §6.11)。
|
||
//SELF 尺寸与 LEFT/RIGHT 不同(84×53 vs 91×118),bySeat 内单独覆盖 w/h
|
||
EQW_Layout.PLAYER_AVATAR_FRAME_REF = {
|
||
kind: 'point', w: 91, h: 118,
|
||
bySeat: {
|
||
LEFT: { x: 22, y: 122 },
|
||
RIGHT: { x: 1160, y: 122 },
|
||
SELF: { x: 22, y: 645, w: 84, h: 53 }
|
||
}
|
||
};
|
||
|
||
//『庄』印章:三家各一个精灵(P_LEFT_BANKER / P_RIGHT_BANKER / P_SELF_BANKER),按 bySeat 求位置。
|
||
//LEFT/RIGHT 贴平台头像框外角;SELF 为底栏固定点(与清单 §6.5「底栏·庄标」同一元素,此处合并,避免重复定义)。
|
||
//注意:base 的 kind 是 attach,SELF 变体里【有意】把 kind 覆盖为 point——EQW_LayoutSolver._mergeBySeat
|
||
//会合并包括 kind 在内的所有字段,这里利用该机制表达「底栏庄标是固定坐标、不贴附任何目标」,
|
||
//与 LEFT/RIGHT 两个上家贴头像框(attach)是不同的定位方式,不是笔误
|
||
EQW_Layout.P_BANKER_MARK = {
|
||
kind: 'attach', targetKind: 'platform', w: 40, h: 40,
|
||
bySeat: {
|
||
LEFT: { target: 'P_LEFT_AVATAR', corner: 'topRight', offsetX: 7, offsetY: 8 },
|
||
RIGHT: { target: 'P_RIGHT_AVATAR', corner: 'topLeft', offsetX: -40, offsetY: 8 },
|
||
SELF: { kind: 'point', x: 338, y: 668, w: 32, h: 34 }
|
||
}
|
||
};
|
||
|
||
//『主N』角标底:仅左右两家(自己主/对数已在手牌区可见,无此角标)。w/h 为清单 §6.6 实测值
|
||
EQW_Layout.P_ZHU_BADGE = {
|
||
kind: 'attach', targetKind: 'platform', corner: 'bottomLeft', offsetX: 0, offsetY: 6, w: 40, h: 19,
|
||
bySeat: {
|
||
LEFT: { target: 'P_LEFT_AVATAR' },
|
||
RIGHT: { target: 'P_RIGHT_AVATAR' }
|
||
}
|
||
};
|
||
|
||
//『对N』角标底:贴主N角标右侧。w/h 清单未重复给出,沿用主N角标同尺寸
|
||
//(同资源 BADGE_ZHU_PAIR 的另一帧,帧1黄底=主N、帧2白底=对N,尺寸一致)
|
||
EQW_Layout.P_PAIR_BADGE = {
|
||
kind: 'attach', targetKind: 'layout', target: 'P_ZHU_BADGE', hAlign: 'right', vAlign: 'middle',
|
||
offsetX: 44, offsetY: 0, w: 40, h: 19
|
||
};
|
||
|
||
//状态文字「60分」/「不叫」:仅左右两家(自己此阶段无独立文字区,见清单 §6.6 表)
|
||
EQW_Layout.P_STATUS_TEXT = {
|
||
kind: 'point', w: 130, h: 70, textStyle: EQW_Layout.TEXT_STYLE.STATUS_BIG,
|
||
bySeat: {
|
||
LEFT: { x: 170, y: 165 },
|
||
RIGHT: { x: 980, y: 165 }
|
||
}
|
||
};
|
||
|
||
//倒计时:三家都有(多帧图数字精灵,纯秒数无后缀,见 NUM_STYLE.COUNTDOWN)。
|
||
//高度恒为单字高,取 NUM_STYLE.COUNTDOWN.charHeight(SSOT);宽度随位数变化
|
||
//(SpriteManager.setNumberImage 按【字符数 × charWidth】自动改精灵宽),故 w 留到运行时注入
|
||
EQW_Layout.P_COUNTDOWN = {
|
||
kind: 'point', h: EQW_Layout.NUM_STYLE.COUNTDOWN.charHeight,
|
||
runtime: ['w'],
|
||
bySeat: {
|
||
LEFT: { x: 195, y: 165 },
|
||
RIGHT: { x: 1010, y: 165 },
|
||
SELF: { x: 445, y: 345 }
|
||
}
|
||
};
|
||
|
||
//提示气泡(踩/没分/有分):朝向 arrowRight 是配置项,不按座位硬判(清单 §6.6)。
|
||
//w/h 清单 §3 标『待定』,此处用示意尺寸占位,资源定稿后回填(不影响 kind/字段结构)
|
||
EQW_Layout.TISHI_BUBBLE = {
|
||
kind: 'attach', targetKind: 'platform', w: 96, h: 44,
|
||
bySeat: {
|
||
LEFT: { target: 'P_LEFT_AVATAR', hAlign: 'right', vAlign: 'middle', offsetX: 10, arrowRight: false },
|
||
RIGHT: { target: 'P_RIGHT_AVATAR', hAlign: 'left', vAlign: 'middle', offsetX: -10, arrowRight: true },
|
||
SELF: { target: 'P_SELF_AVATAR', hAlign: 'right', vAlign: 'top', offsetX: 10, offsetY: -70, arrowRight: false }
|
||
}
|
||
};
|