Hi all. Here is some simple code slightly modified from some teaching material I use with my students. Hope it is useful!
void setup() {
size(960, 540, P2D);
background(0);
smooth(8);
createBubbles(100);
}
void draw() {
background(0);
doBubbles();
}
void mousePressed() {
checkIfBubbleHit(mouseX, mouseY);
}
//////////////////////////////
// BUBBLE CLASS AND HELPERS //
//////////////////////////////
// An arraylist to hold all the bubbles
ArrayList<Bubble> bubbles = new ArrayList<Bubble>();
// An easy way to make lots of them
void createBubbles(int _thisMany) {
for (int i = 0; i < _thisMany; i++) {
bubbles.add(new Bubble());
}
}
// An easy way to step through, update and display them all
void doBubbles() {
for (Bubble b : bubbles) {
b.update();
b.display();
}
}
// Check all bubbles to see if they have been clicked on
void checkIfBubbleHit(int _mx, int _my) {
for (Bubble b : bubbles) {
b.checkIfHit(_mx, _my);
}
}
//////////////////
// BUBBLE CLASS //
class Bubble {
float x, y, diam, diamBurst, floatSpeed;
float originalDiam;
int wobbleOffset = int(random(10000));
int state = 0; // 0 = normal; 1 = clicked;
Bubble() {
reset();
}
void reset() {
diam = random(40, 70);
originalDiam = diam; // we use this for our burst dots mapping
x = random(diam, width - diam);
y = height + (diam/2);
floatSpeed = random(0.5, 2);
diamBurst = diam + 50;
state = 0;
}
void update() {
switch(state) {
case 0: // normal rising bubble
y = y - floatSpeed;
if (y <= -diam/2) {
reset(); // off the top without being clicked? reset to bottom
}
break;
case 1: // bubble has been clicked on
diam = lerp(diam, diamBurst, 0.1); // burst!
break;
}
}
void display() {
switch(state) {
case 0: // normal rising bubble
fill(255, 32);
stroke(255);
strokeWeight(1);
// simple wobble using sin, cos and frameCount
// random wobbleOffset variable means they don't all wobble at the same time
float xDiam = diam + sin(radians(wobbleOffset + frameCount*5))*5;
float yDiam = diam + cos(radians(wobbleOffset + frameCount*5))*5;
ellipse(x, y, xDiam, yDiam);
break;
case 1: // bursting bubble
// draw the burst dots
int numBurstDots = 60;
float angleStep = radians(360.0/numBurstDots);
strokeWeight(3);
float burstDotAlpha = map(diam, originalDiam, diamBurst, 255, 0); // makes our burst dots fade out
stroke(255, burstDotAlpha);
for (int i = 0; i < numBurstDots; i++) {
float bx = sin(angleStep*i)*diam/2;
float by = cos(angleStep*i)*diam/2;
point(x + bx, y + by);
}
if (diam >= diamBurst) { // burst yet?
reset(); // reset it!
}
break;
}
}
void checkIfHit(int _mx, int _my) {
// check distance from centre of bubble
if (dist(x, y, _mx, _my) < diam/2) {
state = 1;
}
}
}