Extract beforeUpdate steps

This commit is contained in:
Daddy32
2025-12-15 21:31:42 +01:00
parent 7802f66b52
commit c5c4c25d61

View File

@@ -636,6 +636,83 @@
rebuildSceneBodies(); rebuildSceneBodies();
}; };
const runSceneBeforeUpdateHook = () => {
if (
state.levelWon ||
typeof currentScene?.config?.onBeforeUpdate !== "function"
) {
return;
}
currentScene.config.onBeforeUpdate({
engine,
width: state.width,
height: state.height,
});
};
const stepRopeConstraints = () => {
chain.constraints.forEach((c) => {
if (!c.plugin || !c.plugin.rope) return;
const current = Vector.magnitude(
Vector.sub(c.bodyA.position, c.bodyB.position),
);
const maxLen = c.plugin.maxLength ?? c.length;
if (current <= maxLen) {
c.length = current;
c.stiffness = 0;
} else {
c.length = maxLen;
c.stiffness = c.plugin.baseStiffness ?? c.stiffness;
}
});
};
const stepRotators = (dt, timeScale) => {
state.rotators.forEach((b) => {
const speed = b.plugin.rotSpeed || 0;
if (speed !== 0) {
Body.rotate(b, speed * ((dt * timeScale) / 1000));
}
});
};
const stepOscillators = () => {
state.oscillators.forEach((b) => {
const osc = b.plugin.oscillate;
if (!osc) return;
if (!osc.base) {
osc.base = { x: b.position.x, y: b.position.y };
}
const now = (engine.timing.timestamp || 0) / 1000;
const amplitude = osc.amplitude ?? 0;
const speed = osc.speed ?? 1;
const phase = osc.phase ?? 0;
const offset = Math.sin(now * speed + phase) * amplitude;
const target =
osc.axis === "x"
? { x: osc.base.x + offset, y: osc.base.y }
: { x: osc.base.x, y: osc.base.y + offset };
Body.setPosition(b, target);
Body.setVelocity(b, { x: 0, y: 0 });
});
};
const stepTimer = () => {
if (!state.timerEndMs) return;
const winCond = currentScene?.config?.winCondition;
const duration = winCond?.durationSec ?? 120;
const now = Date.now();
const remainingMs = Math.max(0, state.timerEndMs - now);
const remainingSec = Math.ceil(remainingMs / 1000);
if (state.lastTimerDisplay !== remainingSec) {
state.lastTimerDisplay = remainingSec;
updateHud();
}
if (remainingMs <= 0 && !state.levelWon) {
checkWinCondition();
}
};
Events.on(engine, "afterUpdate", () => { Events.on(engine, "afterUpdate", () => {
// Keep stray balls within the play area horizontally. // Keep stray balls within the play area horizontally.
state.balls.forEach((ball) => { state.balls.forEach((ball) => {
@@ -674,72 +751,15 @@
Events.on(engine, "beforeUpdate", () => { Events.on(engine, "beforeUpdate", () => {
// Rope-like constraint handling: allow shortening without push-back, tension when stretched. // Rope-like constraint handling: allow shortening without push-back, tension when stretched.
if ( runSceneBeforeUpdateHook();
!state.levelWon && stepRopeConstraints();
typeof currentScene?.config?.onBeforeUpdate === "function"
) {
currentScene.config.onBeforeUpdate({
engine,
width: state.width,
height: state.height,
});
}
chain.constraints.forEach((c) => {
if (!c.plugin || !c.plugin.rope) return;
const current = Vector.magnitude(
Vector.sub(c.bodyA.position, c.bodyB.position),
);
const maxLen = c.plugin.maxLength ?? c.length;
if (current <= maxLen) {
c.length = current;
c.stiffness = 0;
} else {
c.length = maxLen;
c.stiffness = c.plugin.baseStiffness ?? c.stiffness;
}
});
// Rotate any scene rotators slowly.
const dt = (engine.timing && engine.timing.delta) || 16; const dt = (engine.timing && engine.timing.delta) || 16;
const timeScale = engine.timing?.timeScale ?? 1; const timeScale = engine.timing?.timeScale ?? 1;
if (state.paused || state.gameOver || timeScale === 0) return; if (state.paused || state.gameOver || timeScale === 0) return;
state.rotators.forEach((b) => { // Rotate any scene rotators slowly.
const speed = b.plugin.rotSpeed || 0; stepRotators(dt, timeScale);
if (speed !== 0) { stepOscillators();
Body.rotate(b, speed * ((dt * timeScale) / 1000)); stepTimer();
}
});
state.oscillators.forEach((b) => {
const osc = b.plugin.oscillate;
if (!osc) return;
if (!osc.base) {
osc.base = { x: b.position.x, y: b.position.y };
}
const now = (engine.timing.timestamp || 0) / 1000;
const amplitude = osc.amplitude ?? 0;
const speed = osc.speed ?? 1;
const phase = osc.phase ?? 0;
const offset = Math.sin(now * speed + phase) * amplitude;
const target =
osc.axis === "x"
? { x: osc.base.x + offset, y: osc.base.y }
: { x: osc.base.x, y: osc.base.y + offset };
Body.setPosition(b, target);
Body.setVelocity(b, { x: 0, y: 0 });
});
if (state.timerEndMs) {
const winCond = currentScene?.config?.winCondition;
const duration = winCond?.durationSec ?? 120;
const now = Date.now();
const remainingMs = Math.max(0, state.timerEndMs - now);
const remainingSec = Math.ceil(remainingMs / 1000);
if (state.lastTimerDisplay !== remainingSec) {
state.lastTimerDisplay = remainingSec;
updateHud();
}
if (remainingMs <= 0 && !state.levelWon) {
checkWinCondition();
}
}
}); });
Events.on(render, "afterRender", () => { Events.on(render, "afterRender", () => {