The leagues, phase 2: five bands, pace tiers, locked courts, the members' ground, the promotion ceremony
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9133c0d351
commit
16bf5b9fed
12 files changed
+406
-71
No files matched your search
+17
-7
@@ -1,7 +1,7 @@
|
||||
// Camera, viewport, sprites and all drawing. Owns the crowd dots (visual-only state).
|
||||
|
||||
import { cv, ctx } from './dom.js';
|
||||
import { BENCH, BENCH_STAGES, ZFAMS, famFrames, racketStage, TUNE, UI, EATEN_BURST, EATEN_SUMMARY, EATEN_RESTART, DONE_RESTART, COURT, P_BOUNDS, PLAYER_H, BOY_H, UMP_H, UMP_X, MACH_H, BOSS_ART, ZWOUND, woundStage, BOUNCE_IDLE, SPRITE_H, zombieH , WEAPONS, RACK_ROW, TOSS, HEAD_CROP, CUP_ROUNDS, TINT, SHOT_DEPTH, matchFoe } from './config.js';
|
||||
import { BENCH, BENCH_STAGES, ZFAMS, famFrames, racketStage, TUNE, UI, EATEN_BURST, EATEN_SUMMARY, EATEN_RESTART, DONE_RESTART, COURT, P_BOUNDS, PLAYER_H, BOY_H, UMP_H, UMP_X, MACH_H, BOSS_ART, ZWOUND, woundStage, BOUNCE_IDLE, SPRITE_H, zombieH , WEAPONS, RACK_ROW, TOSS, HEAD_CROP, TINT, SHOT_DEPTH, matchFoe } from './config.js';
|
||||
import { P, O, ball, score, crowd, G, court, tour, kit, skin } from './state.js';
|
||||
import { RAISERS, FRAMES } from './crowd.js';
|
||||
import { predictLanding, previewServe, slotId, slotStock, serveApexY, rallyFeel, swayOf } from './gameplay.js';
|
||||
@@ -236,7 +236,7 @@ function farB(z) {
|
||||
// Asset cache-buster — bump with main.js?v=N (see the img.src note below). EXPORTED because the
|
||||
// menu screens hang <img> tags on the same files, and two copies of this number is one copy too
|
||||
// many: the one that does not get bumped is the one that serves a cached 404.
|
||||
export const SPRV = 148;
|
||||
export const SPRV = 149;
|
||||
// The boot bar in main.js watches this. Nothing here CHANGES when things load — every sprite was
|
||||
// already requested at import — it just makes the wait visible and holds the menu back until the
|
||||
// last sheet has landed. See the onerror note below for the other half of "sometimes missing".
|
||||
@@ -2844,11 +2844,14 @@ export function render() {
|
||||
// ...and in CLASSIC it says how far through the MATCH you are, which is the one thing the
|
||||
// board itself cannot: which set this is, and how many it takes to win.
|
||||
// the cup names the ROUND — its opp is a drawn rung, so the deathmatch arithmetic lied here
|
||||
// clamped: past the final, cup.round sits one beyond the last row (that is how cupWon is
|
||||
// reached) and the trophy screen still draws one frame of this panel over the held court
|
||||
ctx.fillText(G.match && G.match.cup
|
||||
? `${CUP_ROUNDS[G.match.cup.round].name} · ${G.match.cup.round} FELLED`
|
||||
? `${G.match.cup.rounds[Math.min(G.match.cup.round, G.match.cup.rounds.length - 1)].name} · ${G.match.cup.round} FELLED`
|
||||
// training: the ladder is parked, so "opponent N · felled" would lie — name the rep instead
|
||||
: G.match && G.match.train ? `TRAINING · ${matchFoe(G.match.opp).short}`
|
||||
: G.match ? `OPPONENT ${G.match.opp} · ${G.match.opp - 1} FELLED`
|
||||
// the arcade names the RUNG and counts d.felled (THE LEAGUES: opp is a band position now)
|
||||
: G.match ? `${matchFoe(G.match.opp).short} · ${G.match.felled || 0} FELLED`
|
||||
: G.classic ? `SET ${G.sets[0] + G.sets[1] + 1} · FIRST TO ${TUNE.classicSets}`
|
||||
: `GAME ${G.runGames + 1} · ${G.sets[0]} SET${G.sets[0] === 1 ? '' : 'S'}`, bW - 3, bH + 8);
|
||||
}
|
||||
@@ -2887,12 +2890,16 @@ export function render() {
|
||||
ctx.fillStyle = won ? 'rgba(6,10,8,0.72)' : 'rgba(10,4,6,0.72)'; ctx.fillRect(0, 0, W, H);
|
||||
// The announcement face, at 26 rather than the card's 30: this is the longest string in the
|
||||
// game and at 30 it ran edge to edge on a 270px-wide portrait canvas.
|
||||
// the big line is reserved for the TOP league's cup (THE LEAGUES): a lower cup is a step
|
||||
// up the club, not the whole club — its ceremony (the promotion screen) follows anyway
|
||||
const title = dead ? (m ? 'BLED OUT.' : 'GAME, SET, MASSACRE.')
|
||||
: G.done.cup ? 'CHAMPION OF THE DEAD CLUB.' : won ? 'GAME, SET, MATCH.' : 'BEATEN.';
|
||||
: G.done.cup ? (G.league >= 5 ? 'CHAMPION OF THE DEAD CLUB.' : 'THE CUP IS YOURS.')
|
||||
: won ? 'GAME, SET, MATCH.' : 'BEATEN.';
|
||||
const line = dead
|
||||
? (m ? 'FELLED ' + m.felled + ' OPPONENT' + (m.felled === 1 ? '' : 'S') + ' · ' + m.games + ' GAMES'
|
||||
: 'SURVIVED ' + G.runGames + ' GAMES · ' + G.sets[0] + ' SETS')
|
||||
: G.done.cup ? 'THE CHAMPION FELL · ' + ((G.match && G.match.games) || G.runGames) + ' GAMES'
|
||||
: G.done.cup ? (G.league >= 5 ? 'THE CHAMPION FELL · ' : 'THE FINAL FELL · ')
|
||||
+ ((G.match && G.match.games) || G.runGames) + ' GAMES'
|
||||
: G.sets[0] + '–' + G.sets[1] + ' IN SETS · ' + G.runGames + ' GAMES';
|
||||
ctx.font = B(26); shadowText(title, W / 2, H / 2 - 44, won ? UI.pick : UI.bad);
|
||||
ctx.font = F(9); shadowText(line, W / 2, H / 2 - 14, UI.cream);
|
||||
@@ -2917,7 +2924,10 @@ export function render() {
|
||||
W / 2, H / 2 + 18, xd.to > xd.from ? UI.pick : UI.cream);
|
||||
const bw = 120, bx = Math.round(W / 2 - bw / 2), by = Math.round(H / 2 + 30);
|
||||
ctx.fillStyle = 'rgba(255,255,255,0.14)'; ctx.fillRect(bx, by, bw, 4);
|
||||
ctx.fillStyle = UI.warm; ctx.fillRect(bx, by, Math.round(bw * pr.frac), 4);
|
||||
// the fill is a gradient (Oliver's call), green into gold — same ramp as the splash strip
|
||||
const gr = ctx.createLinearGradient(bx, 0, bx + bw, 0);
|
||||
gr.addColorStop(0, '#3f9560'); gr.addColorStop(0.55, UI.pick); gr.addColorStop(1, '#e8b23a');
|
||||
ctx.fillStyle = gr; ctx.fillRect(bx, by, Math.round(bw * pr.frac), 4);
|
||||
}
|
||||
// gated well past the animation so a panic tap can't skip it (main.js gates the restart the same)
|
||||
if (dead ? G.eatenT > EATEN_RESTART : G.done.t > DONE_RESTART) {
|
||||
|
||||
Reference in new issue
Block a user