Week 04 :: Object Oriented Programming

<< back to Procedural Morphology homepage

Class notes

History -- Sketchpad by Ivan Sutherland
Sketchpad was the first program to introduce OOP. Drawings created in the program could be instantiated.

Alan Kay Presentation (sketchpad starts at 2:54)


What is OOP?

• Bundled Data and Methods.
• Modeled after real-world objects. 
• Benefits: modular, pluggable, protected (hiden data), resuable, faster development


Critical Concepts of OOP

Class -- template of an object
Encapsulation -- internalization of class variables and methods
Interface -- how you get/set class variables, trigger behaviors
Inheritance -- subclasses can be made that build upon classes
Polymorphism -- create different responses to the same message
Instantiation -- create a specific object in memory from your class blueprint.

Processing Class reference
Processing OOP example
Shiffman's Chapter on Objects in Processing
JAVA OOP tutorials

 

Develop a Class

1.  Name
2.  Fields (Data)
3.  Constructor
4.  Methods (Functions or behaviors)


Class Pseudo Code Example 1

class ClassName {
   // fields...

   // constructor...
   ClassName(constructionArguments) {
      store constructionArguments
   }

   // methods...
   void update() {
      code to execute on update
   }
}


Class Pseudo Code Example 2

class Cat {
   // fields....................
   color fur;
   float speed;
   float posx, posy;
          
   // constructor....................
   Cat(color furColor, float catSpeed) {
      fur = furColor;
      speed = catSpeed;                   
      posx = random(width);
      posy = random(height);
   }
           
   // methods....................
   void draw() {
      point(posx, posy);
   }
           
   void walk() {
      posx+= speed;
   }

   float getSpeed() {
      return speed;
   }
       
   void goFaster (float speedUp) {
      speed += speedUp;
   }
}


Instantiate an Object

1. Declaration (name of class is the type for the variable)
2. Allocation ('new' allocates space for the object in memory)
3. Initialization (passes starting conditions to the object)

Instantiation Pseudo Code Example 1

Cat garfield;
garfield = new Cat("orange",1 );

Instantiation Pseudo Code Example 2 (one line)

Cat garfield = new Cat("orange",1 );


Use an Object

Dot Syntax

Using dot syntax to access methods in a class

garfield.draw();
garfield.walk();
println(garfield.getSpeed());
garfield.goFaster(1);


Processing allows for direct access to class fields using dot syntax as well. This isn't pure OOP, but is allowed.

float pX = garfield.posx;
garfield.posx = 37.5;


Super Basic Object Instantiation


This example demonstrates building a simple class and instantiating one copy. The object does almost nothing (one instance is created and draws itself as a pixel on the canvas), but should give you an idea of the core structure of a class.

 

Creating More than One Copy


View this example for ideas how to create more than one instance of an object. Both examples from version 1 demonstrate managing a list of objects using an array. I encourage you to start crafting our objects with one on screen to isolate the behavior. This allows you to determine if the object is working as expected before introducing more copies.

 

Adding Behavior to Our Object


The first 2 examples are useful for understanding the basic syntax of OOP, here, however, we begin to introduce some behavior to our class. In this case is randomly chooses a new pixel around itself and moves into that position.

 

Moving Toward the Mouse


Here we're reducing the randomness of the object behavior and having the object move toward the mouse. Also note the fact that the object doesn't just snap to the mouse position. Rather, it eases to the mouse position by slowly reducing the difference between the object position and the mouse position.

 

Changing the Input


Here an image is used as input for our applet. The objects scan the brightness of the pixels immediately adjacent to their position and move to the brightest pixel. To load an image into your applet, you need a folder named 'data' under the folder containing your PDE file. Below is the image loaded into this applet. Tryloading alternate images to see the behavior on other contexts.

  

 

Example /  A Simple Shell for an Object



// following variable will hold our ball instance
Ball ballie;


// setup
//........................................................

void setup() {
   size(200, 200);
   background(150);
   smooth();
   // create an instance of the ball object
   ballie = new Ball();
}


// draw
//........................................................

void draw() {
   background(150);
   // tell the ball instance to run update() method
   ballie.update();
}


// ball class
//........................................................

class Ball {
   // ball fields
   float x;
   float y;

   // ball constructor
   Ball() {
      x = random(width);
      y = random(height);
   }

   // ball methods (this example only has a single method)
   void update() {
      // draw the ball
      stroke(0);
      strokeWeight(5);
      ellipse(x, y, 10, 10);
   }
}

Example /  Convert the ball example from last week to OOP

   
Click here to see the live version
.

// following variable will hold our ball instance
Ball ballie;


// setup
//........................................................

void setup() {
   size(200, 200);
   background(150);
   smooth();
   // create an instance of the ball object
   // notice that argments can be on different lines because processing is whitespace agnostic
   ballie = new Ball(
               random(width),     
// x position
               random(height),     
// y postion
               random(0.5,1.5),    
// x speed
               random(0.5,1.5)     
// y speed
               );
// end of ball arguments
}


// draw
//........................................................

void draw() {
   noStroke();
   fill(150,50);
   rect(0,0,width,height);
   // tell the ball instance to run update() method
   ballie.update();
}


// ball class
//........................................................

class Ball {
   // ball fields
   float x;
   float y;
   float speedX;
   float speedY;

   // ball constructor
   Ball(float _x, float _y, float _speedX, float _speedY) {
      x = _x;
      y = _y;
      speedX = _speedX;
      speedY = _speedY;
   }

   // ball methods (this example only has a single method)
   void update() {
      // update position of the ball
      x += speedX;
      y += speedY;

      // check for collisions with the side of the canvas
      if ( x > width || x < 0) {
         speedX *= -1;
      }
      if (y > height || y < 0) {
         speedY *= -1;
      }

      // draw the ball
      stroke(0);
      strokeWeight(5);
      ellipse(x, y, 10, 10);
   }
}

Example /  Move class functionality into methods

  
Click here to see a live version
.

// following variable will hold our ball instance
Ball ballie;


// setup
//........................................................

void setup() {
   size(200, 200);
   background(150);
   smooth();
   // create an instance of the ball object
   // notice that argments can be on different lines because processing is whitespace agnostic
   ballie = new Ball(
               random(width),      // x position
               random(height),     // y postion
               random(0.5,1.5),    // x speed
               random(0.5,1.5),    // y speed
               10,                 // normal ball size
               30                  // ball size when it hits the side
               ); // end of ball arguments
}


// draw
//........................................................

void draw() {
   noStroke();
   fill(150,50);
   rect(0,0,width,height);
   ballie.update(); // tells the ball instance to run update() function
}


// ball class
//........................................................

class Ball {
   // ball fields
   float x;
   float y;
   float speedX;
   float speedY;
   int normSize;
   int ballSizeX;
   int ballSizeY;
   int squashAmt;


   // ball constructor
   Ball(float _x, float _y, float _speedX, float _speedY, int _normSize, int _squashAmt) {
      x = _x;
      y = _y;
      speedX = _speedX;
      speedY = _speedY;
      normSize  = _normSize;
      ballSizeX = _normSize;
      ballSizeY = _normSize;
      squashAmt = _squashAmt;
   }

   // ball methods
   void update() {
      position();
      checkCollisions();
      drawBall();
   }


   void position() {
      x += speedX;
      y += speedY;
   }

   void drawBall() {
      stroke(0);
      strokeWeight(5);
      ellipse(x, y, ballSizeX, ballSizeY);
   }

   void checkCollisions() {
      if(x > width || x < 0) {
         speedX *= -1;
         ballSizeY = squashAmt;
      }
      if(y > height || y < 0) {
         speedY *= -1;
         ballSizeX = squashAmt;
      }
      if (ballSizeX > normSize) {
         ballSizeX--;
      }
      if (ballSizeY > normSize) {
         ballSizeY--;
      }
   }
}



Example /  Make multiple instances of the ball

   
Click here to see the live version
.

// following array will hold our ball instances
Ball[] ballies = new Ball[50];


// setup
//........................................................

void setup() {
   size(200, 200);
   background(150);
   smooth();
   // use a loop to fill the array with instances of the ball object
   for (int i=0; i<ballies.length; i++) {
      ballies[i] = new Ball(

                  random(width),      // x position
                  random(height),     // y postion
                  random(0.5,1.5),    // x speed
                  random(0.5,1.5),    // y speed
                  10,                 // normal ball size
                  30                  // ball size when it hits the side
                  );  // end of ball arguments
   }
}


// draw
//........................................................

void draw() {
   noStroke();
   fill(150,50);
   rect(0,0,width,height);
   // use a loop to cycle through and tell all the balls to update
   for (int i=0; i<ballies.length; i++) {
      ballies[i].update();
   }

}


// ball class (notice that it has not changed since previous example)
//........................................................

class Ball {
   // ball fields
   float x;
   float y;
   float speedX;
   float speedY;
   int normSize;
   int ballSizeX;
   int ballSizeY;
   int squashAmt;


   // ball constructor
   Ball(float _x, float _y, float _speedX, float _speedY, int _normSize, int _squashAmt) {
      x = _x;
      y = _y;
      speedX = _speedX;
      speedY = _speedY;
      normSize  = _normSize;
      ballSizeX = _normSize;
      ballSizeY = _normSize;
      squashAmt = _squashAmt;
   }

   // ball methods
   void update() {
      position();
      checkCollisions();
      drawBall();
   }

   void position() {
      x += speedX;
      y += speedY;
   }

   void drawBall() {
      stroke(0);
      strokeWeight(5);
      ellipse(x, y, ballSizeX, ballSizeY);
   }

   void checkCollisions() {
      if(x > width || x < 0) {
         speedX *= -1;
         ballSizeY = squashAmt;
      }
      if(y > height || y < 0) {
         speedY *= -1;
         ballSizeX = squashAmt;
      }
      if (ballSizeX > normSize) {
         ballSizeX--;
      }
      if (ballSizeY > normSize) {
         ballSizeY--;
      }
   }
}

Assignment for next week.

• Convert your assignment from last week to OOP and use the flexibility of OOP to enhance the applet.

• Reading: The essay Animate Form by Greg Lynn from Animate Form Greg Lynn