A browser-based arcade shooter. No external image or audio assets — all fruit
art and the beach background are drawn on <canvas>, and all sound (music,
gun fire, explosions, glass shatter, spoken lines) is synthesized live with
the Web Audio API and the browser's speech synthesis.
index.html— page structure, HUD, start/game-over overlaysstyle.css— layout and overlay stylinggame.js— everything else (rendering, physics, audio, game state)
- ◀ / ▶ arrow keys — move the fruit gun left/right
- Space (hold) — rapid-fire fruit bullets upward. Bullets tilt slightly in the direction the gun is moving, based on a mix of bullet speed and gun velocity.
A dusk beach background renders behind all gameplay: a dark navy-to-purple sky with faint stars and a soft glowing sun/moon near the horizon, a darker teal ocean band with animated wave lines, a muted sand strip along the bottom where the gun sits, and two silhouetted, gently swaying palm trees framing each side. Colors are kept deliberately dark/muted so the bright fruit, bullets, and particles stay highly visible against it.
- Five base fruit types fall from the top of the screen: Orange, Lemon, Cherries, Cantaloupe, Lime — each with its own size, point value, and fall-speed range, plus a gentle sideways sway for visual variety.
- Shooting a fruit triggers a particle explosion, an explosion sound, and the fruit's name spoken aloud.
- Glass bowls fall periodically at randomized speeds, launching at a
random angle off vertical (spread widens as the game progresses — see
Level 2 below). If a bowl hits the gun:
- A glass-shatter sound plays immediately.
- The hit counter increments (top-right HUD, shown as "Hits: X / cap").
- 500ms later, a voice announces "Broken Fruit Bowl."
- When hits reach the current cap, the game ends — a voice announces "Fruit Bowl! Game over!" and the final score is shown.
- The allowed number of bowl hits before game over starts at 10, rises to 15 on reaching Level 2 (score 1000), and rises again to 25 at a score of 2000.
Each time the player starts a new game (after the first), a persistent gravity multiplier increases by 10%, making fruit and bowl fall speeds progressively faster across sessions without needing to reload the page.
The game-over screen shows a "Previous Scores" column listing the 10 most
recent games played, most recent first, plus a highlighted "🏆 Top Score"
line for the best score ever recorded. Scores persist in the browser's
localStorage, so history carries over across page reloads.
Triggered automatically the first time the score reaches 1000:
-
Voice announcement: "You have reached level 2! The all out fruit fight!" plus an on-screen banner.
-
Bowl spawn rate doubles (8x the base rate, up from 4x).
-
Bowl fall speed increases 50%.
-
Bowl launch-angle spread widens from ±15° to ±25°.
-
All fruit fall speed doubles, and fruit also begins launching at random angles up to ±30° off vertical (previously fruit only fell straight down with a sway wobble).
-
Bowl-hit cap rises from 10 to 15.
-
Background music switches to a faster, higher-pitched theme.
-
4 seconds later, three new fruit types unlock and join the spawn pool, announced by voice ("New fruits added! Guava Nuts, Mango Pods, and Lime Cones!") plus a banner:
- Guava Nuts — speckled yellow-green fruit with a stem and leaf.
- Mango Pods — an elongated orange-to-red teardrop pod.
- Lime Cones — a green cone/party-hat shape instead of round.
All three always launch at exactly 45° off vertical (randomly left or right), rather than the randomized angle range used by other fruit.
-
12 seconds later, a "BOWL LINE INCOMING!" challenge fires: 5 glass bowls are released simultaneously, evenly spaced across the screen width, all falling straight down together as a synchronized wall.
The first time the score reaches 2000:
- Bowl-hit cap rises from 15 to 25 (HUD updates immediately).
- Voice announcement: "Horse Lips have arrived! Watch your fingers!" plus a banner.
- A new fruit type, Horse Lips, joins the spawn pool: a pair of pink lips with visible teeth that rapidly snap open and closed as they fall (animated via a fast oscillation). They launch at wide, unpredictable angles up to ±65° off vertical, and — uniquely among regular fruit — bounce off the left/right screen edges instead of leaving the screen, ricocheting back inward like a pool-table rebound. Shooting one plays the usual explosion + "Horse Lips!" voice call.
- If Horse Lips reach the gun uncaught, they bite it: the gun's horizontal move speed is cut by 40% for 6 seconds (a pulsing blue ring around the gun shows the debuff is active), accompanied by a sharp bite sound. This doesn't count as a bowl hit — it's a separate penalty.
The first time the score reaches 3000, a coordinated two-wave assault fires once:
- 12 glass bowls are released simultaneously, evenly spaced across the screen, all falling straight down together ("BOWL BARRAGE!" banner).
- 5 seconds later, 12 Horse Lips spawn at once ("HORSE LIPS SWARM!" banner), each with their usual wide-angle, wall-bouncing behavior.
The first time the score reaches 4000, a new fruit unlocks: voice announcement "New fruit unlocked! Mystery Toot!" plus a banner. Mystery TooT is a purple, sparkly fruit with a big question mark on it. It behaves like a normal fruit when shot (explosion + name callout), but if it reaches the bottom of the screen uncaught, it plays a comedic fart sound instead of just vanishing.
Once the score reaches 4000, a recurring line-drop begins: every 12 seconds, 20 of a single random hazard type — either glass bowls or Horse Lips (never regular fruit) — are released together, evenly spaced across the screen width, all falling straight down in sync as a solid wall ("FRUIT BOWL LINE!" or "HORSE LIPS LINE!" banner). Which type drops is re-rolled 50/50 each time the 12-second timer fires, so it can repeat the same hazard or alternate. This runs independently of (and at the same time as) the Mystery TooT unlock at the same score threshold.
The first time the score reaches 6000, voice announcement "Killer Bean Pods incoming! Everything speeds up!" plus a banner, and a recurring hazard begins: every 12 seconds, 12 killer bean pods rain down from the top of the screen (angry-eyed green pods with a red warning glow). They aren't shootable — only dodgeable. If a bean pod strikes the gun:
- It plays an accelerating "power-up" sound and disappears.
- A permanent chaos multiplier increases by 20%, instantly speeding up every fruit and bowl currently on screen by 20%, and continuing to scale all future fruit/bowl/bean-pod spawns from that point on. Each additional strike compounds on top of the last, so the game keeps getting faster the longer this phase runs.
Reaching a score of 7000 ends the game as a win: a voice announces "You are the Fruit Toot All Time Winner!" while a synthesized trumpet fanfare plays (two detuned oscillators through a bandpass filter for a brassy tone, in a short triumphant "ta-ta-ta-taa... ta-taaa" motif), alongside a "🏆 FRUIT TOOT ALL-TIME WINNER! 🏆" banner. The game-over screen swaps its usual "🥣 FRUIT BOWL! 🥣 / GAME OVER" heading for "🏆 FRUIT TOOT ALL-TIME WINNER! 🏆 / YOU WIN!" (and skips the "Fruit Bowl! Game over!" voice line used on a bowl-hit loss), then shows the final score and score history as usual.
If the player holds the gun perfectly still for 5 seconds, a "killer" bowl is deployed:
- Falls/tracks at 2x the speed of a normal bowl.
- Actively homes in on the gun's horizontal position as it falls.
- Bounces off the left/right screen edges like a pool-table rebound (reflects its horizontal velocity and spin instead of leaving the screen), then continues falling at the new angle.
- A second killer bowl is deployed automatically 500ms later, from the opposite side of the screen for a pincer effect.
- Rendered with a red glow, angry eyes, and crack marks to stand out from normal bowls.
- Voice announcement: "Killer Fruit Bowl!" plus an on-screen banner.
- Colliding with the gun counts as a normal bowl hit (shatter sound, hit counter, delayed "Broken Fruit Bowl" line) — it isn't an instant loss, just faster and harder to avoid.
- Only one wave of killer bowls is active at a time; the 5-second stillness timer resets once they're gone.
All audio is generated at runtime with the Web Audio API (AudioEngine in
game.js) — no sound files are loaded:
- Gun shot — short square-wave downward frequency sweep.
- Explosion — filtered noise burst plus a low sine "pop."
- Glass shatter — high-passed noise burst plus several randomized high-pitched sine "tink" blips.
- Bite (Horse Lips hitting the gun) — square-wave downward chirp plus a short band-passed noise click.
- Fart (Mystery TooT missed) — sawtooth downward sweep layered with filtered noise for texture.
- Bean pod strike — sawtooth upward sweep suggesting an accelerating power-up.
- Trumpet fanfare (score 7000) — a short scheduled melody of detuned sawtooth/square oscillator pairs through a bandpass filter, giving a brassy trumpet-like timbre.
- Background music — a looping scheduled sequence of triangle-wave melody notes over a square-wave bassline; a second, faster/higher variant plays after Level 2 is reached.
- Voice lines (via
SpeechSynthesisUtterance) — fruit names on explosion, "Broken Fruit Bowl" on a delay after a bowl hit, the Level 2 announcement, the new-fruits announcement, "Killer Fruit Bowl!", the Horse Lips arrival announcement, the Mystery TooT unlock announcement, the Killer Bean Pods announcement, the Fruit Toot All-Time Winner announcement, and the "Fruit Bowl! Game over!" line at the bowl-hit cap.
Sound requires a user gesture to start (browser autoplay policy), which is why audio initializes on the Start button click.