var assets = ["logo.png", "bomb.png", "fuse.mp3", "boom.mp3", "warble.mp3"];
var path = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/1604712/";

const frame = new Frame("fit", 1024, 768, black, darker, assets, path, new Waiter({corner:0, backgroundColor:pink}));
frame.on("ready", ()=>{ // ES6 Arrow Function - similar to function(){}
    zog("ready from ZIM Frame"); // logs in console (F12 - choose console)

    // often need below - so consider it part of the template
    let stage = frame.stage;
    let stageW = frame.width;
    let stageH = frame.height;
  
    // REFERENCES for ZIM at http://zimjs.com
    // see http://zimjs.com/learn.html for video and code tutorials
    // see http://zimjs.com/docs.html for documentation
    // see https://www.youtube.com/watch?v=pUjHFptXspM for INTRO to ZIM
    // see https://www.youtube.com/watch?v=v7OT0YrDWiY for INTRO to CODE
  
    // THIS CODE was from a THREE HOUR build it exam for our Sheridan Interactive Media One-year Post Grad program.
    // Taken after 8 days of lessons - one day a week - class of 28 got an 80% average.
  
    // CODE HERE  

    // 1. Make a new label and assign it to label
    // Make the label white and have the text: "ZIM Fuse!  Light the fuse - then visit ZIM!"
    // set the alpha to .6 and the scale to .8 and position it on the stage at 30, 30
    const label = new Label({color:white, text:"ZIM Fuse!  Light the fuse - then visit ZIM!"})
      .alp(.6)
      .sca(.8)
      .pos(30,30)

    // 2. The points data comes from using a recordPoints(true) method - or see https://zimjs.com/nio/paths.html
    // Make the Squiggle have a thickness of 1 and not be interactive
    // Scale the Sqiggle twice as big and center it on the stage
    const points = [[-50.4,11.8,0,0,-30,0,30,0],[26.8,88.7,0,0,-36.7,3.7,36.7,-3.7],[12.2,-42.6,0,0,41.1,-23.5,-41.1,23.5],[82.7,23.9,0,0,-31.4,49.2,31.4,-49.2],[192.9,-73.4,0,0,-65.6,30.4,65.6,-30.4],[199.2,-19.4,0,0,-146.7,-105.1,146.7,105.1],[249.3,2.8,0,0,-5.7,-136.5,5.7,136.5],[164.7,80.7,0,0,-46.5,22.7,46.5,-22.7],[247.7,125.9,0,0,-39.2,5.5,39.2,-5.5],[181.7,27.7,0,0,57.7,17.8,-57.7,-17.8]];
    const fuse = new Squiggle({thickness:1, interactive:false, points:points}).sca(2).center();

    // 3. Make the bomb using the bomb image, scale it to .3, set its alpha to .5 and centerReg it on the stage
    const bomb = frame.asset("bomb.png")
      .sca(.3)
      .alp(.5)
      .centerReg()
  

    // 4. Create a match to light the fuse
    // this will be in a Container called match - do not set the dimensions of the container
    // add a 6x100 Rectangle with a color of tin to the match container
    // expand() the rectangle so that it is easier to drag
    const match = new Container();
    new Rectangle(6,100,tin).addTo(match).expand(); // make it easier to drag

    // 5. Create the fire with an Emitter()
    // a. The particle should be an orange circle with a radius of 5 and an alpha of .6
    // b. Use the random parameter of the Emitter to randomize the scaleX between 1.3 and 1.5
    // c. and the scaleY between 2.3 and 2.5 - this makes the flame taller than it is wide
    // d. Set the width and height of the Emitter to 20 and 40
    // e. Set the interval to 20, the life to 1000, the gravity to -2
    // f. Set the force to between a min of .2 and a max of .4 (using ZIM VEE)
    // g. Set the angle to between a min of -130 and a max of -50 (using ZIM VEE)
    // h. centerReg the Emitter and add it to the match - then move it up 40 pixels

    const fire = new Emitter({
      obj:new Circle(5, orange).alp(.6),
      random:{
        scaleX:{min:1.3, max:1.5},
        scaleY:{min:2.3, max:2.5}
      },
      width:20,
      height:40,
      interval:20,
      life:1000,
      gravity:-2,
      force:{min:.2, max:.4},
      angle:{min:-90-40, max:-90+40}
    })
    .centerReg(match).mov(0,-40);

    // 6. locate the match at the first point of the fuse - use the pointControls array (property of a Squiggle)
    // then move the match down 200
    // set the alpha of the match to 0 and animate in the alpha over 1 second to fade it in
    // set drag on the match with a drag boundary to a ZIM Boundary()
    // the Boundary() should have the match's current location in the x, 100 in the y
    // and no width (so it can't move in the x) and 500 for the height
    match.loc(fuse.pointControls[0])
      .mov(0,200)
      .alp(0)
      .animate({props:{alpha:1}, wait:1000})
      .drag({boundary:new Boundary(match.x,100,0,500), all:true});


    // 7. Make a zim Pen() and store it in pen
    // the pen will have a size of 4, a color of black and no damping
    // centerReg the pen on the stage
    // animate the pen props along the fuse path and orient false
    // wait 100 ms for the pen to be created
    // animate for a time of 10 seconds with a linear ease
    // EVENTUALLY, we will want set startPaused to true so the pen does not animate right away
    // so add this in and test it - comment it out as needed

    const pen = new Pen({damp:false, size:4, color:black}).centerReg().animate({
      props:{path:fuse, orient:false},      
      wait:100,
      time:10000,
      ease:"linear",
      startPaused:true,
    })

    // 8. Create an emitter for the spark 
    // The emitter will use a shape object {type:shape} for its obj property
    // the shape object will also have a stroke (s) of either blue or white (use ZIM VEE)
    // and a strokeSize (ss) of 3
    // The emitter will have an interval of 50, a num of 10, a life of 200 and a decayTime of 200
    // EVENTUALLY, the emitter will have its startPaused parameter set to true - you can comment this to test, etc.
    // centerReg the emitter (important)
    const spark = new Emitter({
      obj:{type:"shape", s:[blue, white], ss:3},
      interval:50,
      num:10,
      life:200,
      decayTime:200,
      startPaused:true
    })
    .centerReg()

    // 9. animate the emitter along the fuse squiggle with the SAME animate parameters as the Pen
    // and set the startPaused parameter to true - and comment as needed in testing, etc.
    // add a call parameter that calls a function that removes the spart and the fuse from the stage
    // In this function also call the makeExplosion() function to go to the next step
    // This way, the explosion will happen when the spark animation is done!
    .animate({
      props:{path:fuse, orient:false},      
      wait:100,
      time:10000,
      ease:"linear",
      startPaused:true,
      call:function () {
        spark.removeFrom();
        fuse.removeFrom();
        makeExplosion();
      }
    });


    // 10. Add a pressmove event to the match and collect the event object (e)
    // Inside the pressmove function, do a hitTestBounds for the following:
    // check if the first circle control point of the fuse squiggle is hitting the fire
    // use the pointCircles array property of the Squiggle - get the first element of the array
    // If these are hitting then do the following:
    // a. run the pen animation - use pauseAnimate(false)
    // b. run the spark animation
    // c. run the spark emitter - also use pauseEmitter(false)
    // d. animate the alpha of the match to 0 in 500 ms
    // e. animate the alpha of the label to 0 in 4000 ms - slow fade
    // f. assign the playing of the fuse sound to the variable fuseSound (do not use var)
    // adjust the sound with a sound object literal inside the play() method
    // make the sound be at a volume of .3 and a loop of -1 (sorry - that is CreateJS's way)
    // g. you have probably not seen this - but remove the event by using e.remove();
    // this will make it so we do not repeatedly do these things as the match continues to hit the fuse

    match.on("pressmove", function (e) {
      if (fuse.pointCircles[0].hitTestBounds(fire)) {
        pen.pauseAnimate(false);
        spark.pauseAnimate(false);
        spark.pauseEmitter(false);
        match.animate({alpha:0}, 500);
        label.animate({alpha:0}, 4000);
        bomb.animate({props:{alpha:1}, time:2000, wait:8000});
        fuseSound = frame.asset("fuse.mp3").play({volume:.3, loop:-1});
        e.remove();
      }
    });

    function makeExplosion() {

      // 11. Create the explosion Emitter and store it in an explosion variable (use var this time!)
      // set the obj to either a Rectangle 25x25 or a Circle with radius 15 (use ZIM VEE)
      // make the num 10 and a force of 10
      // randomize the following in the random parameter:
      // the rotation between a min of 0 and max of 360
      // the color to be blue or pink randomly
      // the regX to be a min of -50 and max of 50
      // the regY to be a min of -50 and max of 50
      // These make the particles start spread out over the bomb
      // pause the emitter with startPaused true
      var explosion = new Emitter({
        obj:[new Rectangle(25,25), new Circle(15)],
        num:10,
        force:10,
        random:{
          rotation:{min:0, max:360},
          color:[blue, pink],
          regX:{min:-50, max:50},
          regY:{min:-50, max:50},
        },
        startPaused:true
      }).centerReg();

      // 12. On the next line make the emitter spurt() with a time of 500 ms
      // Play the boom sound
      // stop() the fuse sound ** comment this out if not running the other parts
      // animate the bomb to an alpha of 0 in 100 ms ** comment this out if not running the other parts
      explosion.spurt({time:500});
      frame.asset("boom.mp3").play();
      fuseSound.stop();
      bomb.animate({alpha:0}, 100);


      // 13. centerReg the logo asset on the stage
      // set its alpha to 0, its scale to 0
      // set the cur() to see a pointer
      // and expand() it to be clickable between the letters
      frame.asset("logo.png")
        .centerReg() // make it scale from the middle
        .alp(0)
        .sca(0)
        .cur()
        .expand() // make it so we can click between the letters

      // 14. Animate the logo to props of alpha 1 and scale 1
      // wait 800 ms for explosion to almost finish
      // animate for 2300 ms with an elasticOut ease
      // once the animation has waited, call a function (use waitedCall)
      // and in this function play the warble sound at a volume of .8
      // When we click on the logo make it zgo() to https://zimjs.com in a new window
      // YOU ARE DONE!
        .animate({
          props:{alpha:1, scale:1},
          wait:800,
          time:2300,
          ease:"elasticOut",
          waitedCall:function () { // play the sound once we have waited
            frame.asset("warble.mp3").play({volume:.8});
          }
        })
        .tap(function () {zgo("https://zimjs.com", "_blank");});

 
    }
  
    // DOCS FOR ITEMS USED
    // https://zimjs.com/docs.html?item=Frame
    // https://zimjs.com/docs.html?item=Container
    // https://zimjs.com/docs.html?item=Circle
    // https://zimjs.com/docs.html?item=Rectangle
    // https://zimjs.com/docs.html?item=Squiggle
    // https://zimjs.com/docs.html?item=Label
    // https://zimjs.com/docs.html?item=Waiter
    // https://zimjs.com/docs.html?item=tap
    // https://zimjs.com/docs.html?item=drag
    // https://zimjs.com/docs.html?item=hitTestBounds
    // https://zimjs.com/docs.html?item=animate
    // https://zimjs.com/docs.html?item=pauseAnimate
    // https://zimjs.com/docs.html?item=cur
    // https://zimjs.com/docs.html?item=pos
    // https://zimjs.com/docs.html?item=mov
    // https://zimjs.com/docs.html?item=alp
    // https://zimjs.com/docs.html?item=sca
    // https://zimjs.com/docs.html?item=addTo
    // https://zimjs.com/docs.html?item=removeFrom
    // https://zimjs.com/docs.html?item=centerReg
    // https://zimjs.com/docs.html?item=center
    // https://zimjs.com/docs.html?item=expand
    // https://zimjs.com/docs.html?item=Emitter
    // https://zimjs.com/docs.html?item=Boundary
    // https://zimjs.com/docs.html?item=zog
    // https://zimjs.com/docs.html?item=zgo
  
    // FOOTER
    // call remote script to make ZIM Foundation for Creative Coding icon
    createIcon(frame); 
    
    stage.update(); // this is needed to show any changes

}); // end of ready

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://d309knd7es5f10.cloudfront.net/createjs_1.1_min.js
  2. https://d309knd7es5f10.cloudfront.net/zim_9.2.1.js
  3. https://d309knd7es5f10.cloudfront.net/codepen/icon3.js