Bubble popping animation

Me and my son looked at this tonight.
We have been taking baby steps and much of this code is way beyond our level as we follow the “Learning Processing” book and tutorials by Daniel Shiffman. We sertanly notice progress by the fact we are actually seeing things in the code examples more now than before!. :joy:
Really cool! :slight_smile:

There is some things we couldn’t figure out.
Our bubble is made with variables all along so everything connects. This is so we can set it to a different size and the wobble will adapt.
When we tries to do this with the “bullets” (now renamed fallouts in the code) we cant figure out how to change this.

We changed the “final float RADIOUS = 1,8” to a variable called “rad” that is based on the bubble dimeter/2. This worked to make the fallout start from the bubble edge :slight_smile:

Then we want to be able to change the number of fallouts depending on the size of the bubble but this we couldn’t find.
The number seems to be hardcoded here:
final float ANGLE_INCREMENT = TWO_PI/10;
and
for (int i=0; i<10; i++) {
I tried using fallout.lenght and “i” but it didn’t work in this case?

We also want to change how far and how fast the fallout moves. We want to have it move a bit less and maybe try some small random here. Could find where to do this?
Is it possible to create the dots a little more random around the circle? just some pixels? So it doesn’t look so perfect :slight_smile:

Then we cant figure out this:

class Fallout { 
  // Bullet

  float posX, posY; **// pos and dir variables crated, no values..**
  float dirX;
  float dirY;

  int fade = 255; 

  Fallout (float x, float y, **// x,y,dx and dy variables created, where do they get there values from?**
    float dx, float dy) {
    posX = x; **// variables with values taken from somewhere and used where? Now getting what value** 
    posY = y;
    dirX = dx;
    dirY = dy;

Also some small question marks.

  • Why is riseY reminding the program of its original values in FALL already and not in RESTART?
  • The default state? when does this appear? And the exit() line. Does it close the viewer?

Played around with it some more and this is what I came up with…
Still cant figure out a lot of the above…

Bubble b1;

void setup() {
  size(640, 360);
  b1 = new Bubble(50);
}

void draw() {
  background(0);
  b1.all();
}

void mousePressed() {
  if (b1.over()) {
    b1.fall();
  }
}




class Bubble {

  // constants: these are values that state can have (must be unique (0,1,2...))
  final int RISE    = 0;   // the word final makes them constants 
  final int FALL    = 1; 
  final int RESTART = 2; 
  // variable: current value of the state
  int state=RISE;  // not a state of the program, but the state of the ball

  float tempSize;
  float w;
  float h;
  boolean move = true;
  float maxW;
  float maxH;
  float minW;
  float minH;
  float wspeed;
  float hspeed;
  float riseY = random(0.8, 3);
  float riseStart;
  float start = random(0, 640);
  float gravity = 0.3;
  float rad;

  Fallout[] fallouts; //might want to use a list (ArrayList)


  Bubble(float tempSize) { // <----------------- Bubble takes value from tab 1 and makes tempSize
    
    w = tempSize;
    h = tempSize;
    riseStart = tempSize + height;

    rad=tempSize/2;
    maxW = w*1.1+random(0, maxW/2);
    maxH = h*1.1+random(0, maxH/1);
    minW = w/1.1;
    minH = h/1.1;
    wspeed = w/100;
    hspeed = h/75;

    //println(tempSize);
  }

  void all() {
    stroke(255,255);
    // all (or script()) 

    //print("Y ", mouseY);
    //print("  RS ", b1.riseStart);
    //print("  X ", mouseX);
    //println("  Start", b1.start);

    switch(state) {

    case RISE: 
      show(); 
      move();
      top(); 
      break; 

    case FALL: 
      riseY = riseY - gravity;
      riseStart = riseStart - riseY;
      ellipse(start, riseStart, 
        3, 3); // new small ball
      showExplosion();
      if (riseStart>height+133) {  // lower screen border
        state = RESTART;
        riseY = random(0.8, 3); // Why do we put this hera and not in case RESTART?
      }
      break; 

    case RESTART: 
      // restart 
      state = RISE; 
      riseStart = tempSize + height+100;
      start = random(w, width-w);
      break;

    default: // What does this state do? When does it run?
      // Error 
      println("Error. Unknown state ");
      exit();    
      break; 
      //
    }//switch 
    //
  } // method 

  void show() {
    //noFill();
    //stroke(255);
    noFill();
    stroke(255,255); 
    strokeWeight(1);
    ellipse (start, riseStart, 
      w, h);

    if (move) {
      w = w + wspeed;

      if ((w > maxW) || (w < minW)) { // Makes bubble wobble.
        wspeed = wspeed * -1;
      }

      if (move) {
        h = h + hspeed;
      }
      if ((h > maxH) || (h < minH)) { // Makes bubble wobble.
        hspeed = hspeed * -1;
      }
    }
  }

  void move() {
    riseStart = riseStart - riseY;
  }

  void top() {
    if (riseStart < tempSize - tempSize -100) { 
      state=RESTART;
    }
  }

  void fall() {
    state=FALL;
    explode();
  }

  boolean over() {
    // returns true or false; true when mouse is on balloon.
    // You had this in mousePressed before. 
    return 
      (mouseX < start + w/2) && 
      (mouseX > start - w/2) &&
      (mouseY < riseStart + h/2) && 
      (mouseY > riseStart - h/2);
  }

  void showExplosion() {
    for (int i = 0; i < fallouts.length; i++) {
      fallouts[i].display();
      fallouts[i].move();
    }//for
  }

  void explode() {

    final float RADIUS = rad;
    println(rad);
    final float ANGLE_INCREMENT = TWO_PI/15; 
    //2PI would only shoot down, PI is up down, 
    //halfPi is in 4 dirs and so on
    //you can also just use some random number like 0.3256
    //but try keeping it within 0-2PI

    // full reset 
    fallouts = new Fallout[0];

    for (int i=0; i<15; i++) {
      float angle=i*ANGLE_INCREMENT; 
      // make a new bullet at CURRENT POSITION : start, riseStart
      Fallout newFallout = new Fallout(
        cos(angle)*RADIUS+start, sin(angle)*RADIUS+riseStart, 
        cos(angle)*0.8, sin(angle)*0.8);
      // append it to array
      fallouts = (Fallout[]) append(fallouts, newFallout);
    }
  }
}//class




class Fallout { 
  // Bullet

  float posX, posY;
  float dirX;
  float dirY;

  int fade = 255; 

  Fallout (float x, float y, 
    float dx, float dy) {
    posX = x;
    posY = y;
    dirX = dx;
    dirY = dy;
  }

  void display() {
    fill(255, fade); 
    noStroke();
    ellipse(posX, posY, 
      1, 1);
  }

  void move() {
    posX+=random(-dirX/5,dirX);
    posY+=random(dirY,-dirY/2);
    fade-=20;
  }
  //
}//class