55 lines
2.2 KiB
JavaScript
55 lines
2.2 KiB
JavaScript
// 用真实引擎(Player/Level)测量跳跃水平距离,核对求解器的物理近似是否可信
|
|
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 { Level } = await import('../js/level.js');
|
|
const { Player } = await import('../js/player.js');
|
|
const { Input } = await import('../js/input.js');
|
|
|
|
// 一块 40 格长的平地,右端断开
|
|
const flat = {
|
|
id: 'test', name: 'T', type: 'jump', width: 44,
|
|
grid: (() => {
|
|
const rows = [];
|
|
rows.push('#'.repeat(44));
|
|
for (let i = 0; i < 16; i++) rows.push('#' + '.'.repeat(42) + '#');
|
|
rows.push('#' + '#'.repeat(42) + '#'); // 整条实心平台
|
|
rows.push('#'.repeat(44));
|
|
return rows;
|
|
})(),
|
|
};
|
|
|
|
function measure(djFrame) {
|
|
const L = new Level(flat);
|
|
const P = new Player(L);
|
|
P.x = 8 * 32; P.y = 16 * 32 - P.h; // 站在 row17 平台上(平台行 17)
|
|
P.vx = 0; P.vy = 0; P.grounded = true; P.jumps = 0;
|
|
const x0 = P.x;
|
|
key('keydown', 'ArrowRight');
|
|
key('keydown', 'ShiftLeft');
|
|
let f = 0, landed = -1, released = false;
|
|
for (let i = 0; i < 200; i++) {
|
|
f++;
|
|
// 二段跳需要先松开再按下(跨帧),否则不算一次新的按下
|
|
if (djFrame && f === djFrame) { key('keyup', 'ShiftLeft'); released = true; }
|
|
if (released && f === djFrame + 1) { key('keydown', 'ShiftLeft'); released = false; }
|
|
L.update(1, P, null);
|
|
P.update(1);
|
|
Input.endFrame();
|
|
if (i > 2 && P.grounded) { landed = P.x; break; }
|
|
if (P.dead) break;
|
|
}
|
|
key('keyup', 'ArrowRight'); key('keyup', 'ShiftLeft');
|
|
Input.endFrame();
|
|
return { dist: landed >= 0 ? landed - x0 : null, f };
|
|
}
|
|
|
|
console.log('真实引擎跳跃水平距离(起跳点 x 到落点 x,单位 px / 格)');
|
|
for (const dj of [0, 6, 12, 18, 24, 30]) {
|
|
const r = measure(dj);
|
|
console.log(` 二段跳时机=${String(dj).padStart(2)} 帧 -> ${r.dist === null ? '未落地' : r.dist.toFixed(1) + 'px = ' + (r.dist / 32).toFixed(2) + ' 格 (' + r.f + ' 帧)'}`);
|
|
}
|