BlinkNBuild BlinkNBuild | Arcade Hub
How to play 60 FPS FIXED ENGINE

About this game

Balloon Blaster: how to play, and how it is built

Balloon Blaster is a fast arcade game: balloons drift down from the top of the screen, and you move a shooter along the bottom, firing upwards to pop them before they get past you. Small balloons are worth the most, combos multiply your score, and power-ups fall from above. Every balloon that gets past costs a life.

The whole game is one HTML file of about 1,900 lines, almost all of it JavaScript drawing on a canvas. The sections below explain the rules and the scoring exactly, and then open up the code to show how a browser game like this actually works.

How to playControls on a keyboard, a mouse and a touch screen
ActionKeyboardTouch screen
Move← β†’ or A DHold the left or right half of the screen
ShootSpace (or click)Tap
Change shooter speed↑ ↓-
PauseP or Esc-
Play again after game overSpaceTap the button

Choose Easy, Medium or Hard on the start screen. You start with 5 lives on Easy, 3 on Medium and 2 on Hard. A balloon that reaches the bottom costs one life - unless a Shield catches it, or you are in the short safe period (about 1.5 seconds) after losing a life.

Scoring, exactlyBalloon size, difficulty, combos and Double Score

Each balloon has a base value: small 3, medium 2, large 1 - smaller is harder to hit, so it pays more. The base is multiplied by the difficulty (Γ—1.0 Easy, Γ—1.5 Medium, Γ—2.5 Hard) and rounded. A combo is a run of pops with no balloon escaping: from 5 in a row the points are Γ—1.5, and from 10 in a row Γ—2.

DifficultySmall (combo 1-4 / 5-9 / 10+)MediumLarge
Easy3 / 5 / 62 / 3 / 41 / 2 / 2
Medium5 / 8 / 103 / 5 / 62 / 3 / 4
Hard8 / 12 / 165 / 8 / 103 / 5 / 6

Double Score doubles the value before the combo bonus, so a small balloon on Medium during Double Score, in a 10-pop combo, is worth 18. Playing on several days in a row adds a small streak bonus of 1% per day, up to 7%.

Every 30 points takes you up a level, and each level makes balloons appear 40 ms sooner, down to one every 400 ms. Hard starts at 700 ms, so it reaches that floor at level 9 (240 points); Medium, starting at 1200 ms, reaches it at level 21 (600 points).

The game also watches how you are doing. It remembers whether each of your last 20 balloons was popped or got away. If you are popping more than 85% of them, it gradually brings balloons sooner, by up to 300 ms; if you are popping fewer than 40%, it gradually gives you more time, by up to 400 ms. However well you play, balloons never come faster than one every 300 ms.

Power-ups and how often they appearWhat each one does, and the odds

Power-ups fall from the top of the screen. Move under one to catch it.

Power-upEffectChance when one drops
⚑ Rapid FireShoot much faster, for a while13.6%
✦ Tri-ShotThree bullets at once, for a while13.6%
❄ FreezeBalloons slow down, for a while13.6%
2️⃣ Double ScorePoints Γ—2, for a while13.6%
πŸ”₯ LaserShots pass through every balloon in their path, for a while13.6%
πŸ›‘ ShieldThe next escaping balloon costs no life13.6%
❀ Extra Life+1 life9.1%
πŸ’£ BombPops every balloon on screen, and scores them all9.1%

The timed power-ups last 20 seconds on Easy, 12 on Medium and 7 on Hard. Reaching score milestones also gives you an extra life.

How it is built: the game loopWhy the game runs at the same speed on every screen

Every real-time game runs a loop: update the world a little, draw it, repeat. The browser calls the drawing function once per screen refresh through requestAnimationFrame, but screens refresh at different rates - 60, 120, 144 times a second or more. If the game moved each balloon a fixed amount per drawn frame, it would run more than twice as fast on a 144 Hz gaming monitor as on a 60 Hz laptop.

Balloon Blaster separates the two. Its physics always steps in fixed slices of 1000/60 β‰ˆ 16.67 ms, and each drawn frame runs however many slices of real time have passed:

// from the game's source, with its comments trimmed
const FIXED_PHYSICS_STEP = 1000 / 60; // 16.6667ms baseline
...
if (frameDelta > 100) frameDelta = 100;
physicsLag += frameDelta;

let subSteps = 8;
while (physicsLag >= FIXED_PHYSICS_STEP && subSteps > 0) {
  simTime += FIXED_PHYSICS_STEP;
  update(simTime);
  physicsLag -= FIXED_PHYSICS_STEP;
  subSteps--;
}

On a 30 Hz screen that is about 2 physics steps per drawn frame; on a 60 Hz screen, about 1; on a 144 Hz screen, about 0.42 - most frames just redraw. The cap of 100 ms and at most 8 steps stops the game trying to "catch up" several seconds at once after you switch back from another tab.

The same idea - a fixed tick for the logic, independent of everything else - is how a microcontroller runs control loops from a timer interrupt.

How it is built: hits, odds and saved scoresThree small techniques worth stealing

Circle collision without a square root

A bullet hits a balloon when the distance between their centres is less than the balloon's radius plus the bullet's 5 pixels. Distance needs a square root, which is slow to do thousands of times a second, so the game compares the squares instead:

const dx = bal.x - bul.x, dy = bal.y - bul.y;
if (dx * dx + dy * dy < (bal.r + 5) * (bal.r + 5)) {

Both sides are positive, so comparing squares gives the same answer. For a small balloon (radius 15) the test is dxΒ² + dyΒ² < 400.

Weighted random choice

Each power-up has a weight - 3 for most, 2 for Extra Life and Bomb - adding up to 22. The game picks a random number below 22 and walks along the running totals to see which power-up it lands in. That is where the odds above come from: 3/22 = 13.6% and 2/22 = 9.1%.

A game is a state machine

The game is always in exactly one state - menu, playing, paused or game over - and each key or tap means something different in each. That is a state machine, the same structure used in digital hardware and firmware.

High scores in the browser

Your high score, best combo, best level and daily streak are stored with localStorage, which keeps small values for this site in your browser. They stay between visits on the same device, and clearing your browser's site data resets them.

Tips for a higher score
  • Protect the combo. Past 10 pops every balloon is worth double, so letting one large balloon escape can cost more than it was ever worth.
  • Prioritise small balloons when you have a choice - they are worth three times a large one.
  • Save movement. Raise the shooter speed with ↑ when balloons are spread out, and lower it with ↓ for precise shots.
  • Grab Shields early, before the spawn rate peaks.