Creating a Chain Explosion

February 6, 2009 by: smonte

This tutorial shows you how to create a cool chain reaction with particles.

Setting up the Environment

1. Create a new document of size 400×400.

2. Draw a ball of size 20×20 (you can choose the color as you like).

3. Convert it into a movie clip (registration point in the center!).

4. Linkage to movie clip to a class called “Particle”.

5. Remove the Particle from the stage.

Moving into ActionScript 3.0

6. First, let’s create the Particle class. Create an .as file and type the following.

package {
 
        import flash.display.MovieClip;
 
        public class Particle extends MovieClip {
 
                //We need different speeds for different particles.
                //These variables can be accessed from the main movie, because they are public.
                public var speedX:Number;
                public var speedY:Number;
                public var partOfExplosion:Boolean = false;
 
                function Particle ():void {
 
                }
        }
}

7. Save the file as “Particle”. You can close the file now if you want. We won’t be working with that anymore

8. Let’s move back to our main movie. First let’s set up the particles into the stage and declare some variables. The comments should be informative enough to let know what we’re doing in each step.

//We need few imports for the color
import fl.motion.Color;
import flash.geom.ColorTransform;
 
/*We want 20 particles at the start particlesArray is used when we animate each particle */
var numberOfParticles:Number = 20;
var particlesArray:Array = new Array();
 
//Each time a hit occurs, we want to create 10 new particles
var numberOfExplosionParticles:uint = 10;
 
//This loop creates the first particles and gives them speed and coordinates
for (var i=0; i < numberOfParticles; i++) {
 
        var particle:Particle = new Particle();
 
        //We want the particles to stay at their original position
        particle.speedX = 0;
        particle.speedY = 0;
 
        //Set the starting position
        particle.y = Math.random() * stage.stageHeight;
        particle.x = Math.random() * stage.stageWidth;
 
        //Add the particle to the stage and push it to array for later use.
        addChild (particle);
        particlesArray.push (particle);
}

If you test your movie, you should have a similar looking movie as the following.

Particles setup

10. Add the following piece of code into your actions panel.

//Call for the first explosion
startExplosions ();
 
/*This function makes a random particle to explode. From here, the chain reaction begins.*/
function startExplosions ():void {
 
        //Select a random particle from an array
        var index = Math.round(Math.random() * (particlesArray.length-1));
        var firstParticle:Particle = particlesArray[index];
 
        //Set a random tint
        var ct:Color = new Color();
        ct.setTint (0xFFFFFF * Math.random(),1);
 
        //Create 10 new particles because of explosion
        for (var i=0; i < numberOfExplosionParticles; i++) {
 
                var particle:Particle = new Particle();
 
                /*Give random x and y speed to the particle. Math.random returns a random number n, where 0 <= n < 1. */
                particle.speedX = Math.random()*10 - 5 ;
                particle.speedY = Math.random()*10 - 5;
 
                //Apply the randomly selected tint to each particle
                particle.transform.colorTransform = ct;
 
                //Set the starting position
                particle.y = firstParticle.y;
                particle.x = firstParticle.x;
 
                //Particle is part of an explosion
                particle.partOfExplosion = true;
 
                //Add the particle to the stage and push it to array for later use.
                addChild (particle);
                particlesArray.push (particle);
        }
        //Let's remove the particle that exploded (remove from stage and from the array)
        removeChild (firstParticle);
        particlesArray.splice (index,1);
 
        addEventListener (Event.ENTER_FRAME, enterFrameHandler);
}

Here we simply explode one randomly select particle. We create new particles, because of the explosion. Last, we remove the exploded particle from the stage

11. Let’s move to the enterFrameHandler, type the following.

//This function is responsible for the animation
function enterFrameHandler (e:Event):void {
 
        //Loop through every particle
        for (var i=0; i < particlesArray.length; i++) {
 
                var particleOne:Particle = particlesArray[i];
 
                //Update the particle's coordinates
                particleOne.y += particleOne.speedY;
                particleOne.x += particleOne.speedX;
 
                /*This loop calls a checkForHit function to find if the two particles are colliding*/
                for (var j:uint = i + 1; j < particlesArray.length; j++) {
                        var particleTwo:Particle = particlesArray[j];
 
                        /*Make sure the particles are on stage, only then check for hits*/
                        if (contains(particleOne) && contains(particleTwo)) {
                                checkForHit (particleOne, particleTwo);
                        }
                }
        }
}

Not that bad, eh? We simply move every particle in each frame. The function “checkForHit” is the hardest part. Type the following.

/*This function checks whether two particles have collided*/
function checkForHit (particleOne:Particle, particleTwo:Particle):void {
 
        /*Let's make sure we only check those particles, where one is moving and the other is stationary. We don't want two moving particles to explode. */
        if ((particleOne.partOfExplosion == false && particleTwo.partOfExplosion == true) ||
        particleOne.partOfExplosion == true && particleTwo.partOfExplosion == false ) {
 
                //Calculate the distance using Pythagorean theorem
                var distanceX:Number = particleOne.x - particleTwo.x;
                var distanceY:Number = particleOne.y - particleTwo.y;
                var distance:Number = Math.sqrt(distanceX*distanceX + distanceY*distanceY);
 
                /* If the distance is smaller than particle's width, we have a hit. Note: if the particles were of different size, the calculation would be: distance < ((particleOne.width / 2) + (particleTwo.width / 2)) */
                if (distance < particleOne.width) {
 
                        //Set a random tint to the particles that explode
                        var ct:Color = new Color();
                        ct.setTint (0xFFFFFF * Math.random(),1);
 
                        //Create 10 new particles because of an explosion
                        for (var i=0; i < numberOfExplosionParticles; i++) {
 
                                var particle:Particle = new Particle();
 
                                particle.speedX = Math.random()*10 - 5 ;
                                particle.speedY = Math.random()*10 - 5;
 
                                //Apply tint
                                particle.transform.colorTransform = ct;
 
                                //Set the starting position
                                particle.y = particleOne.y;
                                particle.x = particleOne.x;
 
                                particle.partOfExplosion = true;
 
                                //Add the particle to the stage and push it to array for later use.
                                addChild (particle);
                                particlesArray.push (particle);
                        }
 
                        /* Check which of the two particles was stationary. We'll remove the one that was stationary. */
                        if (particleOne.partOfExplosion == false) {
                                var temp1 = particlesArray.indexOf(particleOne);
                                particlesArray.splice (temp1,1);
                                removeChild (particleOne);
                        }
                        else {
                                var temp2 = particlesArray.indexOf(particleTwo);
                                particlesArray.splice (temp2,1);
                                removeChild (particleTwo);
                        }
 
                }
        }
}

That’s it. Feel free to modify the code for your needs. Try different values and properties, be creative! Have questions? Ask in the forum.

Final Code

//We need few imports for the color
import fl.motion.Color;
import flash.geom.ColorTransform;
 
/*We want 20 particles at the start particlesArray is used when we animate each particle */
var numberOfParticles:Number = 20;
var particlesArray:Array = new Array();
 
//Each time a hit occurs, we want to create 10 new particles
var numberOfExplosionParticles:uint = 10;
 
//This loop creates the first particles and gives them speed and coordinates
for (var i=0; i < numberOfParticles; i++) {
 
        var particle:Particle = new Particle();
 
        //We want the particles to stay at their original position
        particle.speedX = 0;
        particle.speedY = 0;
 
        //Set the starting position
        particle.y = Math.random() * stage.stageHeight;
        particle.x = Math.random() * stage.stageWidth;
 
        //Add the particle to the stage and push it to array for later use.
        addChild (particle);
        particlesArray.push (particle);
}
 
//Call for the first explosion
startExplosions ();
 
/*This function makes a random particle to explode. From here, the chain reaction begins.*/
function startExplosions ():void {
 
        //Select a random particle from an array
        var index = Math.round(Math.random() * (particlesArray.length-1));
        var firstParticle:Particle = particlesArray[index];
 
        //Set a random tint
        var ct:Color = new Color();
        ct.setTint (0xFFFFFF * Math.random(),1);
 
        //Create 10 new particles because of explosion
        for (var i=0; i < numberOfExplosionParticles; i++) {
 
                var particle:Particle = new Particle();
 
                /*Give random x and y speed to the particle. Math.random returns a random number n, where 0 <= n < 1. */
                particle.speedX = Math.random()*10 - 5 ;
                particle.speedY = Math.random()*10 - 5;
 
                //Apply the randomly selected tint to each particle
                particle.transform.colorTransform = ct;
 
                //Set the starting position
                particle.y = firstParticle.y;
                particle.x = firstParticle.x;
 
                //Particle is part of an explosion
                particle.partOfExplosion = true;
 
                //Add the particle to the stage and push it to array for later use.
                addChild (particle);
                particlesArray.push (particle);
        }
        //Let's remove the particle that exploded (remove from stage and from the array)
        removeChild (firstParticle);
        particlesArray.splice (index,1);
 
        addEventListener (Event.ENTER_FRAME, enterFrameHandler);
}
 
//This function is responsible for the animation
function enterFrameHandler (e:Event):void {
 
        //Loop through every particle
        for (var i=0; i < particlesArray.length; i++) {
 
                var particleOne:Particle = particlesArray[i];
 
                //Update the particle's coordinates
                particleOne.y += particleOne.speedY;
                particleOne.x += particleOne.speedX;
 
                /*This loop calls a checkForHit function to find if the two particles are colliding*/
                for (var j:uint = i + 1; j < particlesArray.length; j++) {
                        var particleTwo:Particle = particlesArray[j];
 
                        /*Make sure the particles are on stage, only then check for hits*/
                        if (contains(particleOne) && contains(particleTwo)) {
                                checkForHit (particleOne, particleTwo);
                        }
                }
        }
}
 
/*This function checks whether two particles have collided*/
function checkForHit (particleOne:Particle, particleTwo:Particle):void {
 
        /*Let's make sure we only check those particles, where one is moving and the other is stationary. We don't want two moving particles to explode. */
        if ((particleOne.partOfExplosion == false && particleTwo.partOfExplosion == true) ||
        particleOne.partOfExplosion == true && particleTwo.partOfExplosion == false ) {
 
                //Calculate the distance using Pythagorean theorem
                var distanceX:Number = particleOne.x - particleTwo.x;
                var distanceY:Number = particleOne.y - particleTwo.y;
                var distance:Number = Math.sqrt(distanceX*distanceX + distanceY*distanceY);
 
                /* If the distance is smaller than particle's width, we have a hit. Note: if the particles were of different size, the calculation would be: distance < ((particleOne.width / 2) + (particleTwo.width / 2)) */
                if (distance < particleOne.width) {
 
                        //Set a random tint to the particles that explode
                        var ct:Color = new Color();
                        ct.setTint (0xFFFFFF * Math.random(),1);
 
                        //Create 10 new particles because of an explosion
                        for (var i=0; i < numberOfExplosionParticles; i++) {
 
                                var particle:Particle = new Particle();
 
                                particle.speedX = Math.random()*10 - 5 ;
                                particle.speedY = Math.random()*10 - 5;
 
                                //Apply tint
                                particle.transform.colorTransform = ct;
 
                                //Set the starting position
                                particle.y = particleOne.y;
                                particle.x = particleOne.x;
 
                                particle.partOfExplosion = true;
 
                                //Add the particle to the stage and push it to array for later use.
                                addChild (particle);
                                particlesArray.push (particle);
                        }
 
                        /* Check which of the two particles was stationary. We'll remove the one that was stationary. */
                        if (particleOne.partOfExplosion == false) {
                                var temp1 = particlesArray.indexOf(particleOne);
                                particlesArray.splice (temp1,1);
                                removeChild (particleOne);
                        }
                        else {
                                var temp2 = particlesArray.indexOf(particleTwo);
                                particlesArray.splice (temp2,1);
                                removeChild (particleTwo);
                        }
 
                }
        }
}
  • Digg
  • Sphinn
  • del.icio.us
  • Mixx

Related tutorials:

  1. Creating Fireworks with ActionScript 3
  2. Snowfall Effect
  3. Advanced Animation with Drawing API
  4. Creating a Shake Effect
  5. Creating Random Lines with Animation

Leave a Reply

You must be logged in to post a comment.