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

ScriptResponsibilityKey wiki concept
Ball2D.csMoves the ball; reflects off walls, paddle, and a brick layer; reports a misscollision response, unity-collider2d-and-triggers
Paddle2D.csHorizontal player input, clamped to screenunity-input, unity-transform
Brick.csOne destructible brick: takes hits, awards score, raises Destroyedobserver-pattern
BrickGrid.csBuilds the wall in a loop, tracks bricks in a List, detects clearancecsharp-collections, unity-prefabs-scripting
BreakoutGame.csOwns score and lives; serves; rebuilds on clear; game overunity-gamemanager-pattern
ArcadeHud.cs (in ../shared/)Shared on-screen HUD: a status line plus a timed centre message, drawn with TextMeshProui-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)

  1. New 2D scene, Main Camera set to Orthographic.
  2. Add a user layer called Bricks (Edit → Project Settings → Tags and Layers).
  3. Brick prefab: create a square sprite, add a Box Collider 2D, add the Brick script, set its layer to Bricks, then drag it into the Project window to make a prefab and delete the scene copy.
  4. Paddle: square sprite near the bottom, scaled wide (e.g. 2.5, 0.4, 1). Add a Box Collider 2D and the Paddle2D script.
  5. Ball: small square sprite at the origin. Add the Ball2D script, drag the paddle’s collider into Paddle, and set Brick Mask to the Bricks layer.
  6. Grid: empty GameObject BrickGrid, add the BrickGrid script, drag the brick prefab into Brick Prefab. Tune columns/rows in the Inspector.
  7. Game: empty GameObject Game, add BreakoutGame, and drag in the Ball and BrickGrid.
  8. HUD: copy ../shared/ArcadeHud.cs into 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 text StatusText and anchor it to the top-left; duplicate it as MessageText, anchor it to the centre, and set its alignment to centre. Add ArcadeHud to the Canvas, drag both texts into its Status Text and Message Text fields, then drag the Canvas into the Hud field on Game. (Leave Hud empty and messages print to the Console instead.)
  9. 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):

  1. Brick types — give some bricks hitPoints = 2 (they already darken when weakened) or higher scoreValue; introduce an unbreakable brick.
  2. 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.
  3. Multiple levels — have BrickGrid read a layout from a 2D array or text asset instead of a uniform wall. This is the bridge to grid-based games.
  4. Particle and audio feedback on brick break — see unity-audiosource and game-feel.

Source files

5 items under this folder.