Classes and Objects

Java and therefore Processing is an Object Orientated Language. This means that Java makes it easy to use objects in your code.

An Object is a datatype just like a variable with a couple of differences. Objects can hold multiple pieces of data and can hold methods to manipulate that data.

A Class is the blueprint for an Object. It is the code that represents the data and methods that are contained within.

I like to think of the following example when thinking about Classes and Objects.
We are all people, human people. That is a class. The class states that we have hair, eyes, ears, are capabile of walking and so on.

Our human class, would contain variables that hold the color of our eyes, hair, how fast we walk and so on. It would also contain methods for walking, talking, eating and everything else that we do.

In order to create a person (object), we would use the human (class) as a blueprint and fill in the values particular to the person we are creating.

In (some form of) English:

Define Human Class
	Human Has A Hair Color, Eye Color and Shoe Size.
	Human Can Walk and Run.
Create New Human
	This Human has Green Hair, Orange Eyes and wears a size 10 shoe.

In Processing we would open a new Tab and type the following:

// Give our class a name and tell Processing it is a class.
class Human
{
	// Variables for our individual humans.
	int hairColor;  // Shade of gray for simplicity sake
	int eyeColor;        
	int shoeSize;
	
	// Constructor, what we use to create a NEW human object: a person
	// A special type of method.
	Human(int theHairColor, int theEyeColor, int theShoeSize)
	{
		hairColor = theHairColor;
		eyeColor = theEyeColor;
		shoeSize = theShoeSize;
	}
	
	// our walk function for humans, returns distance walked, takes in number of steps
	int walk(int numSteps)
	{
		int distance = numSteps * shoeSize;
		return distance;
	}
	
	// our run funtion for humans, returns distance walked, takes in number of steps
	int run(int numSteps)
	{
		int distance = walk(numSteps) * 2;
		return distance;
	}
}

In order to create a human in our main program we would do the following:
You will notice that you call methods of the class/object using “.” method name on the actual object.

Human shawn;  // Declare the variable shawn to be an object of type Human

void setup()
{
	shawn = new Human(30,129,12); // Create the new human, run the constructor
	int distanceWalked = shawn.walk(10); // Have shawn walk, get the distance walked
	println("Shawn Walked: " + distanceWalked);
	int distanceRan = shawn.run(10); // Have shawn run
	println("Shawn Walked: " + distanceRan);
}

Using Objects makes it very easy to create multiple versions of the same thing, each with it’s own variables.

We can add a new Human called dan to illustrate:

Human shawn;  // Declare the variable shawn to be an object of type Human
Human dan;

void setup()
{
	shawn = new Human(30,129,12); // Create the new human, run the constructor
	dan = new Human(80,90,9);
	
	int distanceWalked = shawn.walk(10); // Have shawn walk, get the distance walked
	int dDistanceWalked = dan.walk(10);
	println("Shawn Walked: " + distanceWalked + " and Dan walked: " + dDistanceWalked);
	
	int distanceRan = shawn.run(10); // Have shawn run
	println("Shawn Walked: " + distanceRan);
}

Let’s go through another example:

// The name of our class
class Ball
{

  // our Class variables.  
  int wWidth;
  int wHeight;
  int bSize;
  
  int x, y;
  int xDirection, yDirection;
  
  // Constructor.  This gets called when we create a "new Ball"
  Ball(int windowWidth, int windowHeight, int ballSize)
  {
	wWidth = windowWidth;
	wHeight = windowHeight;
	bSize = ballSize;
	x = 1;
	y = 1;
	xDirection = 1;
	yDirection = 1;
  }
  
  // This is an Overloaded constructor
  Ball(int windowWidth, int windowHeight, int ballSize, int xPosition, int yPosition)
  {
	this(windowWidth, windowHeight, ballSize);
	x = xPosition;
	y = yPosition;
  }
  
  // Our method to determine current position of the ball.
  void compute()
  {
	if (x < wWidth && x > 0)
	{
	  // Move along x axis
	  x += xDirection;
	}
	else
	{
	  // Change direction, from positive to negative and vice versa
	  xDirection = xDirection * -1;
	  x += xDirection;
	}
	
	if (y < wHeight && y > 0)
	{
	  y += yDirection;    
	}
	else
	{
	  yDirection = yDirection * -1;
	  y += yDirection;
	}
  }
  
  // This actually displays our ball, it gets called in the main draw function
  void display()
  {
	compute();  // first we run the computation
	ellipseMode(CENTER);
	ellipse(x,y,bSize,bSize);   
  }

}

Here is what would be in the main Processing program:

Ball aBall, anotherBall;

void setup()
{
  size(500,500);
  aBall = new Ball(width,height,100);  // Call the constructor of Ball to create a new Ball
  anotherBall = new Ball(width,height,5,100,2); // Same..
}

void draw()
{
  background(255);
  aBall.display();  // Call the display function/method on the aBall object.
  anotherBall.display(); // Call it on the anotherBall object.
}               

Modularity

Built-In Methods

These methods get called automatically (they are callbacks) by Processing. You override them and implement them yourself.

mouseDragged(): Called when the screen is pressed and finger moved. Will happen repeatedly as the finger is dragged on the screen.

mousePressed(): Gets called when the screen is pressed.

mouseReleased(): Gets called when the screen which has been pressed is released.

keyPressed(): Gets called when a key is pressed. May happen multiple times in a row with one key press.

keyReleased(): Gets called when a key is released.

Test it out:

void setup()
{
}

void draw()
{
}

void mouseDragged() 
{
  println("mouseDragged");
}

void mousePressed() 
{
  println("mousePressed");
}

void mouseMoved() {
  // Doesn't work, no mouse moved in Processing for Android
  println("mouseMoved");
}

void mouseReleased() {
  println("mouseReleased");
}

void keyPressed() {
  println("keyPressed");
}

void keyReleased() {
  println("keyReleased");
}

Mouse Released Example:

void mouseReleased()
{
  fill(255, 127, 0);
  ellipse(mouseX, mouseY, 10, 10);
}

Drawing Example:

int x, y;

void setup()
{
  size(500, 500);
  background(255);
}

void draw()
{
  // Empty!
}

void mouseDragged() 
{
  line(x, y, mouseX, mouseY);
  x = mouseX;
  y = mouseY;
  println("mouseDragged");
}

void mousePressed() 
{
  x = mouseX;
  y = mouseY;
  println("mousePressed");
}

Creating our own methods

We can create our own methods that we can call elsewhere in your code. There are many advantages to writing methods rather than putting everything in the setup() or draw() methods.

Reuse: Writing a function for a commonly used set of commands that you can call over and over again. For instance, you have a complex shape that you use throughout your code. Rather than cutting and pasting those instructions everywhere you can write them once and call it over and over again.
Encapsulation: Putting functionality in a method and thereby seperating it from the rest of the code helps in understanding the program. It also makes making changes to that code much easier.

Methods comprise of the following parts:
Return Type: This is the type of data (or variable) that the method returns. So far we have only seen the built-in methods which return nothing and therefore use the type: void. Any of the other data types are acceptable as well.
Name: This is simply the name of the method. You will call or execute the method using this. An example is setup.
Arguments: You can pass data into a method through the use of arguments. These are specified as variables of a certain type (your choosing) that the method can then make use of. These variables are local to the method.
Code Block: These are the instructions or code that the method will execute when called.

Here is an example:

// return type, function name, arguments, including types
int ourCoolMethod(int someInt, int someOtherInt)
{
  // Declare a variable
  int aThridInt;
  
  // Do something valuable
  aThridInt = someInt * someOtherInt;
  aThridInt++;
  
  // Return something (an integeter in our case as it must match the return type)
  return aThridInt;
}

We would run this method somewhere else in our code such as:

void setup() {        
  int myResult = ourCoolMethod(10, 2);
  print(myResult);

  int a = 10;
  int b = 3;
  int c = ourCoolMethod(a, b);
  print(c);
}

// return type, function name, arguments, including types
int ourCoolMethod(int someInt, int someOtherInt)
{
  // Declare a variable
  int aThridInt;
  
  // Do something valuable
  aThridInt = someInt * someOtherInt;
  aThridInt++;
  
  // Return something (an integeter in our case as it must match the return type)
  return aThridInt;
}

Crazy Example:

int acounter = 0;

void setup()
{
  size(400,400);
  background(255);
}

void draw()
{
  fill(acounter%255);
  if (acounter%2 == 0)
  {
    drawLessCrazyShape(acounter%width,acounter%height,60);
  }
  else
  {
    drawCrazyShape(width-(acounter%width),height-(acounter%height));
  }
  acounter++;
}

void mousePressed()
{
    fill(mouseX,0,mouseY);
    drawCrazyShape(mouseX, mouseY);
}

void mouseDragged()
{
   fill(255,0,0);
   drawLessCrazyShape(mouseX,mouseY,50);
}

void drawCrazyShape(int x, int y)
{
  beginShape(POLYGON); 
    vertex(x, y); 
    x = x/(y+1)*2;
    vertex(x, y);
    y++;
    x--; 
    vertex(x, y); 
    y = x/(y+1)*2;
    vertex(x, y);
    x -= 30; 
    vertex(x, y); 
    vertex(y*2, x); 
  endShape();
}

void drawLessCrazyShape(int one, int two, int size)
{
  beginShape(POLYGON); 
    
    vertex(one, two); 
    
    one -= size;
    two += size;
    vertex(one, two);
    
    one -= size;
    two -= size;
    vertex(one, two); 

    one += size;
    two -= size;
    vertex(one, two);

    one -= size;
    two += size;
    vertex(one, two); 
    
  endShape();
}

Class 5 Homework

Due on Thursday Feb. 16, do a blog post describing (in your own way, text, images, drawings or video) an audio based mobile application that you would like to see in existence. Shoot for the stars, don’t be held back due to what you think is currently possible. Dream a bit!

while and for loop example

//int x = 0;

void setup() {
  fill(0);
  size(400,400);
}

void draw() {
 background(255,255,255);
 
 /*
 x = 0;
 while(x < width && mouseX > 0) {
   rect(x,0,mouseX/2,height);
   x = x + mouseX;
   println(x);
 } 
 */
 
 for (int x = 0; x < width && mouseX > 0; x = x+mouseX) {
     rect(x,0,mouseX/2,height);
 }
}

Bouncing Code – Start


int rectWidthHeight;

int rectX;
int rectY;

int direction = 10;

void setup() {
 
  println("setup");
  println("width " + width);
  println("height " + height);
  //frameRate(1);
  
  //rectMode(CENTER);
  
  rectWidthHeight = 50;
  
  rectX = mouseX;
  rectY = mouseY;
  
}

void draw() {
  background(120,120,120);

  rectWidthHeight = mouseX;
  
  rect((width/2)-(rectWidthHeight/2),(height/2)-rectWidthHeight/2,rectWidthHeight,rectWidthHeight);

  //println("draw");
  
  if (mousePressed) {
    rectX = mouseX;
    rectY = mouseY; 
  }
  
  if (rectX < 0 || rectY < 0) {
   direction = direction * -1; 
  } 
    
  if (rectX > width) {
       direction = direction * -1; 

  }

  if (rectY > height) {
    
       direction = direction * -1; 
  }
  
  rectX = rectX + direction;
  rectY = rectY + direction;
  
  rect(rectX,rectY,50,50);
  
}

Loops

While:
Just as with our conditional (if / else) statements a while loop employs boolean test that must evaluate to true in order for the instructions enclosed in the curly brackets to be executed. The difference is that the instructions continue to be executed until the test condition becomes false.

            int x = 0;
            while (x < 10) 
            {
                println("x is less than 10.");
                x++;
            }

Consider doing a striped background. You could do the following:

	void setup()
	{
	  size(400,400);
	  background(128);
	  stroke(255,0,0);
	  strokeWeight(5);
	}
	
	void draw()
	{
	 line(0,0,0,height);
	 line(20,0,20,height);
	 line(40,0,40,height);
	 // and so on..
	 
	 // or you could use a variable:
	 int x = 60;
	 line(x,0,x,height);
	 x = x + 20;
	 line(x,0,x,height);
	}	

but that would get very tedious.

With a "while" loop we could do it much more quickly and easily:

	void setup()
	{
	  size(400,400);
	  background(128);
	  stroke(255,0,0);
	  strokeWeight(5);
	}

	void draw()
	{
	 int x = 0;
	 while (x <= width)
	 {
	   line(x,0,x,height);
	   x = x + 20;
	 }
	}

For Loop:
Since this is a common use of a loop (creating a variable, checking it's value and incrementing by a certain amount) there exists an even quicker way to do the above, all in one step.

          for (int x = 0; x <= width; x = x + 20)
          {
             line(x,0,x,height);
          }

You can read this as, create variable x and set it to 0, while x is less than or equal to the width, do the following. Increment x by 20 at the end.
Exactly what we are doing in the while loop but in one quick step.

Conditionals

Execute a block of code based on the result of an expresssion that utilizes relational or logical (boolean) operators

If Statement:

            int anint = 1;
            if (anint >= 0)
            {
                // Execute some code
            }

If Else Statement:

            int anint = 1;
            if (anint >= 0)
            {
                // Excute some code
            } 
            else
            {
                // Execute some other code
            }   

If, Else If, Else:

            int anint = 1;
            if (anint >= 0)
            {
                // Execute some code
            }
            else if (anint < -1)
            {
                // Execute some other code
            }
            else
            {
                // Execute this code if none of the other conditions are true
            }

You can use the boolean operations to use boolean logic on multiple expressions.

            int anint = 1;
            int anotherint = 2;
            if (anint > 0 && anotherint <= 2)
            {
                // Execute some code
            }        

Operators

Assignment:
=

Mathematical Operators:
+, -, /, * (addition, subtraction, division and multiplication)

Example:

        int anumber = 0;
        anumber = anumber + 1;
        println("anumber = " + anumber);
        anumber = anumber + anumber;
        println("anumber = " + anumber);
        anumber = anumber/2;
        println("anumber = " + anumber);
        anumber = 7 * 8;
        println("anumber = " + anumber);
        
        anumber++;  // Short-cut for adding one, called "increment"
        println("anumber = " + anumber);
        anumber--; // Short-cut for subtracting one, called "decrement"
        println("anumber = " + anumber);

Relational Operators:
>= (greater than or equal to)
<= (less than or equal to)
== (equality)
!= (inequality)

Logical Operators: boolean logic
|| (logical OR)
&& (logical AND)
! (logical NOT)

Truth tables:

Or True False
True true true
False true false
And True False
True true false
False false false

Built-In Variables

mouseX and mouseY:
Define where the mouse (finger) is in relation to the window or screen.
Follow the cursor around:

        void setup()
        {
            size(500,500);
            fill(255,0,0);
            frameRate(10);
        }
        
        void draw()
        {
            rect(mouseX,mouseY,50,50);        
        }

width and height:
Contain the width and height of the sketch window. They are only set after size() is called (in the standard version, with Android it may be set already).

        void setup()
        {
            size(400,200);
            println("The width is: " + width);
            println("The height is: " + height);
        }

More information about the screen dimensions and other built-in variables available on Android can be found on the Processing Android Wiki Page