Salman Adnan

breakout-game

Breakout

Breakout is the arcade game where you slide a paddle, bounce a ball, and knock out a wall of blocks. This one is built from scratch in Python, no game engine, so everything is hand-made: spotting when the ball touches a block, losing one of three lives, speeding up as you rally, saving the high score. That touch test is a crude distance check; the drawing library offers nothing better.

Solo

Solo work by Salman Adnan.

The Perfect Run: an idealised game of Breakout playing itself, the paddle never missing and the wall of bricks never lasting. Live and interactive: drag it to orbit, scroll or pinch to zoom. Open full screen
The real turtle-graphics Breakout clone, running.
Live screenshot of the actual game.
3lives before game over
52blocks generated in a verified smoke test
200frames run in headless-safe verification

Overview

A classic Breakout clone built with Python's turtle module: a paddle, a bouncing ball, a wall of blocks colored by row, a lives system, a start and end screen, an increasing difficulty ramp, and a persistent high score.

A game-loop exercise: object motion, collision detection against multiple kinds of surfaces (walls, paddle, blocks), a small state machine for start/playing/game-over/win, and score state that survives between runs, all without a game engine, just turtle and a manual while-loop.

Key features

  • A block wall generated procedurally: random widths, packed row by row until there's no more vertical room, each row colored from a fixed palette.
  • Breaking a block flashes it white for a few frames and fires a small outward burst of particle turtles before both disappear.
  • Three lives; missing the ball costs one and re-centers it, keeping current difficulty, until all lives are gone.
  • The ball speeds up slightly every 4 paddle returns, capped at a maximum speed.
  • A start screen gates the game until the player is ready, and a game-over or win screen offers a restart that rebuilds the wall and resets ball and lives.
  • High score persists across runs in `highestScore.txt`, read on startup and saved whenever a game ends.

Verification

Since `main.py` never returns until the window is closed, verification ran the same modules through a headless-safe frame loop capped at 200 iterations, operating on private copies of the modules so the real `highestScore.txt` was untouched. It drove the ball onto the paddle 10 times to trigger the difficulty ramp, then forced a miss and a restart. Result: 52 blocks created, 200 frames run without exception, 10 paddle hits recorded, a life loss and a difficulty increase both observed, and the restart path rebuilding 46 blocks with lives and ball speed reset correctly.

Tech stack

  • Python 3 (stdlib only)
  • turtle
  • time

A challenge worth noting

Turtle gives no rectangle collision out of the box, so ball-to-block collision uses a fixed-radius distance check, an approximation that treats a wide block and a narrow block as the same size. Packing the block wall has a similar manual-geometry problem: `place_block()` tracks the previous block's position and width to decide whether the next one fits on the current row, wrapping to a new row or stopping entirely once vertical space runs out. `main.py` also runs the ball-to-block collision check twice per frame (once before moving the ball, once after) to catch a fast ball tunneling past a block between checks, which works but costs double the checks most frames need.

Book a call

Let's talk about what you're building.

Pick a slot below. No forms, no back-and-forth emails.