OOP
Contents
OOP¶
Example: Circles¶
/* Code without a class. */
int count_up = 0;
int count_down = 400;
void setup() {
size(400, 600);
noStroke();
}
void draw() {
background(222);
fill(170, 172, 204, 150);
circle(width/2, height/2, count_up);
count_up += 1;
fill(250, 191, 171, 100);
circle(width/2, height/2, count_down);
count_down -= 2;
}
/* Code with a class. */
Circle c1, c2;
void setup() {
size(400, 600);
noStroke();
// Initialize circles
c1 = new Circle(color(170, 172, 204, 150), width/2, height/2, 0, 1);
c2 = new Circle(color(250, 191, 171, 100), width/2, height/2, 400, -2);
}
void draw() {
background(222);
c1.display();
c2.display();
}
class Circle {
/* Data.
Size and the modifier for the size are stored
inside the object. */
color c;
int x, y, size, size_mod;
/* Constructor. */
Circle(color c_, int x_, int y_, int size_, int size_mod_) {
c = c_;
x = x_;
y = y_;
size = size_;
size_mod = size_mod_;
}
/* Draw circle and modify size. */
void display() {
fill(c);
circle(x, y, size);
size += size_mod;
}
}
The code of the OOP version is longer and may look more complicated. The advantage is that all the properties of the circles (color, position, size, modifier of the size) are stored within the object itself. There are no global variables in use for that. This is of course a bigger advantage for larger programs. It’s also easier to reuse the code for other projects.
Example: Bars¶
Bar b1, b2, b3;
void setup() {
size(400, 500);
int barHeight = 20;
b1 = new Bar(0, barHeight, int(random(2, 6)));
b2 = new Bar(1*barHeight, barHeight, int(random(2, 6)));
b3 = new Bar(2*barHeight, barHeight, int(random(2, 6)));
noStroke();
}
void draw() {
b1.display();
b2.display();
b3.display();
}
class Bar {
int x, y, h, speed;
color c;
Bar(int y_, int h_, int speed_) {
x = 0;
y = y_;
h = h_;
speed = speed_;
c = get_color();
}
void display() {
fill(c);
rect(0, y, x, h);
x += speed;
}
int get_color() {
color c = color(random(0, 256), random(0, 256), random(0, 256));
return c;
}
}
/* Circle with OOP - more instances. */
Circle c1, c2, c3, c4;
void setup() {
size(400, 600);
noStroke();
// Initialize circles
c1 = new Circle(color(170, 172, 204, 150), width/2, height/2, 0, 1);
c2 = new Circle(color(250, 191, 171, 100), width/2, height/2, 400, -2);
c3 = new Circle(color(20, 191, 171, 120), width/2, height/2, 400, -1);
c4 = new Circle(color(170, 191, 204, 100), width/2, height/2, 0, -2);
}
void draw() {
background(222);
c1.display();
c2.display();
c3.display();
c4.display();
}
class Circle {
/* Data.
Size and the modifier for the size are stored
inside the object. */
color c;
int x, y, size, size_mod;
/* Constructor. */
Circle(color c_, int x_, int y_, int size_, int size_mod_) {
c = c_;
x = x_;
y = y_;
size = size_;
size_mod = size_mod_;
}
/* Draw circle and modify size. */
void display() {
fill(c);
circle(x, y, size);
size += size_mod;
}
}
Objects as data¶
Objects (instances of a class) are data types, thus it’s possible to store them in a list or insert them into another function or class.
Bars¶
ArrayList<Bar> bars;
void setup() {
size(400, 500);
bars = new ArrayList<Bar>();
int barHeight = 20;
for (int i = 0; i <= height/barHeight; i++) {
int y = i*barHeight;
int h = barHeight;
int speed = int(random(2, 6));
bars.add(new Bar(y, h, speed));
}
noStroke();
}
void draw() {
for (Bar b : bars) {
b.display();
}
}
class Bar {
int x, y, h, speed;
color c;
Bar(int y_, int h_, int speed_) {
x = 0;
y = y_;
h = h_;
speed = speed_;
c = get_color();
}
void display() {
fill(c);
rect(0, y, x, h);
x += speed;
}
int get_color() {
color c = color(random(0, 256), random(0, 256), random(0, 256));
return c;
}
}
ArrayList<Bar> bars;
void setup() {
size(400, 500);
bars = new ArrayList<Bar>();
int barHeight = 20;
for (int i = 0; i <= height/barHeight; i++) {
int y = i*barHeight;
int h = barHeight;
int speed = int(random(2, 6));
bars.add(new Bar(y, h, speed));
}
noStroke();
}
void draw() {
for (Bar b : bars) {
b.display();
}
}
class Bar {
int x, y, h, speed;
color c;
Bar(int y_, int h_, int speed_) {
x = 0;
y = y_;
h = h_;
speed = speed_;
c = get_color();
}
void display() {
fill(c);
rect(0, y, x, h);
x += speed;
if (x > width) {
c = get_color();
x = 0;
}
}
int get_color() {
color c = color(random(0, 256), random(0, 256), random(0, 256));
return c;
}
}
Circles¶
/* Objects stored and accessed through an ArrayList. */
ArrayList<Circle> circles;
void setup() {
size(400, 600);
noStroke();
// Initialize circles and add them to the list
circles = new ArrayList<Circle>();
for (int i = 0; i < 5; i++) {
color c = color(random(0, 256), random(0, 256), random(0, 256), random(0, 256));
int size = int(random(0, width));
int size_mod = int(random(-8, 8));
// avoid size_mod == 0
if (size_mod == 0) {size_mod = 1;}
circles.add(new Circle(c, width/2, height/2, size, size_mod));
}
}
void draw() {
background(222);
// Loop through the list of circles
for (Circle c : circles) {
c.display();
}
}
class Circle {
/* Data. */
color c;
int x, y, size, size_mod;
/* Constructor. */
Circle(color c_, int x_, int y_, int size_, int size_mod_) {
c = c_;
x = x_;
y = y_;
size = size_;
size_mod = size_mod_;
}
/* Draw circle and modify size. */
void display() {
fill(c);
circle(x, y, size);
// Invert size_mod if size is too big
if ((size >= width*2) || ((size * -1) >= width*2)) {
size_mod *= -1;
}
size += size_mod;
}
}
Example: irregular mapping¶
/* Code without a class. */
int num = 50;
int[][] xy1 = new int[num][2];
int[][] xy2 = new int[num][2];
int[][] xy3 = new int[num][2];
void setup() {
size(500, 300);
background(125);
noStroke();
noCursor();
fill(255, 102);
}
void draw() {
background(50);
// First
// Shift the values to the right
for (int i = num-1; i > 0; i--) {
xy1[i][0] = xy1[i-1][0];
xy1[i][1] = xy1[i-1][1];
xy2[i][0] = xy2[i-1][0];
xy2[i][1] = xy2[i-1][1];
xy3[i][0] = xy3[i-1][0];
xy3[i][1] = xy3[i-1][1];
}
// Add the new values to the beginning of the array
xy1[0][0] = mouseX;
xy1[0][1] = mouseX/2;
xy2[0][0] = mouseY;
xy2[0][1] = mouseX/2;
xy3[0][0] = mouseX;
xy3[0][1] = mouseY/2;
// Draw the circles
for (int i = 0; i < num; i++) {
circle(xy1[i][0], xy1[i][1], i/2.0);
circle(xy2[i][0], xy2[i][1], i/2.0);
circle(xy3[i][0], xy3[i][1], i/2.0);
}
}
/* Code with OOP - one instance. */
Trace t1;
void setup() {
size(500, 300);
background(125);
noStroke();
noCursor();
fill(255, 102);
// Init object
t1 = new Trace(50);
}
void draw() {
background(50);
t1.updatePos(mouseX, mouseX/2);
t1.display();
}
class Trace {
/* Data */
int num;
int[][] pos;
/* Constructor */
Trace(int num_) {
num = num_;
// Array for the previous positions
pos = new int[num_][2];
}
/* Add the new position to the array. */
void updatePos(float x, float y) {
// Shift existing values to the right
for (int i = num-1; i > 0; i--) {
pos[i][0] = pos[i-1][0];
pos[i][1] = pos[i-1][1];
}
// Add the new value at the beginning
pos[0][0] = int(x);
pos[0][1] = int(y);
}
/* Display circle. */
void display() {
for (int i = 0; i < num; i++) {
circle(pos[i][0], pos[i][1], i/2.0);
}
}
}
/* Code with OOP - multiple instances. */
Trace t1, t2, t3;
void setup() {
size(500, 300);
background(125);
noStroke();
noCursor();
fill(255, 102);
// Init object
t1 = new Trace(50);
t2 = new Trace(50);
t3 = new Trace(50);
}
void draw() {
background(50);
t1.updatePos(mouseX, mouseX/2);
t2.updatePos(mouseY, mouseX/2);
t3.updatePos(mouseX, mouseY/2);
t1.display();
t2.display();
t3.display();
}
class Trace {
/* Data */
int num;
int[][] pos;
/* Constructor */
Trace(int num_) {
num = num_;
// Array for the previous positions
pos = new int[num_][2];
}
/* Add the new position to the array. */
void updatePos(float x, float y) {
// Shift existing values to the right
for (int i = num-1; i > 0; i--) {
pos[i][0] = pos[i-1][0];
pos[i][1] = pos[i-1][1];
}
// Add the new value at the beginning
pos[0][0] = int(x);
pos[0][1] = int(y);
}
/* Display circle. */
void display() {
for (int i = 0; i < num; i++) {
circle(pos[i][0], pos[i][1], i/2.0);
}
}
}