first commmit

This commit is contained in:
jakciehan
2026-05-06 08:17:32 +08:00
commit 427a33c55b
269 changed files with 20906 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
import { ConfigMgr, MapJsonLoader } from '@data/ConfigMgr';
import { LevelMgr } from '@logic/LevelMgr';
import { cameraFromLevel } from '@logic/CameraScroller';
import { EnemyType } from '@data/Interfaces';
// Reuse delivered JSON.
import enemies from '../../assets/resources/configs/enemies.json';
import items from '../../assets/resources/configs/items.json';
import weapons from '../../assets/resources/configs/weapons.json';
import levels from '../../assets/resources/configs/levels.json';
import bosses from '../../assets/resources/configs/bosses.json';
import stories from '../../assets/resources/configs/stories.json';
async function loadBundle() {
const mgr = new ConfigMgr(
new MapJsonLoader({
'configs/enemies': enemies,
'configs/items': items,
'configs/weapons': weapons,
'configs/levels': levels,
'configs/bosses': bosses,
'configs/stories': stories,
})
);
await mgr.load();
return mgr;
}
describe('Chapter-1 levels — JSON × LevelMgr integration (task 7.2)', () => {
it('exposes all 5 levels (1-1 … 1-5)', async () => {
const mgr = await loadBundle();
for (const id of ['1-1', '1-2', '1-3', '1-4', '1-5']) {
expect(mgr.level(id)).toBeDefined();
}
});
it('1-1 requires killing 3 妖坊 within 75s (req 8.1)', async () => {
const mgr = await loadBundle();
const lv = mgr.level('1-1');
expect(lv.timeLimitSec).toBe(75);
expect(lv.objective).toEqual({ kind: 'kill_count', enemy: EnemyType.YaoFang, count: 3 });
});
it('1-3 is a bi-directional cave stage with 10 青忍 objective (req 8.3)', async () => {
const mgr = await loadBundle();
const lv = mgr.level('1-3');
expect(lv.scrollDirection).toBe('horizontal_bi');
expect(lv.objective).toEqual({ kind: 'kill_count', enemy: EnemyType.QingRen, count: 10 });
});
it('1-4 is a vertical castle-wall stage with reach_top objective (req 8.4)', async () => {
const mgr = await loadBundle();
const lv = mgr.level('1-4');
expect(lv.scrollDirection).toBe('vertical');
expect(lv.objective).toEqual({ kind: 'reach_top' });
});
it('1-5 is a defeat-boss objective pointing at 双幻坊 (req 8.5)', async () => {
const mgr = await loadBundle();
const lv = mgr.level('1-5');
expect(lv.objective.kind).toBe('defeat_boss');
expect(lv.objective.bossId).toBe('shuang_huan_fang');
});
it('CameraScroller instantiates cleanly from each chapter-1 level', async () => {
const mgr = await loadBundle();
for (const id of ['1-1', '1-2', '1-3', '1-4', '1-5']) {
const cam = cameraFromLevel(mgr.level(id));
expect(cam.offsetX).toBe(0);
expect(cam.offsetY).toBe(0);
}
});
it('LevelMgr drives every level to victory via its configured objective', async () => {
const mgr = await loadBundle();
for (const id of ['1-1', '1-2', '1-3', '1-4', '1-5']) {
const lv = new LevelMgr(mgr.level(id));
switch (lv.level.objective.kind) {
case 'kill_count':
for (let k = 0; k < (lv.level.objective.count ?? 0); k++) {
lv.onEnemyKilled(lv.level.objective.enemy!);
}
break;
case 'reach_top':
lv.onReachedTop();
break;
case 'defeat_boss':
lv.onBossKilled();
break;
}
expect(lv.tick(0.016)).toBe('victory');
}
});
});