Creating Animated Confetti Using ActionScript 2

Get Adobe Flash player




Today we will learn to make animated confetti using ActionScript 2. We will learn how to instantiate multiple instances of a movie clip in the library by exporting it for ActionScript and then move each piece of confetti in a manner that is typical of confetti. This tutorial is great for banner and greeting card animators who are looking to save some k-size and create interesting dynamic animations at runtime. The principals learned here can be applied to create particle effects as well.


Description:
Create a festive animation of confetti. Confetti is thrown in the air and then slowly cascades down landing on the floor.

Prerequisites:
Basic understanding of Flash.
Intermediate understanding of ActionScript 2.
Some experience with code-based movement using Actionscript 2.
Understanding and implementation of TweenLite/TweenMax tween engine.

You can either download the completed example , or follow along and start from scratch.

1. Open a new AS2 Flash Document and save it as confetti_as2.fla.
2. Go to the first frame of the time line and draw a small blue circle with the circle tool.
Draw a little blue circle
3. Fill it light blue, #7FCDEC using the properties window as shown above in Figure 1.
4. Select it and hit F8 create movie clip. Name it “confetti” and make sure the registration is centered.
Export confetti for ActionScript
5. Using linkage, export confetti for ActionScript by checking the boxes as shown in Figure 2 above. Press ok. Delete the confetti movie clip off the stage, but it should remain in your library.
6. Go back to the now vacant first frame of the time line and name the layer AS 2. Its a good habit to lock it.
7. Click on the first frame of AS 2 layer and open the actions panel.

Tip: Before writing any code, I like to make an outline of my project in the comments of my code. Kind of like an outline of an essay. These will eventually be the functions that make up my animation. The best way to make an outline is to think of what you will be required to do as an animator and developer to get this job done.

We will be required as a developer and animator to:

Some things we will need to do to sell this as confetti to the human eye.

Now we know what we have to do lets start writing some code.

8. Start importing.
I’ve decided to use TweenFilterLIte because it can move an object and change its color and generate the lowest possible k-size (approximately 6K). See editors notes below regarding TweenFilterLite.

  1. // Imports
  2. import gs.TweenFilterLite;

9. Lets make a quick array to hold the two colors of the confetti piece.

  1. // Arrays
  2. var colorArray:Array = [0×004986, 0x7fcdec];

You will notice that the movie clip in our library is light blue. We are going to want to make it dark blue on the “flip side”. We’ll create a flip side by combining a color change with the timing of y scale hitting zero or 100. This should create a nice horizontal flipping effect for our piece of confetti.

10. Create variables. On Line 7, type in this code.

  1. // Variables
  2. var home = this;// main timeline moveable
  3. var horizonLevel:Number;// where confetti falls to
  4. var top:Number = -200;// where confetti falls from
  5. var numOfConfetti:Number = 50;// how many pieces

Line 8 is a little trick that is optional. I generally like to name the main timeline Home for easy reference later. This has nothing to do with confetti, it is just a personal choice when it comes to navigating the display list in AS2. The next variable is the horizonLevel. This is a number that collectively will establish the horizon line by serving as a final resting place for each piece of our confetti. This will define the sky from the floor without any additional artwork. The next variable is top, another number variable is an offstage y position where our confetti will fall from. The final variable on Line 11, numOfConfetti will be how many pieces of confetti we will instantiate. Note that with any particle effect that runs on enterFrame will have a direct effect on CPU performance so a variable for the number of pieces is a good idea. This allows you to increase or decrease the amount of pieces accordingly a lot quicker.

There are more variables we’ll need such as direction of the confetti and speed, but those will be local variables to each piece.

11. Set up an init() function and create some timers.

  1. // Functions
  2. stop();
  3. init();
  4.  
  5. function init() {
  6.  startTimers();
  7. }
  8.  
  9. function startTimers() {
  10.  trace("[f] Start Timers");
  11.  setUpTimer = setTimeout(setUp, 0);
  12.  confettiThrowTimer = setTimeout(confettiThrow, 0);
  13.  confettiFallTimer = setTimeout(confettiFall, 1500);
  14. }

Even with simple procedural code it is generally a good idea to wrap everything up in functions and start the whole thing off with an init() function. In banner animations and games its common to use the setTimeout() method and place your functions inside as parameters essentially creating timers that fire off your functions. The method takes two parameters, the function you want to run and how many milliseconds before it runs.

In our case, we’ll set up all of our stuff at 0 seconds in the setUpTimer by firing off a function called setUp() and at the same instance we’ll instantiate some confetti with a function we”ll call confettiThrow(). The next function that will be fired off will be confettiFall(). Remember our outline? 1. instantiate the pieces of confetti and make the confetti appear to be thrown up in the air. Well, that is being handled by the two functions, confettiThrow() and confettiFall(). Pretty simple right?

Well, there is a tad more to it than that, but for now lets comment out the confettiFallTimer and focus on creating multiple instances of the confetti.

Ok, lets get to the first two of our three functions, setUp() and confettiThrow();

First off we need to set up our stuff. We’ll do this in the first function fired off by our setUpTimer called setUp().

  1. function setUp() {
  2.  // if looped, clear enterframe event
  3.  this.onEnterFrame = null;
  4.  //create background which will hold the confetti
  5.  home.createEmptyMovieClip("bckgrnd",1000);
  6. }

Here we’re creating two movie clips that contain everything. One clip will hold the confetti animation and the other clip will hold the play button. This makes it easier to move the button in front of the confetti or vice versa.

12. Instantiate the confetti
In simpler terms, lets create a bunch of confetti to throw. We will do this with our second function that was fired off by one of our timers at zero seconds. On line 36 begin typing the following code.

  1. // create confetti to throw
  2. function confettiThrow() {
  3.  trace("[f] Throw Confetti");
  4.  for (var i = 0; i<numOfConfetti; i++) {
  5.   // create a piece of confetti to throw
  6.   var piece:Object = bckgrnd.attachMovie("confetti", "confetti"+i, i);
  7.   // place random x
  8.   piece._x = Math.random()*Stage.width;
  9.   // place within a certain height on the stage
  10.   piece._y = Stage.height+30;
  11.   //scale each piece randomly to 300%.
  12.   piece._yscale = piece._xscale=Math.random()*300;
  13.   //set each pieces direction which will be used for y scale and x direction
  14.   piece.direction = Math.random()*-8;
  15.   // put an enterframe event on each piece and name the function
  16.   piece.onEnterFrame = confettiMoverThrow;
  17.  }
  18. }

The code is pretty straight forward but in a nutshell, we’re using a for loop to create a set number of pieces based on our numOfConfetti variable that we previously set at 50. Inside that for loop each piece is created with the attachMovie() method, placed randomly across the stage on the x axis and positioned within a certain area on the stage, based on stage height.

Each piece is then scaled randomly up to 300% to give the illusion that the confetti is right in front of you. One of the most important parts of this is line 49 where we set the direction for each piece. This direction variable will be used like speed to increase movement and scale in increments for the y scale and x direction of each piece. Except, direction will sometimes be a negative number. The Math.random() method in this case will always generate a negative number for starters.

13. Handle movement of each piece.
Each piece will be animated with a enterFrame function called confettiMoverThrow(). Somewhere around line 64 type the following code in.

  1. function confettiMoverThrow() {
  2.  //set the speed
  3.  var s:Number = Math.random()*80;
  4.  // basic movement based off speed and y scale direction
  5.  // change the y scale
  6.  this._yscale -= this.direction;
  7.  // move the piece up the stage
  8.  this._y -= s;
  9.  // move the piece on the x axis.
  10.  this._x -= this.direction;
  11. }

The above function is a simple mover – for now – so you can see how the movement works. The movement is basically created by giving each piece a different speed, s and a different direction . The direction has already been determined in the confettiThrow() function and now direction will be used as an increment of change in the x position and y scale of each piece.

Lets run down it line by line. First we set the speed for each piece, speed is used to move the piece up the stage on the y axis. Then we change the y scale in increments of the piece’s direction. If you remember from our previous function line 49 each piece has a negative direction somewhere between -001 and -8.

this._yscale -= this.direction;

Because the y scale of the piece is constantly being updated by the enterFrame event as a double negative, the pieces are being scaled in positive y increments somewhere between 0 – 8. At the same time the y scale is being changed we move the and across (x axis) the stage in increments of that pieces speed (also a positive number). In addition we move the piece up the y axis because speed is a positive number between 0-80 and we are moving that in negative increments.

Change s to something much slower like .5, preview the movie and you will see the pieces go up and across to the right while they become ovals. All of them stay light blue.

Well this doesn’t look like confetti at all!

14.Exactly, time to add the logic
Even when throwing confetti in the air, it doesn’t all go up the same. In animation when you want conditions to change dynamically during runtime, you can easily use conditional statements to change them. The conditional statements are what gives the confetti its personality and convinces the viewer that this is confetti, not a bunch of ovals flying around the stage. Delete the original confettiMoverThrow() function shown above and replace it with the one below at line 54.

  1. // movement for thrown confetti
  2. function confettiMoverThrow() {
  3.  //set the speed
  4.  var s:Number = Math.random()*80;
  5.  // logic that changes the color of the piece
  6.  // if the y scale hits zero
  7.  if (this._yscale<=0) {
  8.   // piece becomes parameter placeholder in color function
  9.   changeColor(this);
  10.   // Change the direction of the scale and direction x
  11.   this.direction = -1*Math.random()*8;
  12.   // repeat for change in scale in the opposite direction
  13.  } else if (this._yscale>=100) {
  14.   this.direction = Math.random()*8;
  15.                 changeColorBack(this);
  16.  }
  17.  // basic movement based off speed and y scale direction
  18.  this._yscale -= this.direction;
  19.  this._y -= s;
  20.  this._x -= this.direction;
  21.  
  22.  // remove the confetti  when it reaches the sky
  23.  if (this._y<=-30) {
  24.   this._x = this._x;
  25.   this._y = this._y;
  26.   this.onEnterFrame = null;
  27.   //delete(this);
  28.   //trace("[cs] confetti removed" + this);
  29.  }
  30. }

Once we add the conditional statements to the code gets a bit more complex. First off lets look at the ELSE, in our first If/else statement. If the y scale of the piece gets larger than 100 (which it does instantly) we will change its color and direction. So immediately we will no longer have vertically stretched ovals because they can never go above 100% y scale. After the color changes, the direction will turn into a negative, so the piece will move to the left and more importantly we will start to scale the piece’s y scale in negative increments which will scale it vertically smaller and start to give the appearance of flipping horizontally. Above that Else statement is the if statement which will become true when the confetti piece’s y scale hits zero. At that point we pass the piece into a function called changeColor() and change the direction again making the confetti scale vertically in a positive direction and completing the illusion of horizontal flipping.

Remember, because each piece has its own set speed and direction that changes each time it flips, each piece of confetti has a completely unique moving pattern.

Finally we remove the enterFrame event from each piece when it goes off the top of the stage.

15. Create common functions to do repeating tasks.
In order to preview this we’ll need to quickly write the functions that change the color. This will be done quite simply by using TweenFilterLite in our function. At around Line 67, add the changeColor() function.

  1. // functions to change color
  2. function changeColor(mc:MovieClip) {
  3.  TweenFilterLite.to(mc,.12,{colorMatrixFilter:{colorize:colorArray[0], amount:1, contrast:1}});
  4. }
  5.  
  6. function changeColorBack(mc:MovieClip) {
  7.  TweenFilterLite.to(mc,.12,{colorMatrixFilter:{colorize:colorArray[1], amount:1, contrast:1}});
  8. }

Each piece of confetti is passed as a parameter into the above functions. TweenFilterLite takes each piece and changes its color to one of the two colors in the colorArray.

So if you preview now, you will see we have confetti being thrown in the air too quickly to see any color changes and flips. You’d have to slow down the speed to really see the pieces flip on the throw since the speed is so high. It seems like a lot of work for a quick throw that looks like bubbles. The good news is, however all the code you’ll need to make the fall is already written in the throw.

Tip: A great way to see how the speeds and directions of the pieces change is to add this to the If statement

  1. trace("ConfettiMoverThrow[If]"  + "\n" + "\t" + this +"'s" + " " + "direction = " + this.direction)

and add this to the Else statement

  1. trace("ConfettiMoverThrow[Else]"  + "\n" + "\t" + this +"'s" + " " + "direction = " + this.direction)

Change the both the numOfConfetti and speed to a lower number and you can better track the behaviour of each piece.

16. Create the falling confetti
Lets un-comment out that line in the setUp() function.

  1.  confettiFallTimer = setTimeout(confettiFall, 1500);

And lets go back to line 35 and add this function above the confettiMoverThrow() function.

  1.  // create confetti to fall
  2. function confettiFall() {
  3.  // create a for loop to create the pieces
  4.  for (var i = 0; i<numOfConfetti; i++) {
  5.   // attach a piece to background
  6.   var piece:Object = bckgrnd.attachMovie("confetti", "confetti"+i, i);
  7.   // position the piece x
  8.   piece._x = Math.random()*Stage.width;
  9.   // position the piece y
  10.   piece._y = Math.random()*top;
  11.   // position the scale
  12.   piece._yscale = Math.random()*100;
  13.   //set the direction
  14.   piece.direction = 10;
  15.   // set the X direction
  16.   piece.dirX = 5;
  17.   // put an enterframe event on each piece.
  18.   piece.onEnterFrame = confettiMover;
  19.  }
  20. }

17. Create the falling confetti’s movement function
As you can see creating confetti for the fall is the exact same as setting up the confetti for the throw with only one exception. I’ve created a variable called dirX in addition to direction so that my y scale increments are different my x pos increments. this will give a better fluttering effect at slower speeds.

Lets look at the mover function below. I’ve added it on Line 106, just after the confettiMoverThrow() function.

  1.  // movement for falling confetti
  2. function confettiMover() {
  3.  //set the horizon
  4.  horizonLevel = (Stage.height/1.5) + Math.random()*(Stage.height);
  5.  // set the speed of each piece
  6.  var s:Number = Math.random()*14;
  7.  
  8.  if (this._yscale<=0) {
  9.   changeColor(this);
  10.   this.dirX = -1*Math.random()*5;
  11.   this.direction = -1*Math.random()*10;
  12.  } else if (this._yscale>=100) {
  13.   this.dirX = Math.random()*5;
  14.   this.direction = Math.random()*10;
  15.   changeColorBack(this);
  16.  }
  17.  // move the piece in a random x direction
  18.  this._x -= this.dirX;
  19.  // reduce the y scale individually
  20.  this._yscale -= this.direction;
  21.  // move the piece down
  22.  this._y += s;
  23.  
  24.  if (this._y>=horizonLevel) {
  25.   this._xscale = 100;
  26.   // skew it slightly to look like it landed on a plane
  27.   this._yscale = 40;
  28.   this._alpha = 100;
  29.   //stop where you are
  30.   this._x = this._x;
  31.   this._y = this._y;
  32.   // remove enter frame event from each piece
  33.   this.onEnterFrame = null;
  34.   //trace("[cs] confetti landed" + this);
  35.  
  36.  }
  37. }

This code is exactly the same as the throw code with minor exceptions. First thing you will see is that we are setting the horizonLevel for each piece. Each piece therefore has its own pre-designated landing spot. You will notice the same Math.random() is used for speed but this time the speed is much slower (0-14). As stated before we are changing the x pos in different increments than the y scale giving us a very dynamic animation. Finally you can see the last conditional statement checks the piece of confetti to its final resting place. When the piece gets to that spot it will stop and retain a certain y scale.

18. Preview the final movie!
If you preview the movie now you should see some quickly thrown confetti, a slight pause and then falling confetti gently landing on the floor. Pretty cool. Try playing with the timers to delay the fall of the confetti. Or try playing with some of the numbers to make more or less confetti, change speeds etc..

Well that’s it! I hope you enjoyed this tutorial and are looking forward to applying some of the things learned here to your personal projects.

Editors note: Apparently there is no longer TweenFilterLite and this has been replaced with TweenMax. From blog.greensock.com:

TweenFilterLite retired – With the new plugin architecture, you can activate the filter plugins in TweenLite or TweenMax, so TweenFilterLite is obsolete.

TweenFilterLite is included in the example files provided in the link above.

Posted on July 16, 2009 at 2:41 pm by Runtime · Permalink
In: ActionScript 2, CS3, Flash, OOP, Tutorial, animation · Tagged with: , , , ,

4 Responses

Subscribe to comments via RSS

  1. Written by Smitty
    on July 21, 2009 at 6:19 pm
    Permalink

    Epic post, homes.

  2. Written by Jerlyn
    on September 28, 2009 at 11:55 am
    Permalink

    No As3?

  3. Written by Runtime
    on September 28, 2009 at 2:50 pm
    Permalink

    Jerlyn, I’ll send you a sample of basic particle effects in AS3. It’s good for web animation, but as you know not used in banners.

  4. Written by Jerlyn
    on November 30, 2009 at 11:18 am
    Permalink

    It’s funny, I actually needed one of these for a banner :-D

Subscribe to comments via RSS

Leave a Reply

You must be logged in to post a comment.