> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.X55vhZIzHED/rev.10
 * 
 * authors: 
 *   GoToLoop

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



/**
 * Fireworks (v2.0)
 * by  JManton1992 (2013/Apr)
 * mod GoToLoop
 * 
 * http://forum.processing.org/topic/
 * i-know-this-is-bad-but-would-anyone-be-able-to-explain-this-code
 * -i-ve-only-began-using-processing-in-college
 * -and-i-need-to-replicate-this-code-with-some-understanding
 *
 * http://studio.processingtogether.com/sp/pad/export/ro.9Q6oRai8-41WJ/latest
 */

final static byte MAX_FIRES = 15;
final static Firework[] fires = new Firework[MAX_FIRES];

final static color  BG = 0x14320028;
final static String ENGINE = JAVA2D;  //JAVA2D or P2D

void setup() {
  size(400, 400, ENGINE);
  frameRate(50);
  smooth();
  fill(BG);

  for ( int i=0; i!=MAX_FIRES; fires[i++] = new Firework() );
}

void draw() {
  noStroke();
  rect(0, 0, width, height);

  for (Firework fw: fires)  fw.display();
}

void mousePressed() {
  for (Firework fw: fires)
    if (fw.isInactive) {
      fw.launch();
      return;
    }
}

final class Firework {
  int x, y, targetY;
  int flareAmount, flareWeight, colour;
  int explodeTimer, explosionDuration;

  float flareAngle;
  boolean hasExploded, isInactive = true;

  final static color FG  = -1;
  final static byte  SPD = 2, BOLD = 2;

  void display() {
    if (isInactive)   return;

    if (hasExploded)  exploding();
    else              rising();
  }

  void rising() {
    launchMaths();

    strokeWeight(BOLD);
    stroke(FG);
    point(x, y);
  }

  void exploding() {
    explodeMaths();

    strokeWeight(flareWeight);
    stroke(colour);

    translate(x, y);

    for (int i = flareAmount+5; i != 0;) {
      float rad = radians(--i*flareAngle);
      point(sin(rad)*explodeTimer, cos(rad)*explodeTimer);
    }

    resetMatrix();
  }

  void launch() {
    activate();

    x = mouseX;
    y = height;
    targetY = mouseY;

    colour = color(random(3)*50 + 105, 
    random(3)*50 + 105, random(3)*50 + 105);

    flareAmount = ceil( random(30) ) + 20;
    flareWeight = ceil( random(3) );
    explosionDuration = 20*ceil( random(4) ) + 30;

    //makes explosion a full circle:
    flareAngle  = 360/flareAmount;
  }

  void launchMaths() {
    if (targetY - (y -= SPD) > 0)  explode();
  }

  void explodeMaths() {
    if (++explodeTimer > explosionDuration)  disable();
  }

  void explode() {
    explodeTimer = 0;
    hasExploded  = true;
  }

  void disable() {  
    isInactive  = true;
  }

  void activate() {
    isInactive = hasExploded = false;
  }
}