Week 6b – Classes

There is another way to make your code even more modular and what we call “object-orientated”. Object orientated programming ‘OOP’ is a style for structuring code that moves away from writing everything in a linear way. Instead, we group chunks of code into what we call classes.

A class is a section of code that has all the instructions for a specific part of your code. If you think back to the space invaders example, the aliens, for spaceships, for special high scoring aliens etc. would each be a different class. Having a class for each of these category of thing in your program reduces the amount of code we have to write. Classes define types of objects but there can be variability programmed into them.

You might think of a class as a cookie cutter or a template for something. So it has all the instructions to produce a cookie – yet it is not the cookie itself. When we use a class to produce a version of the actual thing, we call this an ‘instance’ of the class. Or an object. So the cookie itself is the object.

All objects have data (variables – size, color etc) and they have functions ( their behavior or their actions.)

An object has a particular syntax as shown below in the right hand column. As you can see it has 4 parts.

Screen Shot 2015-03-02 at 5.19.10 PM

  • The Class Name—The name is specified by “class WhateverNameYouChoose”. We then enclose
    all of the code for the class inside curly brackets after the name declaration. Class names are traditionally capitalized (to distinguish them from variable names, which traditionally are lowercase).
  • Data—The data for a class is a collection of variables. These variables are often referred to as instance variables since each instance of an object contains this set of variables.
  • A Constructor—The constructor is a special function inside of a class that creates the instance of the object itself. It is where you give the instructions on how to set up the object. It is just like Processing’s setup( ) function, only here it is used to create an individual object within the sketch, whenever a new object is created from this class. It always has the same name as the class and is called by invoking the new operator: “Car myCar new Car( );”.
  • Functionality—We can add functionality to our object by writing methods. These are done in the same way as described in Chapter 7, with a return type, name, arguments, and a body of code.

This code for a class exists as its own block and can be placed anywhere outside of setup( ) and draw( ). It can also be placed in a tab of the Processing IDE. Below you can see there is a class called MRect arranged as a tab. Whether you make it a tab or leave it sitting after void draw(); makes no difference.

Screen Shot 2015-03-02 at 5.58.01 PM

 

If you make it a tab you will notice that your class becomes a sepearate .pde file (as shown).

Screen Shot 2015-03-02 at 6.01.19 PM

USING A CLASS TO MAKE AN OBJECT:

We then use a class to make an object in the same way as a variable, in three stages. This is how we would initialize a car object.

Screen Shot 2015-03-02 at 5.59.17 PM

 

And the entire example would look like this:

 

// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com
 
// Example 8-1: A Car class and a Car object
 
Car myCar; // Declare car object as a globle variable.
 
void setup() {
  size(200,200);
  // Initialize Car object
  myCar = new Car(); // Initialize car object in setup() by calling constructor.
}
 
void draw() {
  background(255);
  // Operate Car object.
  myCar.move(); // Operate the car object in draw( ) by calling object methods using the dots syntax.
  myCar.display();
}
 
class Car { // Define a class below the rest of the program.
  color c; // Variables.
  float xpos;
  float ypos;
  float xspeed;
 
  Car() { // A constructor.
    c = color(175);
    xpos = width/2;
    ypos = height/2;
    xspeed = 1;
  }
 
  void display() { // Function.
    // The car is just a square
    rectMode(CENTER);
    stroke(0);
    fill(c);
    rect(xpos,ypos,20,10);
  }
 
  void move() { // Function.
    xpos = xpos + xspeed;
    if (xpos < width) {
      xpos = 0;
    }
  }
}

In the previous examples, the car object was initialized using the new operator followed by the constructor for the class.

    Car myCar = new Car();

This was a useful simplification while we learned the basics of OOP. Nonetheless, there is a rather serious problem with the above code. What if we wanted to write a program with two car objects?

    // Creating two car objects
    Car myCar1 = new Car();
    Car myCar2 = new Car();

This accomplishes our goal; the code will produce two car objects, one stored in the variable myCar1 and one in myCar2. However, if you study the Car class, you will notice that these two cars will be identical: each one will be colored white, start in the middle of the screen, and have a speed of 1. In English, the above reads:
Make a new car.
We want to instead say:
Make a new red car, at location (0,10) with a speed of 1.
So that we could also say:
Make a new blue car, at location (0,100) with a speed of 2.
We can do this by placing arguments inside of the constructor method.

    Car myCar = new Car(color(255,0,0),0,100,2);

The constructor must be rewritten to incorporate these arguments:

    Car(color tempC, float tempXpos, float tempYpos, float tempXspeed) {
      c = tempC;
      xpos = tempXpos;
      ypos = tempYpos;
      xspeed = tempXspeed;
    }

In my experience, the use of constructor arguments to initialize object variables can be somewhat bewildering. Please do not blame yourself. The code is strange-looking and can seem awfully redundant: “For every single variable I want to initialize in the constructor, I have to duplicate it with a temporary argument to that constructor?”

Screen Shot 2015-03-02 at 6.07.57 PM

 

Using a class constructor with arguments:

//Two objects!
Car myCar1;
Car myCar2;
void setup() {
  size(200, 200);
 
  //Parameters go inside the parentheses when the object is constructed.
  myCar1 = new Car(color(255, 0, 0), 0, 100, 2);
  myCar2 = new Car(color(0, 0, 255), 0, 10, 1);
}
void draw() { 
  //Even though there are multiple objects, we
  //still only need one class. No matter how many 
  //cookies we make, only one cookie cutter is needed.
  //Isn’t object-oriented programming swell?
 
  background(255);
  myCar1.move();
  myCar1.display();
  myCar2.move();
  myCar2.display();
}
 
 
class Car {
  color c;
  float xpos;
  float ypos;
  float xspeed;
 
  //The Constructor is defined with arguments
  Car(color tempC, float tempXpos, float tempYpos, float tempXspeed) {
    c = tempC;
    xpos = tempXpos;
    ypos = tempYpos;
    xspeed = tempXspeed;
  }
  void display() {
    stroke(0);
    fill(c);
    rectMode(CENTER);
    rect(xpos, ypos, 20, 10);
  }
  void move() {
    xpos = xpos + xspeed;
    if (xpos > width) {
      xpos = 0;
    }
  }
}

 

EXERCISE:
1) Download this example of the bouncingBall example and create a ball class. Hint: Your class is going to have the same amount of variables as does this example. And the variables that are constantly changing for your ball (like the x and y coordinate for example) are going to be in your constructor.

2) Take your class and make an array of 100 bouncing balls. No idea? Here is a video tutorial on arrays of objects to get you started.

3) Now, build take this example create a particle system using a PNG files to draw the particles for each class.  (make sure your PNG file is really small, otherwise your computer will become SUPER slow.)

'+
1
'+
2 - 3
4 - 5
6 - 7
8 - 9
10 - 11
12 - 13
13 - 14
[x]