Clear the frame to the apron colour

That band at the bottom was not a background mismatch — the canvas was
transparent there. render() never cleared: the stands cover the top and the
out-area quad covers the middle, so it looked complete, but the quad only
reached z=30 and everything below where that projects was see-through. The
page showed through it, which is why it read as a slightly duller green.

The frame is now cleared to pal.out before anything draws, oversized by 8px so
a camera shake cannot expose an edge, and the out-area quad runs to z=60 so the
perspective floor reaches the bottom on any aspect. Verified by sampling alpha
down the bottom third: opaque everywhere, one uniform colour, matching the page
gradient behind it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-07-30 19:22:23 +02:00
1 parent 7b15e10494
commit c9699da6f1
3 files changed
+17 -4

No files matched your search

+9 -3
View File
@@ -129,7 +129,7 @@ export function proj(x, y, z) {
// ---------------------------------------------------------------- sprites ----
// assets/<name>.png; game falls back to code-drawn figures until sprites load.
const SPRV = 48; // asset cache-buster — bump with main.js?v=N (see the img.src note below)
const SPRV = 49; // asset cache-buster — bump with main.js?v=N (see the img.src note below)
const SPR = {};
for (const n of ['p_idle1','p_idle2','p_bounce','p_bounce2','p_toss','p_smash','p_run1','p_run2','p_swing1','p_swing2',
'o_idle1','o_idle2','o_bounce','o_bounce2','o_toss','o_smash','o_run1','o_run2','o_swing1','o_swing2',
@@ -611,7 +611,13 @@ export function render() {
}
const pal = palette(), pt = paletteT();
pageBackground(pal.out); // keep the page behind the canvas matching the court's apron
// CLEAR THE WHOLE FRAME to the apron colour first. There was no clear at all: the stands cover the
// top and the out-area quad covers the middle, but the quad only reaches z=30, and below where that
// projects the canvas was simply TRANSPARENT — you saw the page through it as a duller band across
// the bottom of the screen. Oversized by 8px so a camera shake can never expose an edge.
ctx.fillStyle = pal.out;
ctx.fillRect(-8, -8, W + 16, H + 16);
pageBackground(pal.out); // ...and the page behind it matches, for the rounded display corners
// stands: the generated crowd, drawn in columns so it can BOUNCE when it cheers.
// sit the ad strip flush on the court's back edge (the out-area quad below reaches z=-6);
// pinning to that projected line keeps the boards clear of the lawn in BOTH orientations
@@ -656,7 +662,7 @@ export function render() {
// ground + court (Super Tennis lawn); everything outside the doubles court is OUT
const dw = COURT.dblW / 2;
quadXZ(-14, -6, 14, 30, pal.out); // out area
quadXZ(-14, -6, 14, 60, pal.out); // out area (past the bottom on any aspect)
quadXZ(-dw - 0.15, -0.15, dw + 0.15, COURT.L + 0.15, '#e8e8dc'); // perimeter border line
quadXZ(-dw, 0, dw, COURT.L, pal.lawn); // lawn (doubles court)
for (let z = 0; z < COURT.L; z += 2.97) quadXZ(-dw, z, dw, Math.min(z + 1.49, COURT.L), pal.stripe); // mow stripes