U4LA2.4: Objects on Canvas

How can I use classes and objects with the p5.js library?

Teacher Notes && Overview

This lesson pulls together everything students have been learning about Classes and objects and brings it back to the canvas. Students may notice that building a Class and the associated methods may be a big initial lift, but the goal is that once it's made, it will be easier to make duplicates on their screen and minimize the amount of repeated and confusing code.

This is a great time to get students used to splitting their code across multiple files that are all linked together; storing Classes in their own location (as we did with functions) can help make our code easier to read and manage, and can be empowering to students.

Objectives

Students will be able to:

  • Create a Class with properties and methods related to the p5.js library

  • Create instances of the Class

  • Use methods to change their object on the canvas

Suggested Duration

1-2 Periods (45 - 90 minutes)

NYS Standards

9-12.CT.4 Implement a program using a combination of student-defined and third-party functions to organize the computation.

9-12.DL.1 Type proficiently on a keyboard.

9-12.DL.2 Communicate and work collaboratively with others using digital tools to support individual learning and contribute to the learning of others.

Vocabulary

No new vocabulary is introduced

Planning Notes && Materials

Resources

Assessments

Formative:

  • Improved Wiggler

Summative:

  • Upcoming Tamagotchi Mini Project

  • Upcoming End of Unit Final

Do Now/Warm Up (~2 - 3 min)

Think back to the beginning of this unit when we were learning about motion, before we dove into Classes and objects. Briefly summarize the process of making something on the canvas move around the screen.

Setting up for Objects that Move (~5 min)

Take time to review the do now with your students, as it's been awhile since they worked with motion. Make sure they get the basics of creating speeds that will change the x and y position of a shape.

Then, explain that you are going to be creating a Wiggler class today. This object will 'wiggle' it's way across the screen and should bounce when it encounters edges. To make things fun, we can get rid of the background to track its progress. If we made several, it might look something like this:

You may want to spend some time with students previewing what they think will need to happen to create these, such as generating random speeds, etc. Once you feel like they have a clear vision of where the lesson is headed, it's time to start coding!

Code Along: Create a Wiggler (15 - 25 min)

Ask students to create a new sketch with Collide2D linked. We won't be using collision right away, but they may want it later!

To start out, we are going to make our Class and slowly add in our methods. You can instruct students to do this in their main sketch.js file, or to create a separate file that they will link through index.html to keep their code. more organized.

NB: In JavaScript, it is acceptable to write the Class definitions at the bottom of our main p5 code, the way we did with our functions - when we run our code it will still be able to find the definitions and create our objects even though it may seem 'out of order.'

Begin by thinking of the very basics of this wiggler: we know it will need to be a shape, and we know it needs to move. For our purposes, let's make that shape a rectangle. We know a rectangle has an x, y, width, and height and that it will need an xSpd and ySpd to move. We will also need to decide which of those we want to set manually, and which are default values. You can discuss with your class or decide unilaterally - based on their choices, the Class may look different, but you will end up with something that looks like:

class Wiggler{
    constructor(w, h){
        this.x = random(width) //will appear anywhere on the canvas
        this.y = random(height) //will appear anywhere on the canvas
        this.w = w
        this.h = h
        this.xSpd = random(-3,3) //create random movement
        this.ySpd = random(-3,3) //create random movement
    }
}

Perfect - so let's make a new Wiggler!

let wiggler1

function setup() {
  createCanvas(400, 400);
  wiggler1 = new Wiggler(35, 35)
}

function draw() {
  background(220);
}

Our code looks right, but if we hit play, nothing is showing up on the screen. We may wonder: did it even make our object? We can test by using a good ol' console.log() as we were in past lessons and sure enough, our object should be there. But it's not appearing on the screen! That's because while we have set all our properties and given all this information to draw our moving rectangle, we haven't actually told the computer that we expect it to make a moving rectangle.

That's where our methods are going to come in! The first method we need is one to get a rectangle to appear on the screen. Let's set it up like so:

class Wiggler{
    constructor(w, h){
        this.x = random(width) //will appear anywhere on the canvas
        this.y = random(height) //will appear anywhere on the canvas
        this.w = w
        this.h = h
        this.xSpd = random(-3,3) //create random movement
        this.ySpd = random(-3,3) //create random movement
    }
    
    display(){
        rect(this.x, this.y, this.w, this.h)
    }
}

This is really simple, but students can return to style their wigglers later. We have to make sure we don't just write our method but also call it:

let wiggler1

function setup() {
  createCanvas(400, 400);
  wiggler1 = new Wiggler(35, 35)
}

function draw() {
  background(220);
  
  wiggler1.display()
}

NOW we should have a shape on the screen! If we run the code a few times, we will see that the rectangle keeps appearing in different places, which is great - that's what we wanted our code to do when new wigglers were created!

So now we need to make it wiggle. That means another method:

class Wiggler{
    constructor(w, h){
        this.x = random(width) //will appear anywhere on the canvas
        this.y = random(height) //will appear anywhere on the canvas
        this.w = w
        this.h = h
        this.xSpd = random(-3,3) //create random movement
        this.ySpd = random(-3,3) //create random movement
    }
    
    display(){
        rect(this.x, this.y, this.w, this.h)
    }
    
    move(){
        this.x += this.xSpd
        this.xSpd = random(-3,3) //pick a new speed so it looks 'wiggly'
        
        this.y += this.ySpd
        this.ySpd = random(-3,3) //pick a new speed so it looks 'wiggly'
    }
}

And just like before, we will use that method on our object:

let wiggler1

function setup() {
  createCanvas(400, 400);
  wiggler1 = new Wiggler(35, 35)
}

function draw() {
  background(220);
  
  wiggler1.display()
  wiggler1.move()
}

Perfect, nice and wiggly! But it doesn't bounce on the edges yet, so we are going to head back to our class and make that happen:

class Wiggler{
    constructor(w, h){
        this.x = random(width) //will appear anywhere on the canvas
        this.y = random(height) //will appear anywhere on the canvas
        this.w = w
        this.h = h
        this.xSpd = random(-3,3) //create random movement
        this.ySpd = random(-3,3) //create random movement
    }
    
    display(){
        rect(this.x, this.y, this.w, this.h)
    }
    
    move(){
        this.x += this.xSpd
        this.xSpd = random(-3,3) //pick a new speed so it looks 'wiggly'
        
        this.y += this.ySpd
        this.ySpd = random(-3,3) //pick a new speed so it looks 'wiggly'
    }
    
    bounceOnEdge(){
        if(this.x > width || this.x < 0){
            this.xSpd *= -1
        }
        
        if(this.y > height || this.y < 0){
            this.ySpd *= -1
        }
    }
}

Perfect! Now, the biggest issue we might face is that because our rectangle keeps track of space from the top left corner, it may still appear to go off the edge on the right side and bottom of the screen. We could adjust our code to say this.x > width - this.w and this.x < 35to make sure to account for the size of the rectangle - we could do something similar to the conditional keeping it from going off the page, as well!

Now, before we take the background off and watch our little guy mvoe around, let's think critically about our code. If we wanted to make many of these little guys, and we know we always want them to display, move, and bounceOnEdge. That could get really redundant fast - so let's put those methods inside of another method to simplify our life! We will call this method animate():

class Wiggler{
    constructor(w, h){
        this.x = random(width) //will appear anywhere on the canvas
        this.y = random(height) //will appear anywhere on the canvas
        this.w = w
        this.h = h
        this.xSpd = random(-3,3) //create random movement
        this.ySpd = random(-3,3) //create random movement
    }
    
    display(){
        rect(this.x, this.y, this.w, this.h)
    }
  
    move(){
        this.x += this.xSpd
        this.xSpd = random(-3,3) //pick a new speed so it looks 'wiggly'
        
        this.y += this.ySpd
        this.ySpd = random(-3,3) //pick a new speed so it looks 'wiggly'
    }
  
    bounceOnEdge(){
        if(this.x > width || this.x < 0){
            this.xSpd *= -1
        }
        
        if(this.y > height || this.y < 0){
            this.ySpd *= -1
        }
    }
  
    animate(){
      this.display()
      this.move()
      this.bounceOnEdge()
    }
}

And then our main code can be thus simplified:

let wiggler1

function setup() {
  createCanvas(400, 400);
  wiggler1 = new Wiggler(35, 35)
}

function draw() {
  background(220);
  
  wiggler1.animate()
}

Ta-dah! Remove the background and watch that critter wiggle!

Student Challenge: Improving the Wiggler (10 - 20 min)

Depending on time, give students a series of things to attempt with their Wigglers:

  1. Create two more instances of the Wiggler class and get them to display on screen

  2. Style the wiggler as you see fit - this may mean adding properties, depending on what you decide. (Giving it some transparency can be fun while you watch it walk around!)

  3. Make the Wiggler change color when the mouse is clicked - you'll likely want a new method for this. (You can also track how many times it's been clicked, and the color can progress based on that number.)

  4. Make something happen if the Wigglers hit each other using Collide2D and new methods.

  5. Change anything else you'd like about these objects and how they behave!

Wrap-Up (3-5 min)

Allow students to show off what they've changed about the Wiggler, or to present questions to the class about what they are struggling with.

Extensions

For students really forging ahead who ahve already fully improved the Wiggler, ask them to research how to extend a Class in JavaScript. This option allows you to make different versions of the same Class template without starting from scratch, because the extended version will inherit from the original.

Last updated