Tutorials › Build a Game Simple Mode

Build a Game

Put everything together and build a simple catching game from scratch, step by step!

1

The Player

Every game needs a player! Let's start with a paddle at the bottom of the screen that follows the mouse. We'll use constrain() to keep it inside the canvas.
0 / 10 lines
Loading editor...
size(400 400) draw: background(midnightblue) // Player paddle let px = constrain(mouseX 30 width - 30) fill(dodgerblue) noStroke() rect(px - 30 370 60 15)
2

A Falling Object

Now let's add something to catch! We'll create a ball that falls from the top. When it goes off the bottom, we'll reset it to the top at a random position.
0 / 24 lines
Loading editor...
let ballSpeed = 3; setup: size(400 400) draw: background(midnightblue) // Falling ball fill(gold) noStroke() circle(ballX ballY 12) ballY += ballSpeed // Reset when off screen if (ballY > height + 12) { ballY = -12 ballX = random(20 width - 20) // Player paddle let px = constrain(mouseX 30 width - 30); fill(dodgerblue); rect(px - 30 370 60 15); }
3

Collision Detection

The core of any game: checking if things are touching! We use dist() to measure the distance between the ball and the paddle center. If the ball is close enough, it's a catch!
0 / 38 lines
Loading editor...
let ballSpeed = 3; let score = 0; setup: size(400 400) draw: background(midnightblue) // Falling ball fill(gold) noStroke() circle(ballX ballY 12) ballY += ballSpeed // Player paddle let px = constrain(mouseX 30 width - 30) fill(dodgerblue) rect(px - 30 370 60 15) // Collision check if (ballY > 360 && ballY < 385 && ballX > px - 35 && ballX < px + 35) { score++ ballY = -12 ballX = random(20 width - 20) // Reset if missed if (ballY > height + 12) { ballY = -12; ballX = random(20 width - 20); } // Score fill(white); textSize(20); text("Score: " + score 10 25); }
4

Lives and Game Over

Let's add consequences! The player starts with 3 lives. Missing a ball loses a life. When lives hit zero, the game is over and a message shows up. Press Space to restart!
0 / 67 lines
Loading editor...
let ballSpeed = 3; let score = 0; let lives = 3; let gameOver = false; setup: size(400 400) resetBall() function resetBall() { ballY = -12; ballX = random(20 width - 20); } draw: background(midnightblue) if (gameOver) { fill(white) textSize(36) text("GAME OVER" 90 150) textSize(20) text("Score: " + score 150 200) text("Press SPACE to restart" 80 250) return // Falling ball fill(gold); noStroke(); circle(ballX ballY 12); ballY += ballSpeed; // Player paddle let px = constrain(mouseX 30 width - 30); fill(dodgerblue); rect(px - 30 370 60 15); // Catch! if (ballY > 360 && ballY < 385 && ballX > px - 35 && ballX < px + 35) { score++; resetBall(); } // Miss! if (ballY > height + 12) { lives--; if (lives <= 0) { gameOver = true; } resetBall(); } // HUD fill(white); textSize(18); text("Score: " + score 10 25); text("Lives: " + lives width - 90 25); } keyPressed: if (key === " " && gameOver) { score = 0 lives = 3 ballSpeed = 3 gameOver = false resetBall() }
5

Polish: Speed & Stars

Let's make it feel like a real game! We'll increase the speed as the score goes up, add some background stars for atmosphere, and show the level. This is the finished game!
0 / 80 lines
Loading editor...
let ballSpeed = 3; let score = 0; let lives = 3; let gameOver = false; let stars = []; setup: size(400 400) resetBall() for (let i = 0; i < 50; i++) { stars.push({ x: random(400) y: random(400) s: random(1 3) }) } function resetBall() { ballY = -12; ballX = random(20 width - 20); } draw: background(midnightblue) // Stars noStroke() fill(white) for (let i = 0; i < stars.length; i++) { circle(stars[i].x stars[i].y stars[i].s) if (gameOver) { fill(white); textSize(36); text("GAME OVER" 90 150); textSize(20); text("Final Score: " + score 130 200); text("Press SPACE to play again" 70 250); return; } // Ball fill(gold); noStroke(); circle(ballX ballY 12); ballY += ballSpeed; // Paddle let px = constrain(mouseX 30 width - 30); fill(dodgerblue); rect(px - 30 370 60 15); // Catch if (ballY > 360 && ballY < 385 && ballX > px - 35 && ballX < px + 35) { score++; ballSpeed = 3 + score * 0.3; resetBall(); } // Miss if (ballY > height + 12) { lives--; if (lives <= 0) gameOver = true; resetBall(); } // HUD fill(white); textSize(18); text("Score: " + score 10 25); text("Lives: " + lives width - 90 25); let level = Math.floor(score / 5) + 1; text("Level: " + level width / 2 - 30 25); } keyPressed: if (key === " " && gameOver) { score = 0 lives = 3 ballSpeed = 3 gameOver = false resetBall() }

What to try next

  • Add multiple falling balls at once using an array
  • Add power-ups that make the paddle wider or give extra lives
  • Make some balls dangerous (red) — catching them loses a life
  • Add a high score that persists between game overs
  • Add sound effects — try playSound("coin") when you catch something!