← Drawing and animation with p5.js

Final challenge: Catch the circle

Click the falling circles to score. Fix a catch that works backwards, add lives and a game over, then add a power-up of your own.

Everything you have learned in one game: a list of objects, a loop, a function, a decision, and a click.

Your game has falling circles. When you click one, you score and it starts again at the top. If one reaches the bottom, it starts again too.

Two new ideas:

The hard part is "close". Two things touch when the distance between them is small: dist(...) < 20. It is easy to write > and have the game score for every click that misses.

PredictRead the code and say what it will do before you run anything. A wrong guess is fine: it shows you what to look for.

Predict

sketch.js
function setup() {
  console.log(dist(10, 10, 13, 14));
}

dist gives the straight distance between two points.

What does console.log(dist(10, 10, 13, 14)) show?

RunRun it and compare the result with your prediction.

Run

Click the circles before they fall off the bottom.

sketch.js
let balls = [];
let score = 0;

function setup() {
  createCanvas(300, 200);
  for (let i = 0; i < 4; i++) {
    balls.push({ x: random(20, 280), y: random(-100, 0), speed: random(1, 2.5) });
  }
}

function draw() {
  background(20, 30, 60);
  fill(255, 210, 0);
  for (let ball of balls) {
    circle(ball.x, ball.y, 24);
    ball.y = ball.y + ball.speed;
    if (ball.y > 210) {
      restart(ball);
    }
  }
  fill(255);
  text("Score: " + score, 10, 20);
}

function restart(ball) {
  ball.x = random(20, 280);
  ball.y = -10;
}

function mousePressed() {
  for (let ball of balls) {
    if (dist(mouseX, mouseY, ball.x, ball.y) < 20) {
      score = score + 1;
      restart(ball);
    }
  }
}
Try it yourselfYour edits are saved in this browser.

InvestigateTrace how each line of code connects to what you see.

Investigate

sketch.js
let balls = [];
let score = 0;

function setup() {
  createCanvas(300, 200);
  for (let i = 0; i < 4; i++) {
    balls.push({ x: random(20, 280), y: random(-100, 0), speed: random(1, 2.5) });
  }
}

function draw() {
  background(20, 30, 60);
  fill(255, 210, 0);
  for (let ball of balls) {
    circle(ball.x, ball.y, 24);
    ball.y = ball.y + ball.speed;
    if (ball.y > 210) {
      restart(ball);
    }
  }
  fill(255);
  text("Score: " + score, 10, 20);
}

function restart(ball) {
  ball.x = random(20, 280);
  ball.y = -10;
}

function mousePressed() {
  for (let ball of balls) {
    if (dist(mouseX, mouseY, ball.x, ball.y) < 20) {
      score = score + 1;
      restart(ball);
    }
  }
}

Match code with meaning.

One place for it.

Every miss scores.

Match each piece with what it does.

mousePressed()
dist(mouseX, mouseY, ball.x, ball.y) < 20
restart(ball);
"Score: " + score

Where does the score go up?

In this game every click that misses scores. Click the line that is wrong.

ModifyChange the code on purpose and check the result.

Modify

Give the player 3 lives and a GAME OVER screen. Start from the game above.

Need a hint?

Make let lives = 3; at the top. When a ball falls off the bottom, take one away.

Another hint

In draw(), only move and draw the balls if (lives > 0); otherwise show GAME OVER with text().

Press R after GAME OVER to start again.

Need a hint?

Add a keyPressed() function. p5 gives you key, the key that was pressed.

Another hint

if (key === "r" && lives === 0) { score = 0; lives = 3; }

Try it yourselfYour edits are saved in this browser.

Add lives: lose one when a ball falls off the bottom, and show GAME OVER at zero.

    Run your program. This ticks when your code does all of the above.

    Press R to play again after the game is over.

      Run your program. This ticks when your code does all of the above.

      MakeBuild something new using what you have learned. Expect a few tries; that is normal.

      A power-up

      Add a power-up: a different kind of ball (fast, small, gold) that is worth more points. Give it a property such as gold: true, draw it in its own colour, and score more when it is clicked. Finish by asking a friend to play it and change one thing because of what you saw.

      Try it yourselfYour edits are saved in this browser.

      Info

      Where this leads

      You have built a game from lists, objects, decisions, functions and events. That is a real programme: games bigger than this are the same pieces in more places.

      You have 4 balls and want to add 10 more. What is the smallest change?

      For teachers

      Students play a click-to-catch game, learn that mousePressed runs on its own and that touching means a small distance, fix a catch that scores for every miss, add lives with a game over and a restart key, and make a power-up ball. About 60 minutes.

      Open the teacher guide: answers, solutions, slides and a worksheet.

      Students will be able to

      Before class

      Read the unit primer first. This is the Python Catch the turtle challenge in JavaScript, and it completes the course. Everything has been taught except events and joining text: mousePressed() and keyPressed() are functions p5 calls for you. Click coordinates are the sketch's mouseX and mouseY. The common slip is > where < belongs, so the bug task is a logic error with no red line: students must read the condition and play. The game needs the sketch to be clicked first for keys to work. This lesson marks "Challenge complete".

      Running the lesson

      1. Predict: draw a 3-4-5 triangle on the board.
      2. Run: let students play for a minute and call out their scores.
      3. Investigate: for the bug, ask 'when is the distance big?'
      4. Modify: ask where lives are taken away, and where the check for zero lives belongs.
      5. Make: pairs list the power-up's property and the two lines that change before coding.

      The hard part (on purpose)

      Close means a small distance. Play the buggy version and say what is happening before reading the code.

      When students get stuck

      Stretch and support

      Stretch: Make the balls get faster as the score rises, or add a high score kept in a variable.

      Support: Give the lives code and ask only for the restart key, or give the gold ball and ask for a second power-up.

      Where it leads

      Optional next lesson: moving art with sin, cos and map.

      What each step is for

      Now you can
      Next lesson8. Moving artUse sin and cos to move things in circles, map to turn one range into another, and make a pattern of your own.