Hide the racket, and light the beam all the way to its edge
The mg racket is gone, not moved. It was a procedural racket drawn over a sprite that already holds one: straight up-court it projected onto the player's back as a floating oval, and offset to the side it just stuck out. The laser's far edge was pinned to the middle of the ad strip two commits ago and nothing appeared to change, twice. The geometry was always right -- each wedge layer faded to alpha 0 along its length, so the beam went invisible before it reached its own far corners and the VISIBLE end sat well short of the pinned one. The far stop is lit now, so the two are the same line. Verified by recomputing the projection: far corners at y 113.8, the ads' middle, against 110.2 unpinned. It also falls off with distance now, brightest at the strings and thinning down the court -- but never to zero, which is the trap above. Fixes a third instance of the empties-under-the-iterator bug: a rocket blast can bank the last kill of a game, and the duel or chapter boss that follows clears pellets[] mid-loop. shots, pellets, extras and the body loop all carry the guard. Also records that two consecutive render() calls do not produce the same frame -- render mutates camera smoothing as a side effect -- so frame-diffing to find where something was drawn measures the camera drift instead. It claimed the beam reached 16 px above where its own geometry could go. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6e88fd5bb9
commit
da9cca2f23
4 files changed
+48
-24
No files matched your search
@@ -961,6 +961,10 @@ export function updateZombies(dt) {
|
||||
|
||||
for (let i = pellets.length - 1; i >= 0; i--) { // gun rounds flat and fast; lobbed ones ride an arc
|
||||
const pe = pellets[i];
|
||||
// A rocket blast can bank the last kill of a game, and the beat that follows (a duel, a chapter
|
||||
// boss) empties this array — so every remaining index reads undefined and the frame throws. Same
|
||||
// guard, and the same reason, as the one in the shots loop and the body loop.
|
||||
if (!pe) continue;
|
||||
pe.t -= dt; pe.x += pe.vx * dt; pe.z += pe.vz * dt;
|
||||
let hit = false, landed = false;
|
||||
if (pe.arc) { // a thrown round: it falls, and landing is a hit
|
||||
@@ -1062,6 +1066,7 @@ export function updateZombies(dt) {
|
||||
|
||||
for (let i = extras.length - 1; i >= 0; i--) { // triple-serve side balls: full ballistic clones
|
||||
const e = extras[i];
|
||||
if (!e) continue; // same as pellets/shots: a kill here can start a beat that empties the array
|
||||
e.t -= dt; e.vy -= (e.g || TUNE.gravity) * dt; // e.g: a clone flies under the SAME topspin as the ball it came from
|
||||
e.x += e.vx * dt; e.y += e.vy * dt; e.z += e.vz * dt;
|
||||
if (e.y <= 0 && e.vy < 0) { e.y = 0; e.vy = -e.vy * TUNE.bounceY; e.vx *= TUNE.bounceXZ; e.vz *= TUNE.bounceXZ; }
|
||||
|
||||
Reference in new issue
Block a user