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
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
// 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
// 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
// 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