← Teacher guide

Making it move

Students meet draw() (about 60 times a second) and variables that keep their value between frames, follow a circle's x frame by frame, see why background belongs in draw, fix a variable made inside draw, then move things down and at different speeds.

Drawing and animation with p5.js · Shapes and movement · about 50 minutes · Open the student lesson

Classroom resources

Load these into Waypoints Prepare: choose Load URL and paste the copied address, or download the file and import it. In Prepare, the worksheet's Teacher edition shows the answers; the student copy hides them.

Students will be able to

Timing

Predict and Run 10 min · Investigate 15 min · Modify 10 min · Make 15 min

Before class

Read the unit primer first. The big idea is that draw() runs by itself, again and again; students never call it. A variable made at the top (outside functions) keeps its value between frames, and x = x + 2 reads as "make x two bigger", not as a maths equation. Students who did Python Foundations will recognise x = x + 1 from the variables lesson; the new part is that the loop is built in. The let in the bug task is the classic mistake: a variable made inside draw() starts again every frame. % (remainder) appears only in the Make step's text. The playground's number in the corner is text(x, 10, 20).

Running the lesson

  1. Predict: ask a student to act as p5, saying 'frame' and stepping a classmate two steps right each time.
  2. Run: change the 2 to a 5 and ask why it is faster.
  3. Investigate: fill the trace together before students do: x is drawn first, then changed.
  4. Modify: ask which variable moves which circle before they run it.
  5. Make: choose the two ideas as a pair, then each makes one.

The hard part (on purpose)

Seeing that draw() repeats, so a variable made inside it starts again. The trace table and the let-in-draw bug are for that.

When students get stuck

What you will seeA question to askThe fix
The circle does not move.Is the variable changed inside draw(), and made outside it?let x = 0; goes at the top, outside every function; x = x + 2; goes inside draw().
A red line saying x is not defined.Where is let x = 0;?Put it at the top of the sketch, above setup().
A smear instead of a moving circle.Is background(...) the first line in draw()?Move it to the first line of draw().
Both circles move together.Do they use the same variable?Make a second variable for the second circle.

Answers to the checks

  1. Predict: What does the circle do?
    It slides right. draw() runs about 60 times a second and each time x goes up by 2, so the circle moves 120 pixels every second. Nothing sends it back, so it slides off the edge.
  2. Frame by frame: x starts at 0. Fill in where the circle is drawn, and what x is after each frame.
    2, 4, 4, 6, 6, 8
    Each frame draws the circle with the current x, then adds 2. So the circle is drawn at 0, 2, 4, 6, and x is already 2 bigger when the next frame starts.
  3. The smear: What would happen if background(20, 30, 60) was removed from draw()?
    Every old circle would stay, leaving a thick smear
    Without background, nothing paints over the previous frame, so each frame's circle is added to the picture. That is how trails are made on purpose.
  4. Spot the bug: The circle never moves, however long you wait. Click the line that is wrong.
    line 6
    let x = 0 inside draw() makes a new x, set to 0, every frame. The change of 2 is thrown away each time. Make x once, above the functions.
  5. Where this leads: A circle slides off the right edge and is never seen again. What does the sketch need to do?
    Notice when x is too big and put it back: a decision
    The sketch has to decide something each frame: is x past the edge? That is an if, and it is the next lesson.

Solutions

One possible solution for each task. Other correct programs are fine.

Modify › Down, not across

let y = 0;

function setup() {
  createCanvas(300, 200);
}

function draw() {
  background(20, 30, 60);
  fill(255, 210, 0);
  circle(150, y, 40);
  fill(255);
  text(y, 10, 20);
  y = y + 2;
}

Modify › Two circles

let x = 0;
let y = 0;

function setup() {
  createCanvas(300, 200);
}

function draw() {
  background(20, 30, 60);
  fill(255, 210, 0);
  circle(x, 60, 40);
  fill(255, 120, 160);
  circle(300 - y, 140, 30);
  x = x + 2;
  y = y + 4;
}

two things that move

let t = 0;

function setup() {
  createCanvas(300, 200);
}

function draw() {
  background(20, 30, 60);
  t = t + 1;
  fill(255, 210, 0);
  circle(t % 300, 60, 30);
  fill(255, 120, 160);
  circle(300 - (t % 300), 140, 30);
  fill(255);
  text(t, 10, 20);
}

Stretch and support

Stretch: Make a circle that moves in both directions at once (x and y), or one that grows and shrinks.

Support: Give students the sketch with let y = 0; already made, and ask for the draw() changes only.

Exit ticket

Why is let x = 0; at the top and not inside draw()?

Inside draw() it would be made again every frame and go back to 0; at the top it keeps its value.

What each step is for

Where it leads

Next lesson: if, so circles can bounce, and the mouse.