// 机器人试玩:真实物理下向右推进,看存档点是否会被自然触发 const handlers = {}; const addL = (t, fn) => { (handlers[t] = handlers[t] || []).push(fn); }; globalThis.addEventListener = addL; globalThis.window = { addEventListener: addL }; const key = (t, c) => (handlers[t] || []).forEach(fn => fn({ code: c, preventDefault() { }, repeat: false })); const down = c => key('keydown', c); const up = c => key('keyup', c); const { LEVELS } = await import('../js/levels/index.js'); const { Level } = await import('../js/level.js'); const { Player } = await import('../js/player.js'); const { Input } = await import('../js/input.js'); const id = process.argv[2] || 'j1'; const d = LEVELS.find(l => l.id === id); const L = new Level(d); const P = new Player(L); let deaths = 0; P.onDeath = () => deaths++; down('ArrowRight'); let jumpPhase = 0; for (let i = 0; i < 3000; i++) { // 简易 AI:遇到前方障碍/刺就跳,滞空一会儿再补二段跳 const ahead = L.solidRect(P.x + 3, P.y, P.w, P.h) || L.deadlyRect(P.x + 20, P.y + P.h - 6, 12, 8); const gap = !L.solidRect(P.x + 6, P.y + P.h + 2, P.w, 4); if (P.grounded && (ahead || gap)) { down('ShiftLeft'); jumpPhase = i; } if (!P.grounded && i - jumpPhase === 12) { up('ShiftLeft'); down('ShiftLeft'); } if (i - jumpPhase === 30) up('ShiftLeft'); L.update(1, P, null); for (const b of L.bosses) b.update(1, P); P.update(1); Input.endFrame(); if (P.savePoint) break; } const saves = L.entities.filter(e => e.type === 'save'); console.log(`${id}: 存档点 ${saves.filter(s => s.active).length}/${saves.length} 被激活, x=${P.x.toFixed(0)}, 死亡=${deaths}`); saves.forEach(s => console.log(` (${s.tx},${s.ty}) active=${s.active}`)); console.log(` savePoint=${P.savePoint ? `(${P.savePoint.x.toFixed(0)},${P.savePoint.y.toFixed(0)})` : 'null'} spawn=(${L.spawn.x},${L.spawn.y})`);