ActionScript 3 Chain Explosion
February 6, 2009 by: smonteThis 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.
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); } } } }