Minimal Breakout (Unity / C#)
The step-2 project in overview-arcade-classics-as-learning-projects. It builds directly on the Pong example and adds the skills the canon reference (see source-classic-games-canon) lists for Breakout: collision response, arrays/lists, level reset, and scoring.
As with Pong, this is an original project inspired by a recognisable pattern, not a clone of Atari’s Breakout.
Files
| Script | Responsibility | Key wiki concept |
|---|---|---|
Ball2D.cs | Moves the ball; reflects off walls, paddle, and a brick layer; reports a miss | collision response, unity-collider2d-and-triggers |
Paddle2D.cs | Horizontal player input, clamped to screen | unity-input, unity-transform |
Brick.cs | One destructible brick: takes hits, awards score, raises Destroyed | observer-pattern |
BrickGrid.cs | Builds the wall in a loop, tracks bricks in a List, detects clearance | csharp-collections, unity-prefabs-scripting |
BreakoutGame.cs | Owns score and lives; serves; rebuilds on clear; game over | unity-gamemanager-pattern |
ArcadeHud.cs (in ../shared/) | Shared on-screen HUD: a status line plus a timed centre message, drawn with TextMeshPro | ui-design, game-interface-types |
The ball still uses no Rigidbody — collision and reflection stay explicit. Bricks
are found with Physics2D.OverlapBox against a layer, which keeps the ball
decoupled from the grid.
Scene setup (about 10 minutes)
- New 2D scene, Main Camera set to Orthographic.
- Add a user layer called
Bricks(Edit → Project Settings → Tags and Layers). - Brick prefab: create a square sprite, add a Box Collider 2D, add the
Brickscript, set its layer to Bricks, then drag it into the Project window to make a prefab and delete the scene copy. - Paddle: square sprite near the bottom, scaled wide (e.g.
2.5, 0.4, 1). Add a Box Collider 2D and thePaddle2Dscript. - Ball: small square sprite at the origin. Add the
Ball2Dscript, drag the paddle’s collider into Paddle, and set Brick Mask to the Bricks layer. - Grid: empty GameObject
BrickGrid, add theBrickGridscript, drag the brick prefab into Brick Prefab. Tune columns/rows in the Inspector. - Game: empty GameObject
Game, addBreakoutGame, and drag in theBallandBrickGrid. - HUD: copy
../shared/ArcadeHud.csinto the project as well. Add GameObject → UI → Text - TextMeshPro (click Import TMP Essentials the first time). Unity also creates a Canvas (leave it on Screen Space - Overlay) and an EventSystem. Name the textStatusTextand anchor it to the top-left; duplicate it asMessageText, anchor it to the centre, and set its alignment to centre. AddArcadeHudto the Canvas, drag both texts into its Status Text and Message Text fields, then drag the Canvas into the Hud field onGame. (Leave Hud empty and messages print to the Console instead.) - Press Play. Move with A/D or the left/right arrows. Score and lives show on screen; clearing the wall rebuilds it and re-serves.
How the brick bounce works
When the ball overlaps a brick, ReflectOffBox compares how far it has
penetrated the brick on each axis and flips the axis of least penetration —
that is the side it most recently crossed. This is the standard lightweight
axis-aligned bounding box (AABB) resolution, and it is worth reading closely: the
same idea reappears whenever you resolve a moving box against static boxes.
Extension ladder
These mirror the Breakout extension tasks in the canon reference and point toward step 3 (Snake, grid logic):
- Brick types — give some bricks
hitPoints = 2(they already darken when weakened) or higherscoreValue; introduce an unbreakable brick. - Power-ups — on brick death, occasionally drop a falling pickup (wider paddle, multi-ball, slow ball). First taste of spawning and pooling — see object-pool-pattern.
- Multiple levels — have
BrickGridread a layout from a 2D array or text asset instead of a uniform wall. This is the bridge to grid-based games. - Particle and audio feedback on brick break — see unity-audiosource and game-feel.