Advanced Animation with Drawing API


Intro

This tutorial teaches you how to combine basic animation with the drawing API. Don't get scared about the amount of code, it's actually pretty straightforward if you look at it with attention. So let's get going!

Note: you should already be familiar with Animating with Physics via Actionscript 3.0

Setting up the environment

1. Create a new document of size 300x300.

2. Draw a ball of size 10x10.

3. Convert the ball into a movie clip called "Particle" (registration point in the center).

4. Remove the ball (Particle) from the stage.

5. Linkage the Particle movie clip to a class called "Particle".

6. Create a class (.as file) called "Particle". 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;

		function Particle ():void {

		}
	}
}

That's it for the setup. Now let's start to animate things!

Moving into Actionscript 3.0

7. First, let's set up the particles to the stage and add some effects. Type the following.


//We need few imports for the filters
import fl.motion.Color;
import flash.geom.ColorTransform;

//Create an array for the particles for later use
var numberOfParticles:Number = 30;
var particlesArray:Array = new Array();

//This loop creates 30 particles that are positioned randomly on the stage. 
//We also add some effects to the particles
for (var i=0; i < numberOfParticles; 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 = 2 + Math.random();
	particle.speedY = 2 + Math.random();

	//Set the starting position
	particle.y = Math.random() * stage.stageHeight;
	particle.x = Math.random() * stage.stageWidth;

	//Set a random tint to the particle, so they will have different colors.
	var ct:Color = new Color();
	ct.setTint (0xFFFFFF * Math.random(), 0.5);
	particle.transform.colorTransform = ct;

	//Set random size to the particles, so the particles will differ in size
	particle.scaleX = 0.5 + Math.random();
	particle.scaleY = particle.scaleX;

	//This array is used to store all of the filters
	var particleFilters:Array = new Array();

	//Create a different blur effect in each particle
	var tempBlurAmount = Math.random()*4;
	var blur:BlurFilter = new BlurFilter(tempBlurAmount, tempBlurAmount, 1);
	particleFilters.push (blur);

	//Create a glow effect in each particle
	var color:Number = 0x000000;
	var alphaValue:Number = 0.5;
	var blurX:Number = 20;
	var blurY:Number = 20;
	var strength:Number = 5;
	var glow:GlowFilter = new GlowFilter(color,
	                                  alphaValue,
	                                  blurX,
	                                  blurY,
	                                  strength);

	particleFilters.push (glow);

	//Apply the created filters to the particle (blur & glow)
	particle.filters = particleFilters;

	//Add the particle to the stage and push it into an array for later use
	addChild (particle);
	particlesArray.push (particle);
}

Allthough that may look hard, it's actually very simple. The comments should explain enough, about what we're doing in each portion. You should now have something like the following. Feel free to change some values for different look!



Animating the particles

8. To move the particles randomly, type the following.

addEventListener (Event.ENTER_FRAME, enterFrameHandler);

//This function is responsible for animation
function enterFrameHandler (e:Event):void {

	//Let's loop through the particles
	for (i=0; i < particlesArray.length; i++) {

		var particleOne:Particle = particlesArray[i];
		//Move the particle to a new location
		particleOne.x += particleOne.speedX;
		particleOne.y += particleOne.speedY;

		//Check the boundaries. 
		//If a hit occurs, multiply the speed by (-1) to reverse the speed.
		
		//Right edge
		if (particleOne.x > stage.stageWidth) {
			particleOne.x = stage.stageWidth - particleOne.width/2;
			particleOne.speedX *= -1;
		}
		
		//Left edge
		else if (particleOne.x < 0) {
			particleOne.x = particleOne.width/2;
			particleOne.speedX *= -1;
		}
		
		//Bottom
		if (particleOne.y > stage.stageHeight) {
			particleOne.y = stage.stageHeight - particleOne.width/2;
			particleOne.speedY *= -1;
		}
		
		//Top
		else if (particleOne.y < 0) {
			particleOne.y = particleOne.width/2;
			particleOne.speedY *= -1;
		}
	}
}

If you test your movie, you should have similar movement as in the following animation.



Adding the Lines to the Animation

9. To add the lines to the animation, modify the enterFrameHandler, so it looks like the following.

function enterFrameHandler (e:Event):void {

	//Clear the previous lines
	graphics.clear();

	//Let's loop through the particles
	for (i=0; i < particlesArray.length; i++) {

		var particleOne:Particle = particlesArray[i];
		//Move the particle to a new location
		particleOne.x += particleOne.speedX;
		particleOne.y += particleOne.speedY;

		//Check the boundaries
		if (particleOne.x > stage.stageWidth) {
			particleOne.x = stage.stageWidth - particleOne.width/2;
			particleOne.speedX *= -1;
		}
		else if (particleOne.x < 0) {
			particleOne.x = particleOne.width/2;
			particleOne.speedX *= -1;
		}
		if (particleOne.y > stage.stageHeight) {
			particleOne.y = stage.stageHeight - particleOne.width/2;
			particleOne.speedY *= -1;
		}
		else if (particleOne.y < 0) {
			particleOne.y = particleOne.width/2;
			particleOne.speedY *= -1;
		}
		
		//Go through the other particles to check the distance with the first particle
		for (var j:uint = i + 1; j < particlesArray.length; j++) {

			var particleTwo:Particle = particlesArray[j];

			var distanceX:Number = particleOne.x - particleTwo.x;
			var distanceY:Number = particleOne.y - particleTwo.y;
			//Use Pythagorean theorem (a^2 + b^2 = c^2) to calculate the distance 
			var distance:Number = Math.sqrt(distanceX * distanceX + distanceY * distanceY);
			
			//If the distance is smaller than 80px, draw a line between the particles
			if (distance < 80) {
				drawLine (particleOne, particleTwo);
			}
		}
	}
}

Add the following function after the enterFrameHandler

//This function draws a black line between two particles
function drawLine (particleOne:Particle, particleTwo:Particle):void {
	graphics.lineStyle (1, 0x000000);
	graphics.moveTo (particleOne.x, particleOne.y);
	graphics.lineTo (particleTwo.x, particleTwo.y);
}

That's it! Test your movie. Feel free to use this code in your projects.


Final Code

//We need few imports for the filters
import fl.motion.Color;
import flash.geom.ColorTransform;

//Create an array for the particles for later use
var numberOfParticles:Number = 30;
var particlesArray:Array = new Array();

//This loop creates 30 particles that are positioned randomly on the stage. 
//We also add some effects to the particles
for (var i=0; i < numberOfParticles; 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 = 2 + Math.random();
	particle.speedY = 2 + Math.random();

	//Set the starting position
	particle.y = Math.random() * stage.stageHeight;
	particle.x = Math.random() * stage.stageWidth;

	//Set a random tint to the particle, so they will have different colors.
	var ct:Color = new Color();
	ct.setTint (0xFFFFFF * Math.random(), 0.5);
	particle.transform.colorTransform = ct;

	//Set random size to the particles, so the particles will differ in size
	particle.scaleX = 0.5 + Math.random();
	particle.scaleY = particle.scaleX;

	//This array is used to store all of the filters
	var particleFilters:Array = new Array();

	//Create a different blur effect in each particle
	var tempBlurAmount = Math.random()*4;
	var blur:BlurFilter = new BlurFilter(tempBlurAmount, tempBlurAmount, 1);
	particleFilters.push (blur);

	//Create a glow effect in each particle
	var color:Number = 0x000000;
	var alphaValue:Number = 0.5;
	var blurX:Number = 20;
	var blurY:Number = 20;
	var strength:Number = 5;
	var glow:GlowFilter = new GlowFilter(color,
	                                  alphaValue,
	                                  blurX,
	                                  blurY,
	                                  strength);

	particleFilters.push (glow);

	//Apply the created filters to the particle (blur & glow)
	particle.filters = particleFilters;

	//Add the particle to the stage and push it into an array for later use
	addChild (particle);
	particlesArray.push (particle);
}

addEventListener (Event.ENTER_FRAME, enterFrameHandler);

//This function is responsible for animation
function enterFrameHandler (e:Event):void {

	//Clear the previous lines
	graphics.clear();

	//Let's loop through the particles
	for (i=0; i < particlesArray.length; i++) {

		var particleOne:Particle = particlesArray[i];
		//Move the particle to a new location
		particleOne.x += particleOne.speedX;
		particleOne.y += particleOne.speedY;

		//Check the boundaries
		if (particleOne.x > stage.stageWidth) {
			particleOne.x = stage.stageWidth - particleOne.width/2;
			particleOne.speedX *= -1;
		}
		else if (particleOne.x < 0) {
			particleOne.x = particleOne.width/2;
			particleOne.speedX *= -1;
		}
		if (particleOne.y > stage.stageHeight) {
			particleOne.y = stage.stageHeight - particleOne.width/2;
			particleOne.speedY *= -1;
		}
		else if (particleOne.y < 0) {
			particleOne.y = particleOne.width/2;
			particleOne.speedY *= -1;
		}
		
		//Go through the other particles to check the distance with the first particle
		for (var j:uint = i + 1; j < particlesArray.length; j++) {

			var particleTwo:Particle = particlesArray[j];

			var distanceX:Number = particleOne.x - particleTwo.x;
			var distanceY:Number = particleOne.y - particleTwo.y;
			//Use Pythagorean theorem (a^2 + b^2 = c^2) to calculate the distance 
			var distance:Number = Math.sqrt(distanceX * distanceX + distanceY * distanceY);
			
			//If the distance is smaller than 80px, draw a line between the particles
			if (distance < 80) {
				drawLine (particleOne, particleTwo);
			}
		}
	}
}

//This function draws a black line between two particles
function drawLine (particleOne:Particle, particleTwo:Particle):void {
	graphics.lineStyle (1, 0x000000);
	graphics.moveTo (particleOne.x, particleOne.y);
	graphics.lineTo (particleTwo.x, particleTwo.y);
}

Bookmark and Share