🎯 My First GameMaker Game · Episode 3 of 5 · See All Episodes
🧱 Episode 3 · Improver · Instances & Juice

Brick Blitz!
GML Breakout

Breakout the GameMaker way: spawn a brick wall with two loops, use collision events for bouncing, add particle explosions with the built-in particle system, and screen shake, juice is a first-class citizen here.

👶 Ages 10+ ⏱️ ~1.5 Hours 🎯 GameMaker ✓ Free
🏓 Mouse paddle 🧱 instance_create loops 💥 Collision events Particle system 📳 Screen shake ❤️ Lives & win
0 XP
Level 1
🔥0
Your Progress 0 / 6 steps
1
🏓
Mouse Paddle & Ball
mouse_x control plus a served ball
Active
🎯
Goal for this step

Set up the paddle on mouse control and a serving ball.

  • 1New project: spr/obj for paddle (110×14) and ball (14×14), room 700×520, dark background.
  • 2Paddle Step: x = clamp(mouse_x, 55, room_width - 55);, one line, mouse control done (origin centred!).
  • 3obj_ball Create: hspeed = choose(-4, 4); vspeed = -4.
  • 4Wall bounces: Step checks the three solid edges and flips speeds (Episode 1 skill).
  • 5The bottom edge does nothing yet, that is the losing zone, wired in step 5.
obj_paddle · Step
x = clamp(mouse_x, 55, room_width - 55);

// obj_ball · Step:
if (x < 8 || x > room_width - 8)  hspeed = -hspeed;
if (y < 8)                        vspeed = -vspeed;
✏️
Fill in the Blanks
+15 XP
The built-in variable gives the cursor position, clamped between 55 and room_width - because the paddle origin is centred.
🧠
Knowledge Check
+15 XP
Why must the paddle sprite’s origin be centred for x = mouse_x to feel right?
AOrigins are decorative
BThe origin is the point that sits AT x, centred means the paddle centres on the cursor
CGameMaker requires it
2
🧱
Spawning the Wall
instance_create_layer in nested loops
Locked
🎯
Goal for this step

Generate the brick wall from code in obj_game.

  • 1obj_brick: 64×22 sprite. But do NOT hand-place 50 bricks, spawn them!
  • 2obj_game Create: nested for loops calling instance_create_layer.
  • 3Colour by row without 5 sprites: set image_blend on each spawned instance, one white sprite, tinted per row!
  • 4The spawn-loop + tint pattern replaces hand-placement everywhere: grids, waves, tilefields.
obj_game · Create
var colors = [c_red, c_orange, c_yellow, c_lime, c_aqua];

for (var r = 0; r < 5; r++) {
    for (var c = 0; c < 10; c++) {
        var b = instance_create_layer(
            c * 68 + 44, r * 26 + 60, "Instances", obj_brick);
        b.image_blend = colors[r];
        b.points = (5 - r) * 10;
    }
}
⌨️
Code Challenge
+20 XP
Spawn and tint one brick:
obj_game · Create
var b = (c * 68 + 44, r * 26 + 60, "Instances", obj_brick);
b. = colors[r];
💡 Hint: The modern spawn function takes x, y, layer name and object; tinting uses the blend colour variable.
🧠
Knowledge Check
+15 XP
image_blend lets 5 brick colours come from…
A5 different sprites
BONE white sprite tinted at spawn time, less art, instant palette changes
CThe room background
3
💥
Brick Breaking & Paddle Spin
Two collision events do all the physics
Locked
🎯
Goal for this step

Wire both collision events: bricks die, paddle steers.

  • 1obj_ball + obj_brick collision: vspeed = -vspeed; add other.points to the score; with (other) instance_destroy();
  • 2with runs code AS another instance, the cleanest way to affect what you hit.
  • 3obj_ball + obj_paddle collision: bounce up and steer by hit position (the eternal spin formula).
  • 4Guard the paddle bounce with vspeed > 0 so edge clips cannot double-bounce.
obj_ball · Collision with obj_brick
vspeed = -vspeed;
global.score += other.points;
with (other) instance_destroy();

/// Collision with obj_paddle:
if (vspeed > 0) {
    vspeed = -vspeed;
    hspeed = (x - other.x) / 12;
    if (hspeed == 0) hspeed = 1;
}
✏️
Fill in the Blanks
+15 XP
The statement runs code as another instance, here destroying the brick the ball touched. The paddle bounce is guarded by vspeed > .
🧠
Knowledge Check
+15 XP
with (other) instance_destroy(); destroys…
AThe ball
BThe brick that was hit, with switches "who is running this code"
CAll bricks
4
Native Particles
GameMaker’s built-in particle system
Locked
🎯
Goal for this step

Make bricks explode into sparks using the particle engine.

  • 1GameMaker has particles BUILT IN, no manual arrays like the JS version.
  • 2obj_game Create: make a particle system and define a "spark" type: tiny squares, random directions, shrink over life, brief lifespan.
  • 3On brick death: part_particles_create at the brick’s position, 12 sparks.
  • 4Tint the burst to match the brick with part_type_color1(..., image_blend) inside the collision.
  • 5One-time setup, one call per burst. Native beats manual.
obj_game · Create (particles)
global.ps = part_system_create();
global.pt_spark = part_type_create();
part_type_shape(global.pt_spark, pt_shape_square);
part_type_size(global.pt_spark, 0.08, 0.14, -0.005, 0);
part_type_speed(global.pt_spark, 2, 5, -0.1, 0);
part_type_direction(global.pt_spark, 0, 359, 0, 0);
part_type_life(global.pt_spark, 20, 35);

// on brick death (in the collision event):
part_particles_create(global.ps, other.x, other.y,
                      global.pt_spark, 12);
✏️
Fill in the Blanks
+15 XP
GameMaker particles need a particle plus particle types. Spawning a burst is one call: with a count of 12.
🧠
Knowledge Check
+15 XP
The advantage of a defined particle TYPE reused for every burst is…
ABigger particles
BConfigure once, emit thousands cheaply, the engine batches and animates them for you
CIt works without a room
5
📳
Screen Shake & Lives
Camera wobble plus the lose-a-ball flow
Locked
🎯
Goal for this step

Add impact shake and the three-lives system.

  • 1Shake: obj_game holds shake = 0; brick deaths set it to 4; each Step it decays and offsets the camera by random(-shake..shake).
  • 2Lives: ball past the bottom → lives--, reset ball to centre with a fresh serve; 0 → rm_gameover.
  • 3Draw hearts in Draw GUI with a small heart sprite in a loop.
  • 4Play: bricks crunch, screen kicks, sparks fly. Juice, natively.
obj_game · Step
if (shake > 0) {
    shake -= 0.3;
    var cam = view_camera[0];
    camera_set_view_pos(cam,
        random_range(-shake, shake),
        random_range(-shake, shake));
}
⌨️
Code Challenge
+20 XP
Decay the shake and wobble the camera:
obj_game · Step
if (shake > 0) {
    shake -= ;
    camera_set_view_pos(cam,
        (-shake, shake),
        random_range(-shake, shake));
}
💡 Hint: Ease the value down a little each frame; the ranged random function picks the wobble offset.
🧠
Knowledge Check
+15 XP
Shake decaying by 0.3/frame (not instantly stopping) makes the effect…
ALonger and floatier
BSnap hard then settle smoothly, a punch followed by recovery, like real impacts
CRandom forever
6
🏆
Win Condition & Polish Pass
instance_number and the finishing checklist
Locked
🎯
Goal for this step

Detect the cleared wall and complete the game loop.

  • 1Win check, one line in obj_game Step: if (instance_number(obj_brick) == 0) room_goto(rm_win);
  • 2rm_win / rm_gameover rooms with score display and R-to-restart (reset globals!).
  • 3Polish checklist: ball speed cap (±7), serve delay (a 60-frame alarm before the ball moves, meet Alarm events!), sound effects (audio_play_sound on hits, the built-in bounce sounds work).
  • 4Three engines, three Breakouts, you now FEEL what engines automate. Episode 4 continues in the Space Shooter trainer!
obj_game · Step
if (instance_number(obj_brick) == 0) {
    room_goto(rm_win);
}

/// serve delay, obj_ball Create:
hspeed = 0; vspeed = 0;
alarm[0] = 60;              // fires in 1 second

/// obj_ball · Alarm 0 event:
hspeed = choose(-4, 4);
vspeed = -4;
✏️
Fill in the Blanks
+15 XP
Counting living instances uses (obj_brick). A delayed one-off action uses an event, set in frames (60 = one second).
🧠
Knowledge Check
+15 XP
Alarm events are GameMaker’s native version of which pattern you built manually elsewhere?
AThe game loop
BThe frame-countdown timer (spawn timers, serve delays), set a number, an event fires when it hits zero
CCollision detection
🎉🏆🎮✨🎉
Workshop Complete!
Instance spawning, native particles and screen shake, GameMaker juice mastered. Episode 4 (Space Shooter) awaits in the shooter trainer!
0
Total XP
1
Level
0
Best Streak
0%
Accuracy
▶ Episode 4: Space Shooter →
⭐ View My Progress & Certificates

This workshop was free and took many hours to build. If it helped you learn something new, consider supporting the project.

☕ Support on Ko-fi