Unit 2 Objects
Learning Activity 2

Literal Objects and Constructors


Overview

In this learning activity students learn how to group a set of related variables and functions into literal objects: the x, y variables, and move, and display functions used to draw a jittering ellipse are grouped into one "bubble" object. They then learn to write a Bubble constructor function: something like an object bubble factory. These concepts constitute the foundation of Object-Oriented Programming, a paradigm that will help students to tackle more complex projects by writing programs that are easier to understand, manage, and extend.

Instructions

1) Group related variables and functions

Let's go back to the second example in LA1. We had two bubbles. Each bubble has a variable for its x position, another for its y position, a function that moves it, and a function that draws it. To keep track of which variable to use in which function, we added numbers to our variable and function names –-for example, in function moveBubble1 we should refer to x1, not to x2).

We know there are two groups of related variables and functions: x1, y1, moveBubble1 and displayBubble1 all relate to our first bubble; x2, y2, moveBubble2 and displayBubble2 all relate our second bubble.

An alternative way to do this, is to group x1, y1, moveBubble1 and displayBubble1 into one package, and group x2, y2, moveBubble2 and displayBubble2 into another one:

Notice that bubble1 and bubble2 look the same: we will create one generic package with variables x, y and functions move and display, and then use it for both:

2) Create a bubble literal object

In p5, packages made of variables and functions are called literal objects. Let's look at the syntax we use to define them. Below we create a literal object that represents a bubble, and put the object inside a variable and call it bubble1:

var bubble1 = {
              x: random(0, width),
              y: random(0, height),
              display: function() {
                stroke(255);
                noFill();
                ellipse(this.x, this.y, 24, 24);
              },
              move: function() {
                this.x = this.x + random(-1, 1);
                this.y = this.y + random(-1, 1);
              }
            }

Our object has four properties: x, y, and display and move, which happen to be functions. From inside these functions, x and y are referred to as this.x and this.y. The keyword this tells p5 we are referring to the x property that is defined in this object, as in the object that contains the function.

Notice that we are storing our literal object in a variable called bubble1: we have used p5 variables to hold numbers ( var x = 1 ), to hold texts ( var greeting = "hello!" ), but they can also hold objects like our bubble:

Now that we have our literal object let's use it. Here is a complete example: we create an object store it in the bubble1 variable, and then access its variables and functions using the dot operator, like so: bubble1.x, bubble1.y, and bubble1.move() and bubble1.display().

Try adding two more bubbles, and moving and displaying them.

3) Create an Array of Bubble Objects

When creating many bubbles, we can store them in an array:

This way we can use a for loop to create them (see setup below), and another for loop to access each bubble to move and display them (see draw ––remember bubbles.length holds the number of elements the bubbles array holds):

Let's say we now want to add a new bubble each time the user clicks the mouse. We would have to copy and paste the object code to the mouseClicked function. Something like this (this snippet still needs the setup and draw code from above to work):

function mouseClicked(){
    bubbles[bubbles.length] = {
      x: random(0, width),
      y: random(0, height),
      display: function() {
        stroke(255);
        noFill();
        ellipse(this.x, this.y, 24, 24);
      },
      move: function() {
        this.x = this.x + random(-1, 1);
        this.y = this.y + random(-1, 1);
      }
    }
}

The first time you click the mouse, the length of the array is ( we create four bubbles in setup). A fifth bubble is created and added to the bubbles array: its length is now 5. The second time the mouse is clicked, a sixth bubble is created and added to the array, and so on.

Of course for this mouseClicked function to work we need to add our setup and draw functions. Here is the complete example ––click on the canvas to create new bubbles:

Notice that lines 41 to 52 in setup are exactly the same as lines 14 to 25 in our mouseClicked function. By now we know that repeating code is not a good thing: it makes our programs longer, harder to read, and more error-prone. In the next section, we will write a function that creates objects for us so that we don't have to re-state what a bubble is each time we want to create a new one. This kind of function is called a Constructor function, and it will allow us to replace the code above with this:

function mouseClicked(){
    var lastBubblePosition = bubbles.length;
    bubbles[length] = new Bubble();
}
4) Create a Bubble Constructor function

A Constructor function is like an object-creating factory. It knows what the structure of an object is, and uses this template to create new ones. In our case, the function is called Bubble (by convention, constructor functions are capitalized). It knows that bubbles have four properties, x, y, move, and display, that x and y should be initialized with random values, and that move and display are functions, and what exactly they do.

When the statement new Bubble() is executed (which is to say when the constructor is called), a new literal object is created

This sketch does the same as the previous one, but it uses the Constructor function to create its four bubble objects: