Fill the screen, and let the swish keep up with a late horde
The portrait canvas is adaptive now. A fixed 270x480 is 9:16 while a modern iPhone is taller, so width bound the fit and ~150 CSS px of screen went unused at the bottom. Height is derived from the device aspect, and TUNE.horizon rides with it — proj() places the court in absolute pixels, so leaving horizon fixed just grew a dead green band between the court and the rack instead of moving the court down. RES 3 to 4 for the extra pixels: an iPhone gives ~1125 device px across and we were rendering 810. That is the first knob to turn back down if the phone stutters. The swish cooldown scales with how swarmed you are — 1.00s at one body, 0.47 at four, 0.22 from fourteen. Oliver died on every game-20 horde because the wave grows with hordeGrow while the panic button stayed a flat second; he chose scaling the melee over shrinking the horde. The first version measured the crowd after meleeSwipe had already killed it, so it counted survivors and barely moved. Winning a duel while wounded lost the weapon popup entirely: showModal never clobbers an open modal, so the heal modal opened first and the tin's was dropped. One popup carries both now. And the mop boy stays off the court unless a stain actually passes the test mopRound uses to pick a target. He was walking on, finding nothing reachable, and walking straight off again. Tennis untouched: 50 hits / 0 whiffs. 45-game soak clean, all four chapters. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
49d391dc64
commit
ae64daa0fb
6 files changed
+108
-19
No files matched your search
@@ -1,6 +1,8 @@
|
||||
// All mutable game state in one place, plus the point-reset that re-arms it.
|
||||
|
||||
import { HOME, BOY_ENTER, TUNE } from './config.js';
|
||||
import { HOME, BOY_ENTER, TUNE, COURT } from './config.js';
|
||||
import { gore } from './zombies.js'; // runtime-only cycle (zombies imports state): sendBoy reads gore
|
||||
// to decide whether a mopping round is worth walking out for
|
||||
|
||||
export const P = { x: 1.3, z: 22.8, side: 'P', pose: 'idle', poseT: 0, swingT: -1, facing: 1, runT: 0 };
|
||||
export const O = { x: -1.3, z: 1.0, side: 'O', pose: 'idle', poseT: 0, swingT: -1, facing: 1, runT: 0 };
|
||||
@@ -112,8 +114,14 @@ export function setupPoint() {
|
||||
// fetch a dead ball — or, in splatter, come out to CLEAN: a different sprite sheet and a slower
|
||||
// walk, because mopping is not sprinting. Mopping is the DEFAULT once the gore starts; the plain
|
||||
// running fetch-boy survives for tennis mode, where there is nothing on the grass but a ball.
|
||||
// Is there a stain worth walking out for? Must match mopRound's own target test, or he walks on,
|
||||
// finds nothing he can reach, and walks straight off again — which is exactly what Oliver saw:
|
||||
// "the mopboy sometimes moves over the court without anything to mop".
|
||||
const mopWorthIt = () => gore.some(d => d.a >= 0.15 && d.z >= COURT.netZ - 2);
|
||||
|
||||
export function sendBoy(tx = ball.x, tz = ball.z, mop = G.mode === 'splatter') {
|
||||
if (G.interlude) return; // the sudden-death duel is clean tennis: nobody mops through it
|
||||
if (mop && !mopWorthIt()) return; // no job, no boy
|
||||
if (tz < -3 || tz > 27) return; // target left the field lengthwise, let it go
|
||||
// ONE boy, one slot. Every kill used to call this and teleport him back to the wing mid-stride,
|
||||
// which is why he flickered in and out: a kill streak restarted him several times a second.
|
||||
|
||||
Reference in new issue
Block a user