Sky’s the Limit: AKQA Shows the Possibilities with Flash CS4 (Part 3 of 3)

NOTE: This is one of three articles commissioned by Adobe and written by separate design agencies to demonstrate the variety of techniques available in Flash CS4 Professional. In these examples, three techniques are shown for creating realistic fireworks effects; all require intermediate to advanced ActionScript 3 skills. Enjoy! —Jeremy Schultz

Introduction by Kristan Jiles, Senior Product Marketing Manager, Adobe Systems Incorporated

Three design agencies that are given an identical initial directive, using the same tool, will return with very different project results. The creative process is essential in determining the end result; it’s how professionals use their tools to bring their work to life. We asked design agencies AgencyNet, AKQA and Vasava to develop a tutorial on how to create a fireworks display using Adobe Flash CS4 Professional to demonstrate how the same tool used to design the same project can yield such unique and differing results. At Adobe, we’re inspired by seeing how each creative uses their knowledge of the product to create amazing and fun projects that can be shared with others. Flash was developed to provide a variety of design and development options for any project and this is only one example. With animation, 3D transformation, rich drawing capabilities, and ActionScript development, we encourage designers and developers to continue experimenting with Flash to produce amazing work!

Tutorial by AKQA

When trying to imitate nature and real-life motion, a significant understanding of math and physics is necessary. To create realistic fireworks shows in Flash involve some kind of particle effect. Making a particle engine from scratch to achieve the effect is not a particular easy task. It requires a certain level of math knowledge on the part of the Flash developer, and is a meticulous time intensive task.

Like any good cooking show, we cheat a little, and rely on one of the publicly available ActionScript engines that have most of the heavy lifting built-in. For this project we’ve chosen to utilize the Flint particle system, which allow developers of almost all levels to create a variety of particle effects with ease. Flint is also one of the more complete particle engines API made for AS3 that is easy to understand and use. It is an active open-source project with the support of a community on their website. Thanks for lending a hand guys!

In this tutorial, we will show you how to use Flint to easily create a cool fireworks effect that not only seems real, but also forms any desired graphic you specify. To showcase this we’ve chosen the AKQA logo.

akqa-image-1

Setup

1. Go to http://code.google.com/p/flint-particle-system/ and download the Flint Particle System codebase.

2. Create the desired PNG image with transparency for the fireworks to emulate. In this tutorial, we use the AKQA logo:

akqa-image-2

3. Create your class to hold the graphic. Make sure it extends the BitmapData class. In this case we are creating it for our logo:

akqa-image-3

4. Create a new FLA for your fireworks and name it Fireworks.fla.

5. Import your PNG into your library, then link your class from Step 3 to the PNG:

akqa-image-4

6. Create a new class, name it Fireworks.as, and use it as your document class:

akqa-image-5

7. Go to http://flintparticles.org/examples/logo-firework and copy the code from the demo and paste it into your document class from Step 6.

8. We are ready to do some coding.

Coding

1. Before we can edit the code to make the fireworks look right in our file, let’s first see what each line does.

Standard instantiating code:

var emitter:Emitter2D = new Emitter2D();
1500 denotes the amount of particles to create:
emitter.counter = new Blast( 1500 );

The particles use colors randomly picked between the two values given below:

emitter.addInitializer( new ColorInit( 0xFFFF3300, 0xFFFFFF00 ) );

How long this sequence of particles last before getting destroyed:

emitter.addInitializer( new Lifetime( 6 ) );

The DiscZone defines a circular area with a hole in the middle, telling where to start the particles:

emitter.addInitializer( new Position( new DiscZone( new Point( 0, 0 ), 10 ) ) );

Pass the PNG to the particles engine to emulate:

var bitmapData:BitmapData = new Logo( 265, 80);

Because the particles are moving according to Flash’s coordinate system, which is based on top left corner, the particles will move in a lower-right direction. Since the fireworks need to explode from the center, the values “-132” and “-300” offset the particles’ direction so that they are shooting out from the center:

emitter.addInitializer( new Velocity( new BitmapDataZone( bitmapData, -132, -300 ) ) );

The following lines do the actual explosion of the fireworks and are pretty self-explanatory (If you’re on Eclipse or Flex, make sure Quadratic comes from the org.flintparticles.common.energyEasing package or it throws a wrong number of parameters compile error if it comes from another package):

emitter.addAction( new Age( Quadratic.easeIn ) );
emitter.addAction( new Fade( 1.0, 0 ) );
emitter.addAction( new Move() );
emitter.addAction( new LinearDrag( 0.5 ) );
emitter.addAction( new Accelerate( 0, 70 ) );

Restart the sequence once this sequence is complete:

emitter.addEventListener( EmitterEvent.EMITTER_EMPTY, restart );

Tells the engine the area to draw the particles:

var renderer:PixelRenderer = new PixelRenderer( new Rectangle( 0, 0, 500, 300 ) );

Gives it a BlurFilter which seems to emulate fireworks’ sparks:

renderer.addFilter( new BlurFilter( 2, 2, 1 ) );

Gives a ColorMatrixFilter which helps to add to the realistic feel of the fireworks:

renderer.addFilter( new ColorMatrixFilter( [ 1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0.96,0 ] ) );

Tie it all together:

renderer.addEmitter( emitter );

Add to display list:

addChild( renderer );

Position the particles emitter:

emitter.x = 250;
emitter.y = 300;

Have to call start() to get it going:

emitter.start( );

2. Now we need to pass our PNG to the fireworks so the particle engine knows what graphic to emulate.

We do this by changing the following two lines of code:

var bitmapData:BitmapData = new Logo( 265, 80);
emitter.addInitializer( new Velocity( new BitmapDataZone( bitmapData, -132, -300 ) ) );

to take our logo:

var bitmapData:BitmapData = new AKQALogo( 0, 0);
emitter.addInitializer( new Velocity( new BitmapDataZone( bitmapData, -bitmapData.width / 2, -bitmapData.height/2 - 50) ) );

3. Finally, knowing what the other values represent we adjust them to fit our file. The following is the complete source code from the class Fireworks.as:

package com.akqa.tutorials.fireworks
{
import flash.events.Event;
import com.akqa.mvc.AbstractSprite;
import org.flintparticles.common.actions.Age;
import org.flintparticles.common.actions.Fade;
import org.flintparticles.common.counters.Blast;
import org.flintparticles.common.energyEasing.Quadratic;
import org.flintparticles.common.events.EmitterEvent;
import org.flintparticles.common.initializers.ColorInit;
import org.flintparticles.common.initializers.Lifetime;
import org.flintparticles.twoD.actions.Accelerate;
import org.flintparticles.twoD.actions.LinearDrag;
import org.flintparticles.twoD.actions.Move;
import org.flintparticles.twoD.emitters.Emitter2D;
import org.flintparticles.twoD.initializers.Position;
import org.flintparticles.twoD.initializers.Velocity;
import org.flintparticles.twoD.renderers.PixelRenderer;
import org.flintparticles.twoD.zones.BitmapDataZone;
import org.flintparticles.twoD.zones.DiscZone;
import flash.display.BitmapData;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
/**
* @author kenny lin
*/
public class Fireworks extends AbstractSprite
{
// how many particles to generate
private var particleAmount:Number = 1500;
// how long the fireworks last
private var lifeSpan:Number = 6; // seconds
// thickness of the area populated by particles
private var thickness:Number = 3;
// the BitmapData used as a guide for the fireworks to generate
private var bitmapData:BitmapData = new AKQALogo();
/*
* The fireworks shoot lower-right by default
* The following correct the direction (try setting them to 0 to see what happens)
*/
private var correctLogoOffsetX:Number = 0;
private var correctLogoOffsetY:Number = 0;
public function Fireworks()
{
correctLogoOffsetX = -bitmapData.width / 2;
correctLogoOffsetY = -bitmapData.height/2 - 50;
}
/*
* Because I want to reference the stage's dimension
* I set up all my stuff after it's been added to stage
*/
override protected function onAddedToStage(e:Event):void
{
// call super to remove event
super.onAddedToStage(e);
// setup starts
var emitter:Emitter2D = new Emitter2D();
emitter.counter = new Blast( particleAmount );
emitter.addInitializer( new ColorInit( 0xFFFF3300, 0xFFFFFF00 ) );
emitter.addInitializer( new Lifetime( lifeSpan ) );
emitter.addInitializer( new Position( new DiscZone( new Point( 0, 0 ), thickness ) ) );
emitter.addInitializer( new Velocity( new BitmapDataZone( bitmapData, correctLogoOffsetX, correctLogoOffsetY ) ) );
emitter.addAction( new Age( Quadratic.easeIn ) );
/*
* Play around the the following to get the ideal effect
*/
emitter.addAction( new Fade( 1.0, 0 ) );
emitter.addAction( new Move() );
emitter.addAction( new LinearDrag( 0.5 ) );
emitter.addAction( new Accelerate( 0, 70 ) );
emitter.addEventListener( EmitterEvent.EMITTER_EMPTY, restart, false, 0, true );
// defines the area to draw all the particles on, in this case the size of stage
var renderer:PixelRenderer = new PixelRenderer( new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight ) );
renderer.addFilter( new BlurFilter( 2, 2, 1 ) );
renderer.addFilter( new ColorMatrixFilter( [ 1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0.96,0 ] ) );
renderer.addEmitter( emitter );
addChild( renderer );
emitter.x = stage.stageWidth/2;
emitter.y = stage.stageHeight/2;
emitter.start( );
}
private function restart( ev:EmitterEvent ):void
{
Emitter2D( ev.target ).start();
}
}
}

Click here to see the final result!

And there you have it, a short and simple way of creating a spectacular fireworks show. Now go ahead and try, write your loved one’s name in the sky, or shamelessly promote yourself and use your company logo. Play with colors and shapes to create something just right for you!