Introduction To Computational Media (ICM) : Week 3
More of Last Week
More Operators
Increment and Decrement Shortcuts: i++ is equivalent to i = i + 1 and i-- to i = i - 1
Addition and subtraction shortcuts: i += 10 is equivalent to i = i + 10. The same goes for the other operators.
Modulo: i%2 gives us the value of the remainder after a division operation.
int i = 1;
i++;
i -= 10;
println(i);
int r = i % 3;
println(r);
More Built-in Variables
Processing has several more built-in variables that you should be aware of. We have already covered mouseX, mouseY, width and height. The following are along the same lines:
mousePressed: A boolean variable that is true if the mouse is currently pressed.
mouseButton: An integer that tells us which which button was pressed. The constants
LEFT, RIGHT and CENTER can be compared to this value.
pmouseX: The previous value of mouseX. You can use this to check direction of mouse movement along the X axis.
pmouseY: The previous value of mouseY. You can use this to check the direction of mouse movement along the Y axis.
keyPressed: A boolean variable that is true if a key is currently pressed.
key: A char variable that holds the value of the key currently pressed.
keyCode: An integer that holds the value of the key currently pressed. Can be compared to a set of constants for special keys. UP, DOWN, LEFT, RIGHT, ALT, CONTROL, SHIFT, BACKSPACE and so on.
Mouse and Keys Example
Bonus: Fonts and Text
PFont font; // Declare the variable (do outside of setup, just like normal variables)
font = loadFont("arial12.vlw"); // Load the font (do in setup as it does this over the network (sloooo)
// Make sure you create the font first (Tools: Create Font)
textFont(font, 12); // Specify that the text you are going to draw should use that font and size
text("My Name is Shawn", x, y); // Draw the String "My Name is Shawn" at specific x and y coordinates
Font and Text Example
Bonus: Displaying Images
PImage b; // Declare the variable (do outside of setup, just like normal variables)
b = loadImage("someimage.jpg"); // Load the image into the variable (do in setup as it does this over the network (slooow)
// Put the image file into the "data" folder (you may need to create this) of the project (Sketch: Show Sketch Folder)
background(b); // Use the image to draw the background or
image(b, x, y, width, height); // Draw the image at a specific x and y coordinates at a specific size
Image Example
Modularity
Built-in Functions
These functions get called automatically (they are callbacks) by Processing. You override them and implement them yourself.
mouseDragged(): Called when the mouse is pressed and moved.
mouseMoved(): Gets called when the mouse is moved.
mousePressed(): Gets called when the mouse button is pressed.
mouseReleased(): Gets called when the mouse butotn is released.
keyPressed(): Gets called when a key is pressed.
keyReleased(): Gets called when a key is released.
Mouse Released Example:
void mouseReleased()
{
fill(255,127,0);
ellipse(mouseX, mouseY, 10, 10);
}
Drawing Example
Creating our own Functions
You can create your own functions that you can call anywhere else in your code. There are many advantages to writing functions rather than putting everything in the setup() or loop() functions.
- 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 function 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.
Functions (or methods as I should be calling them) comprise of the following parts:
- Return Type: This is the type of data (or variable) that the function returns. So far we have only seen the built-in functions 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 function or method. You will call or execute the function using this. An example is setup.
- Arguments: You can pass data into a function through the use of arguments. These are specified as variables of a certain type (your choosing) that the function can then make use of. These variables are local to the function.
- Code Block: These are the instructions or code that the function will execute when called.
Here is an example:
// return type, function name, arguments, including types
int ourCoolFunction(int someInt, int someOtherInt)
{
// Declare a variable
int aThridInt;
// Do something valuable
aThirdInt = someInt * someOtherInt;
aThirdInt++;
// Return something (an integeter in our case as it must match the return type)
return aThirdInt;
}
We would run this function somewhere else in our code such as:
int myResult = ourCoolFunction(10,2);
print(myResult);
int a = 10;
int b = 3;
int c = ourCoolFuntion(a,b);
print(c);
Here is a slightly strange/obtuse/crazy example: Craziness
Classes and Objects, Oh my..
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, a sex, 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 or functions for walking, talking, eating and everything else that we do.
In order to create a person, we would use the class human 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.
}
See it Here