ArrayList<Movable> movables;
int ballWidth = 48;
int randomLast = 0; // to feel random, it has to be not random
void setup() {
size(800, 600);
noStroke();
// Create an empty ArrayList (will store Ball objects)
movables = new ArrayList<Movable>();
randomSeed(millis()+second()); // it's random enough
}
void draw() {
// background(255);
rectMode(CORNER);
stroke(0);
strokeWeight(2);
fill(255);
rect(0, 0, width - 1, height - 1); // show a border
// With an array, we say balls.length, with an ArrayList, we say balls.size()
// The length of an ArrayList is dynamic
// Notice how we are looping through the ArrayList backwards
// This is because we are deleting elements from the list
for (int i = movables.size()-1; i >= 0; i--) {
// An ArrayList doesn't know what it is storing so we have to cast the object coming out
Movable movable = movables.get(i);
movable.move();
movable.display();
if (movable.finished()) {
// Items can be deleted with remove()
movables.remove(i);
}
}
}
void mousePressed() {
// A new object is added to the ArrayList (by default to the end)
int i;
do{
i = (int)random(3000) % 3;
}while(i == randomLast);
randomLast = i;
switch( i ) {
case 0:
movables.add(new Ball(mouseX, mouseY, ballWidth+random(ballWidth / 2)));
break;
case 1:
movables.add(new Box(mouseX, mouseY, ballWidth+random(ballWidth / 2), ballWidth+random(ballWidth / 2) ));
break;
case 2:
movables.add(new Triangle(mouseX, mouseY, ballWidth+random(ballWidth / 2)));
break;
}
}
class Ball extends Movable {
float w;
Ball(float tempX, float tempY, float tempW ) {
super( tempX, tempY ); // call the parent
w = tempW;
}
void display() {
super.display(); // do it first
noStroke();
ellipse(x, y, w, w);
}
}
class Box extends Movable {
float w, h;
float ang;
Box(float tempX, float tempY, float tempW, float tempH) {
super( tempX, tempY );
w = tempW;
h = tempH;
ang = 0.0;
}
void display() {
// without calling super let's do something else
fill( 255, 0, 0, life); // let's make it red
noStroke();
ang += 1.0;
pushMatrix(); // try google what this is
rectMode(CENTER);
translate(x, y);
rotate(radians(ang));
rect(0, 0, w, h);
popMatrix();
}
}
class Triangle extends Movable {
float w;
float ang;
Triangle(float tempX, float tempY, float tempW ) {
super( tempX, tempY ); // call the parent
w = tempW;
ang = 0.0;
}
void display() {
// without calling super let's do something else
fill( 0, 0, 255, life); // let's make it blue
strokeWeight(1);
stroke(0, life);
ang += 1.0;
pushMatrix(); // try google what this is
translate(x, y);
rotate(radians(ang));
triangle( -w/2, -w/2, 0, w/2, w/2, -w/2 );
popMatrix();
}
}
// Simple movable class
class Movable {
float x;
float y;
float speed;
float speedx;
float gravity;
float life = 512;
Movable(float tempX, float tempY) {
x = tempX;
y = tempY;
speed = 0;
gravity = 0.1;
speedx = random(-3,3);
}
void move() {
// Add gravity to speed
speed = speed + gravity;
// Add speed to y location
y = y + speed;
// If square reaches the bottom
// Reverse speed
if (y > height) {
// Dampening
speed = speed * -0.8;
y = height;
}
// x move
x = x+speedx;
if( x < 10 && speedx < 0){
speedx = -speedx;
}
if( x > width - 10 && speedx > 0 ){
speedx = -speedx;
}
}
boolean finished() {
// Balls fade out
life--;
if (life < 0) {
return true;
} else {
return false;
}
}
void display() {
fill(0, life);
}
}