Bubble popping animation

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