Zombie town: the match continues
Win your first game and the applause cuts off mid-clap. The palette drains,
the umpire lowers his voice ('Quiet... please'), your opponent turns — torn
red polo, dragging his racket — and shamblers come over the billboard wall.
The scoreboard rewrites CPU to THEM. 'Play.'
- zombies.js: shamblers walk your way; quality shots splatter them (gore
decal + particle burst + wet synth splat), weak sitters only stagger them
back; one crossing your baseline is a point for THEM
- tennis scoring machinery keeps running untouched: fifteen, thirty, deuce,
and 'Game, set... massacre' on a game win, all in recorded umpire English
- ball boys mop the gore they pass (their destiny fulfilled)
- transition: palette lerp, scripted spawns incl. the turned opponent,
new recorded lines (quiet_dark, remain_seated, play, new_balls)
- moan ambience, drained splatter palette, all zombie params in TUNE
Verified: transition triggers on first game win, splat/stagger/baseline
scoring all correct, dead-ball flow feeds fresh serves, tennis mode
regression clean (6/6 returns, 6/6 points resolved).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f221ff84df
commit
69e3a0c310
20 files changed
+247
-25
No files matched your search
@@ -24,10 +24,11 @@ function reverb(ac) { // stadium PA tail: exponentially decaying noise as impuls
|
||||
return reverbNode;
|
||||
}
|
||||
|
||||
export function voice(name, delay = 0) {
|
||||
export function voice(name, delay = 0, rate = 1) {
|
||||
const ac = audio();
|
||||
const play = buf => {
|
||||
const src = ac.createBufferSource(); src.buffer = buf;
|
||||
src.playbackRate.value = rate; // < 1 = slower and lower — the umpire's dark register
|
||||
src.connect(ac.destination); src.connect(reverb(ac)); // dry + center-court echo
|
||||
src.start(ac.currentTime + delay);
|
||||
};
|
||||
@@ -83,6 +84,38 @@ export function pock(vol = 0.8, freq = 900) { // racket contact / bounce thock
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
export function splat(vol = 0.7) { // wet burst — a zombie meets a first serve
|
||||
try {
|
||||
const ac = audio(), t = ac.currentTime;
|
||||
const src = ac.createBufferSource(); src.buffer = noiseBuf(ac, 0.22);
|
||||
const lp = ac.createBiquadFilter(); lp.type = 'lowpass';
|
||||
lp.frequency.setValueAtTime(1400, t); lp.frequency.exponentialRampToValueAtTime(180, t + 0.2);
|
||||
const g = ac.createGain();
|
||||
g.gain.setValueAtTime(vol, t); g.gain.exponentialRampToValueAtTime(0.001, t + 0.22);
|
||||
src.connect(lp).connect(g).connect(ac.destination); src.start();
|
||||
const o = ac.createOscillator(), og = ac.createGain(); // body thud
|
||||
o.frequency.setValueAtTime(120, t); o.frequency.exponentialRampToValueAtTime(45, t + 0.15);
|
||||
og.gain.setValueAtTime(vol * 0.7, t); og.gain.exponentialRampToValueAtTime(0.001, t + 0.16);
|
||||
o.connect(og).connect(ac.destination); o.start(t); o.stop(t + 0.18);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
export function moan(vol = 0.1) { // distant undead ambience
|
||||
try {
|
||||
const ac = audio(), t = ac.currentTime, dur = 1.2 + Math.random() * 0.8;
|
||||
const o = ac.createOscillator(); o.type = 'sawtooth';
|
||||
const f0 = 65 + Math.random() * 45;
|
||||
o.frequency.setValueAtTime(f0, t);
|
||||
o.frequency.linearRampToValueAtTime(f0 * 1.25, t + dur * 0.4);
|
||||
o.frequency.linearRampToValueAtTime(f0 * 0.9, t + dur);
|
||||
const lp = ac.createBiquadFilter(); lp.type = 'lowpass'; lp.frequency.value = 320;
|
||||
const g = ac.createGain();
|
||||
g.gain.setValueAtTime(0.001, t); g.gain.exponentialRampToValueAtTime(vol, t + dur * 0.3);
|
||||
g.gain.exponentialRampToValueAtTime(0.001, t + dur);
|
||||
o.connect(lp).connect(g).connect(ac.destination); o.start(t); o.stop(t + dur + 0.05);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
export function applause(seconds = 2.4, vol = 0.5) { // ponytail: synthesized claps; swap for a sample if it reads flat
|
||||
try {
|
||||
const ac = audio(), t0 = ac.currentTime, n = 90 * seconds;
|
||||
|
||||
Reference in new issue
Block a user