Files
erqiwang_youle/client/tests/test_spriteindex.js
T
joywayerandClaude Opus 5 2fe0f661b4 二七王:数字改回「一个数字一个精灵」,数字资源改为等宽连续图
有了图集叠绘能力,多位数不再需要每位一个精灵:

- Sprites_Action.js:选主花色张数从每花色两个(_TENS/_ONES)改回每花色一个
  (MAIN_SUIT_COUNT_1..4 = 1674–1677),空出的 1678–1681 按本文件既有写法记跳号、不复用;
  叫分档位 CALL_BTN_NUM_1..14 数量不变,注释改为图集叠绘(现在能正确显示两位数)。
- ImageResources.js:NUM_COUNTDOWN / NUM_RESULT_WIN / NUM_RESULT_LOSE / NUM_CALL_SCORE /
  NUM_MAIN_SUIT_COUNT 不再是编辑器配帧的多帧资源,改为等宽连续排列的一张图,
  逐条写明字符排列顺序、单字符宽高、整图尺寸(给美术的出图规格)。
- Layout_Action.js:张数的十位/个位两节点合并为一个;两个数字节点的 w/h 直接引用
  NUM_STYLE(SSOT),不再由调用方运行时注入。
- Sprites_Result.js:记下 ACC_TPL_SCORE_NUM 是复制精灵、无法用 NumberRenderer 的风险。
- 单测:精灵总数 382→378、布局节点 62→61(按实际更新,未放宽下界);
  新增 NUM_STYLE 资源键/字段合法性与「布局节点 w/h 与样式同源」守卫。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 23:53:16 +08:00

89 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// View → group → 精灵 的常量树 → 扁平键名索引
const { load, throws } = require('./_load');
const t = require('./_assert')();
load('client/js/01_SubGame/codes/core/SpriteIndex.js');
// ---- 展平:Layer 与 group 的 id 都不进索引,精灵进 ----
const tree = {
TopInfoView: {
Layer: 101,
TopInfo: { id: 201, BTN_A: 1001, BTN_B: 1002 }
},
PlayerMarkView: {
Layer: 101,
LeftMark: { id: 202, P_LEFT_BANKER: 1100 },
RightMark: { id: 203, P_RIGHT_BANKER: 1110 }
}
};
t.eq('展平结果', EQW_SpriteIndex.build(tree),
{ BTN_A: 1001, BTN_B: 1002, P_LEFT_BANKER: 1100, P_RIGHT_BANKER: 1110 });
// ---- Layer 与 group 的 id 不进索引 ----
const flat = EQW_SpriteIndex.build(tree);
t.eq('Layer 不进索引', flat.Layer, undefined);
t.eq('group 的 id 不进索引', flat.id, undefined);
// ---- 群组映射:精灵 → 它所属的群组 ID ----
t.eq('群组映射', EQW_SpriteIndex.buildGroupMap(tree),
{ BTN_A: 201, BTN_B: 201, P_LEFT_BANKER: 202, P_RIGHT_BANKER: 203 });
// ---- 反面:一个 View 恰好一个 Layer;Layer1/Layer2 这种多图层写法要报错 ----
// (跨图层的界面应拆成两个 View,各带自己的 Layer——一个 View 将来对应一个 BaseComponent)
const multiLayer = {
OverlayView: { Layer1: 104, Layer2: 105, Bar: { id: 230, TIP_BG: 1750 } }
};
t.eq('多 Layer 写法报错', throws(() => EQW_SpriteIndex.build(multiLayer)), true);
// ---- 反面:View 缺 Layer 声明要报错 ----
const noLayer = { ViewA: { G1: { id: 201, BTN: 1001 } } };
t.eq('View 缺 Layer 报错', throws(() => EQW_SpriteIndex.build(noLayer)), true);
// ---- 反面:重复键报错,不静默覆盖 ----
const dupTree = {
ViewA: { Layer: 101, G1: { id: 201, SAME: 1001 } },
ViewB: { Layer: 102, G2: { id: 202, SAME: 1002 } }
};
t.eq('重复键报错', throws(() => EQW_SpriteIndex.build(dupTree)), true);
// ---- 反面:精灵值不是数字要报错 ----
const badValue = { ViewA: { Layer: 101, G1: { id: 201, NESTED: { x: 1 } } } };
t.eq('精灵值非数字报错', throws(() => EQW_SpriteIndex.build(badValue)), true);
// ---- 反面:View 下混入标量键(不是 group 容器)要报错 ----
// 例如把群组 ID 误写成 View 级的 `Group: 201`,而不是包进 group 容器
const strayScalar = { ViewA: { Layer: 101, Group: 201, G1: { id: 202, BTN: 1001 } } };
t.eq('View 下混入标量键报错', throws(() => EQW_SpriteIndex.build(strayScalar)), true);
// ---- 反面:group 容器缺 id 要报错 ----
const noGroupId = { ViewA: { Layer: 101, G1: { BTN: 1001 } } };
t.eq('group 缺 id 报错', throws(() => EQW_SpriteIndex.build(noGroupId)), true);
// ---- idOf / groupIdOf:查得到 / 查不到抛错 ----
EQW_SpriteIndex.init(tree);
t.eq('idOf 查到', EQW_SpriteIndex.idOf('BTN_A'), 1001);
t.eq('groupIdOf 查到', EQW_SpriteIndex.groupIdOf('P_RIGHT_BANKER'), 203);
t.eq('idOf 查不到抛错', throws(() => EQW_SpriteIndex.idOf('NOT_EXIST')), true);
t.eq('groupIdOf 查不到抛错', throws(() => EQW_SpriteIndex.groupIdOf('NOT_EXIST')), true);
// ---- 空树 ----
t.eq('空树', EQW_SpriteIndex.build({}), {});
// ---- 真实常量:EQW_Sprites 能完整建索引且无重复键 ----
load('client/js/01_SubGame/codes/config/Layers.js');
load('client/js/01_SubGame/codes/config/Groups.js');
load('client/js/01_SubGame/codes/config/Sprites_Table.js');
load('client/js/01_SubGame/codes/config/Sprites_Cards.js');
load('client/js/01_SubGame/codes/config/Sprites_Action.js');
load('client/js/01_SubGame/codes/config/Sprites_Result.js');
load('client/js/01_SubGame/codes/config/Sprites_CreateRoom.js');
let realOk = true;
let realIndex = {};
try { realIndex = EQW_SpriteIndex.build(EQW_Sprites); } catch (e) { realOk = false; console.log('建索引失败: ' + e.message); }
t.eq('真实精灵常量无重复键', realOk, true);
// 钉住精确数量(与 test_constants.js 同一个数):松下界删掉整个 View 都还能通过
t.eq('真实精灵数量', Object.keys(realIndex).length, 378);
process.exit(t.done('spriteindex') ? 0 : 1);