feat: 新增物理弹球实验室及配套功能
1. 新增物理弹球游戏全套代码,包含物理引擎、规则、渲染、游戏逻辑、存档、音效、UI 2. 新增物理弹球相关调试与单元测试脚本 3. 优化私有剪贴上传功能:增加200MB上传限制与错误提示 4. 修复复古弹球桌的光滑面防粘附与休眠逻辑
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
/* ============================================================
|
||||
* debug_physics_balls_preview_match.js · 物理弹球 · 预览=实际轨迹验证
|
||||
* 清空砖块后以固定角度发射,对比 simulatePath 预览点与真实球位置:
|
||||
* 瞄准折线必须与球实际运动线路一致(误差 < 2px)。
|
||||
* 运行:node dev_test_scripts/debug/debug_physics_balls_preview_match.js
|
||||
* ============================================================ */
|
||||
'use strict';
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const vm = require('vm');
|
||||
|
||||
const LAB = path.join(__dirname, '..', '..', 'public', 'tools', 'thought_lab', 'labs', 'physics_balls');
|
||||
const ctx = {
|
||||
Math,
|
||||
console,
|
||||
PBAudio: { fire() {}, hit() {}, wall() {}, item() {}, breakBlock() {}, over() {}, claim() {} },
|
||||
PBStorage: { getEscape() { return 50; } }
|
||||
};
|
||||
vm.createContext(ctx);
|
||||
for (const f of ['pb_physics.js', 'pb_rules.js', 'pb_game.js', 'pb_render.js']) {
|
||||
vm.runInContext(fs.readFileSync(path.join(LAB, f), 'utf8'), ctx, { filename: f });
|
||||
}
|
||||
|
||||
const G = ctx.PBGame, RD = ctx.PBRender;
|
||||
|
||||
let ok = true;
|
||||
for (const ang of [0, 0.35, -0.6, 1.0]) {
|
||||
const g = G.create();
|
||||
G.startGame(g);
|
||||
g.blocks = []; g.items = []; // 清空砖块,保证对比确定
|
||||
g.aimAngle = ang;
|
||||
|
||||
const pts = RD.simulatePath(g); // 预览点:pts[k] 对应 t = k/60 s(subDt=1/240,每 4 子步采样)
|
||||
|
||||
G.fire(g);
|
||||
let maxErr = 0, checked = 0;
|
||||
for (let f = 1; f <= 30; f++) { // 前 0.5s,每帧 4 子步与预览采样对齐
|
||||
G.update(g, 1 / 60);
|
||||
if (!g.balls.length) break;
|
||||
if (f % 2) continue;
|
||||
if (f >= pts.length) break;
|
||||
const b = g.balls[0];
|
||||
const err = Math.hypot(b.x - pts[f].x, b.y - pts[f].y);
|
||||
maxErr = Math.max(maxErr, err);
|
||||
checked++;
|
||||
}
|
||||
const pass = checked >= 10 && maxErr < 2;
|
||||
console.log((pass ? 'PASS ' : 'FAIL ') + 'angle=' + ang + ' checked=' + checked + ' maxErr=' + maxErr.toFixed(2) + 'px');
|
||||
ok = pass && ok;
|
||||
}
|
||||
|
||||
process.exit(ok ? 0 : 1);
|
||||
Reference in New Issue
Block a user