Fold the menu into the title screen, and stop the theme restarting

The menu stage was the same logo on the same backdrop with two buttons, so it
read as the title screen failing to advance. The buttons move onto the title
screen in place of the control list, which is the tutorial's job now.

Death no longer reloads the page. The reload was an honest full reset, but it
also tore down the AudioContext — so the theme restarted from silence every
time you died, when it should carry straight on from the death summary into the
title screen. restartRun() puts G, P, O, ball and score back from a
structuredClone taken at module load (all plain data, so the clone is the whole
job and a field added later is covered for free), and the two modules with
timers of their own reset themselves: every zombies array plus spawnT/moanT/
mgTick, and input's held keys and half-finished drags, which would otherwise be
inherited by the next run's first frame.

The overlay is hidden rather than removed so it can come straight back, which
needs its own [hidden] rule to beat the display:grid on #intro.

The theme starts on the first tap and never restarts: loopBed's beds.has guard
already makes every later menuMusic() a no-op.

Verified: one background-music fetch across launch -> run -> death -> title ->
second run, and a full second run through the transition after the in-place
reset.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-01 16:25:20 +02:00
1 parent 2d4fa79258
commit d3aabc4bd6
7 files changed
+114 -74

No files matched your search

+9
View File
@@ -54,6 +54,15 @@ const canAimServe = () =>
let steerPX = null; // live absolute finger x (-1..1 across the canvas) — machine-gun steering reads it
export const touchPX = () => steerPX;
// Restarting a run no longer reloads the page (see state.resetState), so this module's own state has
// to be put back by hand: a key still held, or a half-finished drag, would otherwise be inherited by
// the next run's very first frame.
export function resetInput() {
for (const k in keys) delete keys[k];
touchAxis.x = touchAxis.z = 0;
stick = flickAim = steerPX = null;
}
cv.addEventListener('touchstart', e => {
e.preventDefault(); audio();
const r = cv.getBoundingClientRect();