Session 1: Based on the HTML5 and JavaScript Animated Circle exercise, we have seen that in order to make multiple instances of shapes on the canvas we need to duplicate many lines of code creating redundancies that make the code long and difficult to manage. This “brute force” technique might be acceptable for two or three shapes, but soon it becomes apparent that a better way must be possible. This is where Object Oriented Programming techniques are useful.
// Simple OOP example "Spot"
Spot sp; // Declare the object
void setup() {
size(200,200)
sp = new Spot(100,100,50); // Construct the object
}
void draw() {
background(0);
sp.display();
}
class Spot { // Define the class
float x,y,d; // x position, y position, diameter
Spot(float xpos, float ypos, float diameter) { // Constructor for the object
x = xpos;
y = ypos;
d = diameter;
}
void display() { // Method (function) to display the object
ellipse(x,y,d,d);
}
}
The example above creates a simple spot on the canvas as an object. Developing this example a little further allows for multiple instances of the object created in an array. Then properties such as the size, position, and speed of each spot can be adjusted to produce interesting results. Here’s an active version of the above script developed a little further.
OOP Animated Circles
More resources:
codepen.io
“CodePen is all about front end code inspiration and education through sharing. In the editor, enter HTML, CSS, and JavaScript and the combined result is displayed below. Save your Pen, share it, and explore others. This is extremely useful for showing off your work, troubleshooting, demonstrating bugs, or anything else you can think of.”
Here’s an example I made from last week’s demo:
Session 2: Today we will continue working on the HTML5 and Processing.js OOP exercise. I’ll be demonstrating some more examples of object oriented techniques using the Processing.js framework, including ways to interact with shapes rendered to the canvas.
void travel() {
translate(width/2, height/2);
rotate(PI/(3*(mouseX/800)));
x += (mouseX - x)/(s*40);
}
Also, let’s revisit an updated version of Bouncy Bubbles. This slightly more complex example of object oriented code gives us an opportunity explore the simulation of gravity and collisions.
// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated. UPDATE: by John Keston to include ball color and reset method.
int numBalls = 50;
float spring = 0.05;
float gravity = 0.2;
Ball[] balls = new Ball[numBalls];
void setup() {
size(600, 400);
//noStroke();
smooth();
for (int i = 0; i < numBalls; i++) {
balls[i] = new Ball(random(width), random(height), random(20, 40), i, balls,random(255),random(50),random(100));
}
}
void mouseClicked() {
for (int i = 0; i < numBalls; i++) {
balls[i].reset();
}
}
// Or, add a new ball each time the mouse is clicked
/* void mouseClicked() {
numBalls += 1;
balls.add(new Ball(mouseX, mouseY, random(20, 40), numBalls, balls,random(255),random(50),random(100)));
} */
void draw()
{
background(128);
for (int i = 0; i < numBalls; i++) {
balls[i].collide();
balls[i].move();
balls[i].display();
}
}
class Ball {
float x, y;
float diameter;
float vx = 0;
float vy = 0;
int r,g,b,id;
Ball[] others;
Ball(float xin, float yin, float din, int idin, Ball[] oin, int cr, int cg, int cb) {
x = xin;
y = yin;
diameter = din;
id = idin;
r = cr;
g = cg;
b = cb;
others = oin;
}
void collide() {
for (int i = id + 1; i < numBalls; i++) {
float dx = others[i].x - x;
float dy = others[i].y - y;
float distance = sqrt(dx*dx + dy*dy);
float minDist = others[i].diameter/2 + diameter/2;
if (distance < minDist) {
float angle = atan2(dy, dx);
float targetX = x + cos(angle) * minDist;
float targetY = y + sin(angle) * minDist;
float ax = (targetX - others[i].x) * spring;
float ay = (targetY - others[i].y) * spring;
vx -= ax;
vy -= ay;
others[i].vx += ax;
others[i].vy += ay;
}
}
}
void move() {
vy += gravity;
x += vx;
y += vy;
if (x + diameter/2 > width) {
x = width - diameter/2;
vx *= -0.9;
}
else if (x - diameter/2 < 0) {
x = diameter/2;
vx *= -0.9;
}
if (y + diameter/2 > height) {
y = height - diameter/2;
vy *= -0.9;
}
else if (y - diameter/2 < 0) {
y = diameter/2;
vy *= -0.9;
}
}
void reset() {
x = mouseX;
y = mouseY;
}
void display() {
fill(r,g,b,204);
ellipse(x, y, diameter, diameter);
}
}
Original example (Bouncy Bubbles) on Processing.js.