二七王:回退自造的图集叠绘,改用平台既有 SpriteManager.setNumberImage
方案作废并纠正认知:多帧图片精灵【不是】只能显示一位数——SpriteManager 第 1154 行 早有 setNumberImage(spriteId, text, charWidth):把整串文本设给一个多帧图片精灵, 引擎按字符逐帧渲染,精灵宽度按「字符数 × charWidth」自动调整。bc75e40 造的 drawImageRegion + NumberRenderer 是重复轮子,本次整体回退(revert bc75e40)。 - 回退:删除 gameabc-framework/ui/NumberRenderer.js 与其单测,SpriteManager 与 index.html 恢复到改动前(与 bc75e40^ 逐字节一致)。 - ImageResources.js:数字类资源改为 16 帧、固定帧序 0123456789.+-x/p,逐条写明 各帧含义、第16帧后缀(选主张数=「张」;结算/叫分的后缀标注待美术与规则确认,未瞎填)、 单字符宽高与整图尺寸(16 × 单字宽),并说明帧序不可重排、不可省略占位。 - LayoutConstants.js:NUM_STYLE 改为 setNumberImage 所需的 res/charWidth/charHeight/suffix。 - Layout_Action.js:两个数字节点 h 取 charHeight(SSOT),w 留运行时注入 (宽度由 setNumberImage 按字符数自动改,随位数变)。 - Sprites_Action.js / Sprites_Result.js:注释改为 setNumberImage 用法; 结算玩家栏 ACC_TPL_SCORE_NUM 是复制精灵也能用(该接口不依赖绘制回调)。 - test_constants.js:NUM_STYLE 守卫改为校验 charWidth/charHeight/suffix 与 「h 同源、w 运行时注入」;suffix 限定为 setNumberImage 支持的 分/倍/张。 - 文档:清单 §1.3/§1.5/§3.6/§5.4/§6.8 与前端 02 的那一节全部按 setNumberImage 重写, 三种机制改为「文字精灵 / setFrame 切帧 / setNumberImage」,并记下这次误判作为反例。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -319,30 +319,34 @@ t.eq('roomtype 位号铺满 0-4', Object.keys(bitsSeen).map(Number).sort((a, b)
|
||||
t.eq('CARD_SIZE.' + size + ' 的资源存在', EQW_Images.hasOwnProperty(EQW_Layout.CARD_SIZE[size].res), true);
|
||||
});
|
||||
|
||||
// ---- 数字样式(图集叠绘):资源键存在、字段齐全合法 ----
|
||||
// ---- 多帧图数字样式(配合 SpriteManager.setNumberImage):资源键存在、字段齐全合法 ----
|
||||
// 与 CARD_SIZE 同一约定:纯数据配置只存资源【键名】,调用方用 EQW_Images[res] 取真实 ID
|
||||
const numStyleProblems = [];
|
||||
Object.keys(EQW_Layout.NUM_STYLE).forEach(key => {
|
||||
const s = EQW_Layout.NUM_STYLE[key];
|
||||
if (!EQW_Images.hasOwnProperty(s.res)) { numStyleProblems.push(key + ' 的资源键不存在: ' + s.res); }
|
||||
['charWidth', 'charHeight', 'width'].forEach(f => {
|
||||
// charWidth 是 setNumberImage 的必需入参(该接口对非正数直接返回 false)
|
||||
['charWidth', 'charHeight'].forEach(f => {
|
||||
if (typeof s[f] !== 'number' || s[f] <= 0) { numStyleProblems.push(key + '.' + f + ' 非正数: ' + s[f]); }
|
||||
});
|
||||
if (typeof s.spacing !== 'number') { numStyleProblems.push(key + '.spacing 非数字: ' + s.spacing); }
|
||||
if (['left', 'center', 'right'].indexOf(s.align) < 0) { numStyleProblems.push(key + '.align 非法: ' + s.align); }
|
||||
// 绘制区至少放得下一个字符,否则这套样式一开始就画不出东西
|
||||
if (s.width < s.charWidth) { numStyleProblems.push(key + ' 绘制区比单字还窄'); }
|
||||
// 后缀落在资源第 16 帧,只能是 0 或 1 个字符;且必须是 setNumberImage 认识的那三个
|
||||
// (编码表 /[分倍张]/ → 'g' → 帧16;写别的字会被原样丢给引擎,按未知字符渲染)
|
||||
if (typeof s.suffix !== 'string') { numStyleProblems.push(key + '.suffix 必须是字符串: ' + s.suffix); }
|
||||
else if (s.suffix !== '' && ['分', '倍', '张'].indexOf(s.suffix) < 0) {
|
||||
numStyleProblems.push(key + '.suffix 不是 setNumberImage 支持的后缀(分/倍/张): ' + s.suffix);
|
||||
}
|
||||
});
|
||||
if (numStyleProblems.length) { console.log('数字样式问题:\n ' + numStyleProblems.join('\n ')); }
|
||||
t.eq('NUM_STYLE 资源键存在且字段合法', numStyleProblems, []);
|
||||
|
||||
// 引用 NUM_STYLE 的布局节点必须与样式同源(SSOT:数值只在 LayoutConstants 定义一处,
|
||||
// 有人在 Layout_Action.js 里手抄一个不同的数就在这里变红)
|
||||
// 有人在 Layout_Action.js 里手抄一个不同的数就在这里变红)。
|
||||
// 注意 w 不在此列:setNumberImage 会按【字符数 × charWidth】自动改精灵宽,故 w 由运行时注入
|
||||
[['CALL_BTN_SCORE_TEXT', 'CALL_SCORE'], ['MAIN_SUIT_COUNT', 'MAIN_SUIT_COUNT']].forEach(pair => {
|
||||
const node = EQW_Layout[pair[0]];
|
||||
const st = EQW_Layout.NUM_STYLE[pair[1]];
|
||||
t.eq(pair[0] + '.w 与 NUM_STYLE.' + pair[1] + '.width 同源', node.w, st.width);
|
||||
t.eq(pair[0] + '.h 与 NUM_STYLE.' + pair[1] + '.charHeight 同源', node.h, st.charHeight);
|
||||
t.eq(pair[0] + '.w 留到运行时注入', node.runtime.indexOf('w') >= 0 && typeof node.w === 'undefined', true);
|
||||
});
|
||||
|
||||
process.exit(t.done('constants') ? 0 : 1);
|
||||
|
||||
Reference in New Issue
Block a user