OOP

Intro on processing.org

Example: Circles

scope_counter_updown


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

oop_bars_1


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;
  }
}

oop_circles


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

oop_bars_2


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;
  }
}

oop_bars_3


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;
  }
}

oop_circles_2


Example: irregular mapping

arrays_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);
    }
  }
  
}