问题:frameFileName 只校验下界(frameIndex > 0),未校验上界(frameIndex <= frameCount)。
结果:会安静产出指向不存在文件的名字(如 frameFileName('00014.png', 999, 12) → '00014_999.png'),
一路流进中间描述,直到 Cocos 加载资源才报错。
这是「把读不出来当成没问题」这一形态的第四次出现:
- Task 2: readPngSize 返回 null 被当成校验通过
- 前期: ??: 缺顶层键当成空集合
- 前轮: frameIndex 任何 falsy 当成帧 1
- 本轮: frameFileName 超界当成合法产出垃圾名字
修法:加上界检查 `normalized > frameCount`,错误信息对齐 frameRect 格式。
新增 1 条测试用例:frameFileName('00014.png', 13, 12) 应抛错。
顺手补齐 frameFileName 的 undefined/NaN 测试的消息断言(与 frameRect 对齐)。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
47 lines
1.7 KiB
JavaScript
47 lines
1.7 KiB
JavaScript
/**
|
||
* 帧矩形与命名。见 spec §0.3、§3。
|
||
* 帧号 1 基、行优先——已由读取 00014.png 的网格内容与 11 个按钮的 FrameIndex 对照实证。
|
||
*/
|
||
|
||
/** 帧号 → 源矩形。FrameIndex=0 按帧 1 处理(实测仅 2 个对象如此)。 */
|
||
export function frameRect(image, frameIndex) {
|
||
const normalized = frameIndex === 0 ? 1 : frameIndex;
|
||
const idx = normalized - 1;
|
||
if (!Number.isInteger(idx) || idx < 0 || idx >= image.frame_all) {
|
||
throw new RangeError(
|
||
`帧号非法或越界: ${image.bmp} frameIndex=${frameIndex}(有效范围 1..${image.frame_all},0 视同 1)`,
|
||
);
|
||
}
|
||
return {
|
||
x: (idx % image.w) * image.w1,
|
||
y: Math.floor(idx / image.w) * image.h1,
|
||
width: image.w1,
|
||
height: image.h1,
|
||
};
|
||
}
|
||
|
||
/** 补零位数:保证字典序 = 帧序。 */
|
||
export function padWidth(frameCount) {
|
||
return String(frameCount).length;
|
||
}
|
||
|
||
/** 00014.png + 帧 5/共 12 → 00014_05.png;单帧图原样返回。 */
|
||
export function frameFileName(bmp, frameIndex, frameCount) {
|
||
if (frameCount <= 1) return bmp;
|
||
const normalized = frameIndex === 0 ? 1 : frameIndex;
|
||
if (!Number.isInteger(normalized) || normalized <= 0 || normalized > frameCount) {
|
||
throw new RangeError(
|
||
`帧号非法或越界: ${bmp} frameIndex=${frameIndex}(有效范围 1..${frameCount},0 视同 1)`,
|
||
);
|
||
}
|
||
const base = bmp.replace(/\.png$/i, '');
|
||
const n = String(normalized).padStart(padWidth(frameCount), '0');
|
||
return `${base}_${n}.png`;
|
||
}
|
||
|
||
/** 该图全部帧的文件名,下标 0 对应帧 1。 */
|
||
export function frameNames(image) {
|
||
return Array.from({ length: image.frame_all }, (_, i) =>
|
||
frameFileName(image.bmp, i + 1, image.frame_all));
|
||
}
|