387a1c26e3
清理已跟踪原始日志与个人本地配置 修复前后端有效门禁、测试和构建问题 补齐生产 Jenkins、SpacetimeDB 本地命令与文档约束 收紧图片编辑器状态、附件与媒体引用测试 排除已下线旧创作入口测试并清理 warning
125 lines
3.2 KiB
TypeScript
125 lines
3.2 KiB
TypeScript
import { expect, test } from 'vitest';
|
|
|
|
import type { Match3DRunSnapshot } from '../../../packages/shared/src/contracts/match3dRuntime';
|
|
import {
|
|
findMatch3DHitItem,
|
|
isPointInsideMatch3DItemAlphaHotspot,
|
|
type Match3DResolvedImageSourceEntry,
|
|
resolveMatch3DItemSizeScale,
|
|
} from './match3dHotspot';
|
|
import { resolveRenderableItemFrame } from './match3dRuntimePresentation';
|
|
|
|
function buildMatch3DHotspotRun(): Match3DRunSnapshot {
|
|
return {
|
|
runId: 'hotspot-run',
|
|
profileId: 'hotspot-profile',
|
|
status: 'Running',
|
|
snapshotVersion: 1,
|
|
startedAtMs: 1,
|
|
durationLimitMs: 600_000,
|
|
remainingMs: 600_000,
|
|
clearCount: 1,
|
|
totalItemCount: 1,
|
|
clearedItemCount: 0,
|
|
traySlots: Array.from({ length: 7 }, (_, slotIndex) => ({ slotIndex })),
|
|
items: [
|
|
{
|
|
clickable: true,
|
|
itemInstanceId: 'alpha-hotspot-item',
|
|
itemTypeId: 'match3d-type-01',
|
|
visualKey: 'block-red-2x2',
|
|
x: 0.5,
|
|
y: 0.5,
|
|
radius: 0.1,
|
|
layer: 1,
|
|
state: 'InBoard',
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
test('透明像素不作为抓大鹅物品点击热区', () => {
|
|
const run = buildMatch3DHotspotRun();
|
|
const item = run.items[0]!;
|
|
const mask = {
|
|
width: 4,
|
|
height: 4,
|
|
alpha: new Uint8ClampedArray([
|
|
0, 0, 0, 0,
|
|
0, 255, 255, 0,
|
|
0, 255, 255, 0,
|
|
0, 0, 0, 0,
|
|
]),
|
|
};
|
|
const imageSourceEntriesByType = new Map<string, Match3DResolvedImageSourceEntry[]>([
|
|
[
|
|
'match3d-type-01',
|
|
[
|
|
{
|
|
source: '/generated-match3d-assets/item-01.png',
|
|
resolvedSource: 'https://oss.example.com/item-01.png',
|
|
},
|
|
],
|
|
],
|
|
]);
|
|
const alphaHitMasks = new Map([
|
|
['/generated-match3d-assets/item-01.png', mask],
|
|
]);
|
|
const itemSizeByType = new Map([['match3d-type-01', '大' as const]]);
|
|
const frame = resolveRenderableItemFrame(item);
|
|
|
|
expect(
|
|
findMatch3DHitItem(run, frame.x - frame.radius * 0.6, 0.5, {
|
|
alphaHitMasks,
|
|
imageSourceEntriesByType,
|
|
itemSizeByType,
|
|
}),
|
|
).toBeUndefined();
|
|
expect(
|
|
findMatch3DHitItem(run, 0.5, 0.5, {
|
|
alphaHitMasks,
|
|
imageSourceEntriesByType,
|
|
itemSizeByType,
|
|
})?.itemInstanceId,
|
|
).toBe('alpha-hotspot-item');
|
|
});
|
|
|
|
test('小尺寸物品只在缩放后的非透明主体内命中', () => {
|
|
const item = buildMatch3DHotspotRun().items[0]!;
|
|
const mask = {
|
|
width: 2,
|
|
height: 2,
|
|
alpha: new Uint8ClampedArray([255, 255, 255, 255]),
|
|
};
|
|
|
|
expect(
|
|
isPointInsideMatch3DItemAlphaHotspot({
|
|
item,
|
|
pointX: 0.5,
|
|
pointY: 0.5,
|
|
mask,
|
|
itemSize: '小',
|
|
}),
|
|
).toBe(true);
|
|
expect(
|
|
isPointInsideMatch3DItemAlphaHotspot({
|
|
item,
|
|
pointX: 0.38,
|
|
pointY: 0.5,
|
|
mask,
|
|
itemSize: '小',
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
test('抓大鹅生成物品大和中也会做一定程度缩小', () => {
|
|
expect(resolveMatch3DItemSizeScale('大')).toBeLessThan(1);
|
|
expect(resolveMatch3DItemSizeScale('中')).toBeLessThan(0.78);
|
|
expect(resolveMatch3DItemSizeScale('大')).toBeGreaterThan(
|
|
resolveMatch3DItemSizeScale('中'),
|
|
);
|
|
expect(resolveMatch3DItemSizeScale('中')).toBeGreaterThan(
|
|
resolveMatch3DItemSizeScale('小'),
|
|
);
|
|
});
|