SWAMP UI / COMPONENTS / MOSQUITO SWAT

Mosquito Swat

click the buzz. spare the dragonfly.

Whack-a-mole, swamp edition. Mosquitoes spawn from the reeds and drift in lazy loops — click to swat. Don't hit the dragonflies; they eat mosquitoes for you (a swatted dragonfly costs you score and combo). The swamp narrates as you go. Reach 30 and the swamp sleeps.

No dependencies
Friendly + hostile bugs
Narrative thresholds
Calm endgame
LIVE PREVIEW · CLICK MOSQUITOES. NOT DRAGONFLIES.
SCORE0
COMBO0
THE SWAMP SLEEPS ★
the air is still. the herons can hear themselves think. you can hear yourself too.
BEST COMBO
0
DRAGONFLIES MISTAKEN
0
SWAMPS SLEPT
0

When to use

A tension-release minigame. Drop it on a 500 error page ("something is buzzing where it shouldn't"), or as a between-section breather in a long page. The narrative messages make it more than a stress ball: every swat is part of a small story about the swamp finally getting some quiet.

Skip to

1. HTML

Arena, HUD, swatter that follows the cursor, narrative + sleep overlay.

<div class="arena" id="arena"
     data-quota="30"
     data-spawn-ms="900">
  <div class="hud">...score / combo...</div>
  <div class="swatter" id="swatter">...svg...</div>
  <div class="narr" id="narr"></div>
  <div class="sleep" id="sleep">...endgame...</div>
</div>

2. Spawn + flight path

Each bug picks an edge spawn, a target heading, and a wobble (sine modulation perpendicular to its heading). Dragonflies fly straighter and faster. Both have a generous click-radius so the swatter feels accurate without being trivial.

// spawn one bug
function spawnBug(kind){
  const rect = arena.getBoundingClientRect();
  const side = Math.floor(Math.random() * 4);
  let x, y, vx, vy;
  if (side === 0) { x = 0;          y = Math.random() * rect.height; vx = .5+Math.random(); vy = (Math.random()-.5); }
  if (side === 1) { x = rect.width; y = Math.random() * rect.height; vx = -.5-Math.random(); vy = (Math.random()-.5); }
  if (side === 2) { x = Math.random()*rect.width; y = 0;            vx = (Math.random()-.5); vy = .5+Math.random(); }
  if (side === 3) { x = Math.random()*rect.width; y = rect.height;   vx = (Math.random()-.5); vy = -.5-Math.random(); }

  const speed = kind === 'df' ? 1.4 : 0.9;
  return { kind, x, y, vx: vx*speed, vy: vy*speed, t: Math.random()*9, alive: true };
}

// every frame: wobble + drift
bug.vx += Math.cos(bug.t) * (bug.kind === 'df' ? .03 : .06);
bug.vy += Math.sin(bug.t * 1.3) * (bug.kind === 'df' ? .03 : .06);
bug.x += bug.vx; bug.y += bug.vy; bug.t += 0.05;

3. Narrative thresholds

The swamp speaks at score milestones. Replace these with your own copy.

const NARRATIVE = {
  3:  'the air is thinning',
  8:  'the bog notices',
  14: 'the reeds are grateful',
  21: 'the herons can hear themselves think',
  30: 'the swamp sleeps'
};
const SCOLD = {
  1:  'a dragonfly! she was helping.',
  3:  'the dragonflies are not the enemy.',
  5:  'the swamp is shaking its head.'
};

4. Parameters you can tweak

WhereDefaultEffect
HTML data-quota30Score needed to trigger the "swamp sleeps" endgame.
HTML data-spawn-ms900Average ms between spawns. Lower = swarm mode.
JS DF_RATE0.18Probability each spawn is a dragonfly (so don't go too high).
JS CATCH_R26 pxClick radius. Higher = more forgiving swat.

Put a swamp to sleep?

Feed the dragonflies. (They like jelly.)

🧋 TREAT THE SWAMP →
More in the garden → Swamp Tarot, Firefly Catch, Lily Pad Stepping, Lure Cast, Frog Hop.
Browse all →