Actionscript 3 Chain Explosion
If you ever want to develop for example games, you have to know how to create explosions etc. This tutorial teaches you how to create a chain reaction like seen in the movie above.
Setting up the Environment
1. Create a new document of size 400x400.
2. Draw a ball of size 20x20 (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.
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);
}
}
}
}
