1 0 Tag Archives: flex

Smoke Particle System for AS3 (ActionScript 3)

Hi,

I just wanted some time out today to do another tutorial for Particle Systems in ActionScript 3. For people who followed my previous Simple Particle System tutorial; this tutorial is totally based on the previous one. I will be telling you, how to add different factors to the already running particle system. If you have the previous tutorial downloaded, you can just open that up and add lines to it as I explain them. I have also attached an updated version, if you want it all done.

Ok, to the tutorial. Particle systems are of so many types that you can never really deal with all of them, yet they all follow the same basic principles as I explained in the first tutorial. For example, you can use the previous tutorial as a “Water” particle system. Today, I’m going to modify it to look like a “Smoke” particle system. We will add wind to it, so that the smoke gets farther away when wind is fast and the speed of particle emission increases as the wind increases and vice versa. Here’s a preview:

First we change the following line in the Particle Class constructor:

Particle.as

1
2
3
4
5
6
7
8
9
10
public function Particle(l:Vector3D)
{
acc=new Vector3D(0.0,0.05,0.0);
 
vel=new Vector3D(Math.random() * 1.0,Math.random() * 1.3 - 1.0,0);
 
loc=l.construct();
r=10.0;
timer=1.0;
}

This gives a different velocity to every newly generated particle in the system. You can always modify this to have a different effect on how the particles behave when they are born. Next, we need to update this velocity component in every frame, or the particles will remain still. So in our update function, we add:

11
12
13
14
15
16
17
18
public function update():void
{
vel.addition(acc);
loc.addition(vel);
 
timer-= 0.025;
acc.setXY(0,0);
 }

and now to add that force, which we call “wind”. The details on the calculation of the wind factor come later in this tutorial, but for now, add a new function to the Particle class as follows:

19
20
21
22
public function add_force(f:Vector3D):void
{
acc.addition(f);
}

Ok, that is all for the Particle class. If you do not understand any of the above changes, do not worry, I will be explaining them once more in the end. Now to our Particle System class:

ParticleSystem.as

There is no big change in the ParticleSystem class, except for one function:

23
24
25
26
27
28
29
30
public function add_force(dir:Vector3D):void
{
for (var i:int=particles.length - 1; i > 0; i--)
{
var p:Particle=Particle(particles[i]);
p.add_force(dir);
}
}

The above function is propagating the wind factor, which comes from our main FLA into each particle of the Particle System. In other words, this function calls the “add_force” function of the Particle Class. I have kept the names same for both the classes, so that one can understand the propagation. More about the “dir” vector in the next paragraph.

To our main FLA, where all of this comes to life.

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
var ps:ParticleSystem = new ParticleSystem(0,new Vector3D(stage.stageWidth/2,stage.stageHeight/2,0));
addChild(ps);
 
function update(e:Event)
{
var dx:Number = (mouseX - width/2) / 1000.0; // horizontal drag component
var dy:Number = (mouseY - height/2) / 1000.0; // vertical drag component
 
var wind:Vector3D = new Vector3D(dx,dy,0);
ps.add_force(wind);
 
for (var i:int = 0; i < 2; i++)
{
ps.addParticle();
}
ps.run();
}
this.addEventListener(Event.ENTER_FRAME,update);

Paste the above code in your FLA and run it, you’ll notice that the Smoke gets an acceleration factor when you move the mouse farther away from the Particle System. This gives you a feeling that there is wind acting on the Particle System. Now to explain what we are doing in the code above:

First we take variables dx and dy. The formula is to take the current position of the Mouse Pointer on the screen and convert it so that our particle system takes direction based on that position. For example:

If

mouseX = 192;
mouseY = 145;
width = 200;
height =200;

then the result for the values of the variables dx and dy should be:

dx = 0.092 = (192 – 200/2) / 1000.0
dy = 0.045 = (145 – 200/2) / 1000.0

and then we send this value to our Particle System’s “add_force” function, which propagates this value into every particle in the Particle System. Also, notice the FOR loop, I’m tricking the Particle System as if there are two emitters ;) . If you do not understand what that means, you should go over my previous turorial. Putting this hierarchy together, lets see what our particle system is doing now:

- Calculate a wind factor (wind vector in the Main FLA) using the values of dx and dy.
- Send that wind vector to the “add_force” function in the Particle System class.
- Calling the “add_force” function of each particle and adding that wind factor to their acceleration.

Simple, right? This was pretty easy. I would recommend you try different things in the particle system to take more use of it. You can change the colors of particles over time to give them a FIRE effect ;) .

M.H.A.Q.S.

smokeparticlesystem.zip

Read full story »

Simple Particle System in ActionScript 3

Assalam o Akeikum and Hi,

It was time to start posting tutorials and source code as I promised earlier and so I will start by continuing my recent experience with particle systems in both Processing and Flash. I will teach you how to make a simple particle system and explain along with it, why traditional particle systems are CPU savy. I will also go through some of the particle engines present for Action Script.

If you don’t know what Particle systems are, then this may not be the right place for you. I would recommend you google “Particle System” or wiki it, you may also visit Daniel Shiffman‘s website. He has an amazing resource of information regarding Particle Based Systems and how they have evolved. The example used in this tutorial has been modified from his source code present on the website. I converted it to Action Script to demonstrate certain differences between Flash and Java. Enough chit chat, let us get on with it.

We will first need some Mathematics to calculate vectors and directions for particles. You don’t need to work on that and download Vector3D class for AS3, I posted a few days ago. This makes our work easier. Here’s a preview of what we’ll be making:

I’ll explain each step of class creation for our particle as we move on:

Particle.as

package
{

External classes in Flash need to be inside a package. If you are not creating complex hierarchies, then I would recommend you keep all the classes in the root package. Packages are necessarily paths to classes. A subpath translates to a hierarchy of other classes. This is the same behavior as Java and many other languages that use packages nowadays.

import flash.display.Shape;

We only need to import this, since we are creating a simple particle for now. We will add imports once we create more complex particle systems.

public class Particle extends Shape
{

We create a particle class and inherit the properties of Shape from Flash primitive types. Inheritance is pretty easy in flash and VERY useful. If you are not familiar with the term inheritance or Object Orientation, then Google it :P .

var location:Vector3D;            // The location in x,y coordinate of our particle
var velocity:Vector3D;            // The velocity of our particle (amount of travelling it does in a given time)
var acceleration:Vector3D;        // The constant addition to the speed of our particle
var radius:Number;            // The radius/size of our particle
var timer:Number;            // A timer that can help us in performing events as needed

Some particle properties that will help us animate or change our particle’s behavior over time. Although the meaning of the properties is very much obvious by their names, I’ve explained what they are used for.

public function Particle(v:Vector3D)
{
acceleration=new Vector3D(0,0.05,0);
velocity=new Vector3D((Math.random() * -1.0 + Math.random() * 1.0),(Math.random() * -2.0 + Math.random() * 0.0),0);
location=v.construct();
radius=10.0;
timer=1.0;
}

Action Script does not support multiple Constructors for now, but this is the one we’ll be using here. This constructor takes a Vector(location) and creates a particle object at that location. The constructor initializes the values for the particle. Values in this construcor will transform how our particles appear on screen at the initial frame.

public function run():void
{
update();
render();
}

This function is called whenever a particle is to be updated. It simply calls two other functions. The update function updates the variables (location, acceleration) of the particle and the render function draws the changes to the screen.

// Method to update location
public function update():void
{
velocity.addition(acceleration);
location.addition(velocity);
timer -= 0.01;
}

Our particle needs to move, or else it would appear like a dot on the screen. We update the location of the particle by adding a constant acceleration to its velocity and then by changing its location. The timer object here is used to detect, how long has it been since the particle was born. We will use this information to make it die and remove it from the screen.

// Method to display
public function render():void
{
graphics.clear();                    // Clears any thing drawn on the previous frame.
graphics.beginFill(0xffffff,timer);            // Start drawing using white color and timer alpha
graphics.lineStyle(0,0xffffff,timer);            // We don't want a boundary on our particle.
graphics.drawEllipse(loc.x,loc.y,r,r);        // Draw a particle on location.x and location.y position
graphics.endFill();                    // Not necessary but a good practice
}

This function renders the changes to the screeen. The purpose of each line is explained next to it. If you are not familiar with Flash scripting, you might wanna skip this and learn basic flash drawing using API first.

// Is the particle still useful?
public function dead():Boolean
{
if (timer <= 0.0)
{
return true;
}
else
{
return false;
}
}

This function checks if the particle needs to be removed from the screen. Clearly this is the timer object we created for each particle. Each particle is traced through its timer based value and will be removed from memory when this timer reaches zero. More detail on this in the Particle System class.

 }
}

Ok, now to our Particle System class:

ParticleSystem.as

package
{
import flash.display.MovieClip;
 
public class ParticleSystem extends MovieClip
{

Our particle system class hosts particles, and this is where all the particles are born. This class creates and deletes particles. We have inherited the MovieClip properties for this class since we want our particles to be animated inside a DisplayObject, but this is not really necessary.

var particles:Array;    // An arraylist for all the particles
var origin:Vector3D;    // An origin point for where particles are created

We create an array of particles. This array should hold a number of particles as they are created and is resized / expanded as required. The origin is a vector object that is used to define the originating position of our particles e.g. every particle should be created at x=0,y=0.

public function ParticleSystem(num:int,v:Vector3D)
{
particles=new Array();        // Initialize the arraylist
origin=v.construct();        // Store the origin point</em></strong>
 
for (var i:uint=0; i &lt; num; i++)
{
particles.push(new Particle(origin));    // Add "num" amount of emitters to the arraylist
}
}

This is the default constructor for the Particle System. The copy1() function returns a vector position and creates a Vector3D object, this is a copy constructor. The loop in this constructor runs for a specific number of emitters provided during the creation of the particle system. An emitter creates particles. The more the emitters, the more the particles. For Example: An emitter is like a fountain, the more pipes in the fountain the more water goodness.

public function run()
{
// Cycle through the ArrayList backwards because we are deleting
for (var i:uint=particles.length - 1 ; i &gt; 0; i--)
{
var p:Particle = Particle(particles[i]);
addChild(p);
p.run();
 
if (particles[i].dead())
{
particles.splice(i,1);
}
}
}

Each emitter then creates a particle inside it and keeps track of it. Once the particle has finished its lifetime, the emitter is responsible for removing it from the array of particles. This is handled through the addparticle and particle.isdead() function. What we are doing in the above function is fairly simple. Run the loop for the length of the particle array. Create a particle object and add it to the Flash Display List. If you don’t know what Display Lists are or what Display Objects are, you might wanna visit Flash’s Documentation at LiveDocs. We then call the particle’s run function, which will essentially update the position of the particle with each run and draw it to the screen. We check the timer object of the particle and fade it over time and where the particle.isdead() would tell us if the particle has completely faded away. We then remove that particle from the particles array using the splice function. The splice function removes elements from the Array object ranging n number of times.

public function addParticle()
{
particles.push(new Particle(origin));
}

We add a particle to the particles array. This is simply creating a particle.

// A method to test if the particle system still has particles
public function dead():Boolean
{
if (particles.length &lt;= 0)
{
return true;
}
else
{
return false;
}
}

This function checks if all particles from the array have been removed, if the movie is not running in a loop, this will remove the particle system object and no more particles will be generated from the emitter.

}
}

The hard part is over here, we now need to create a particle system instance on our Flash Stage. Create an FLA and on its first frame, write this code:

var ps:ParticleSystem = new ParticleSystem(1,new Vector3D(stage.stageWidth/2,stage.stageHeight/2,0));

Create a particle system instance. The number of emitters in it are 1 and the default position for our particle system should be the center of the stage, since this is a 2D particle system, we set Z to 0.

addChild(ps);

We need to add this Display Object to our Flash Display List. This tells Flash to draw the object to the screen.

function update(e:Event)
{
ps.addParticle();
ps.run();
}
this.addEventListener(Event.ENTER_FRAME,update);

This is more likely an “onEnterFrame” function for users who are familiar with ActionScript 2.0. What this function is doing is to be called every n number of frames. If the Frame Rate for the FLA is 30 FPS, then this function is called every 30th second. This function is adding a particle to the Particle array and then calls its update function. The hierarchy is pretty simple to understand:

ParticleSystem (Hosts emitters and calls an update function)
->Emitter (Hosts particles and calls their update function)
–>Particle (Hosts Vectors and uses them to update locations and other variables).

Ok, now compile everything and run the code. If you can’t seem to run it, then go through the tutorial once again. Remember this is ActionScript 3. If you still can’t seem to run it, then go ahead ask me. We now analyze our particle system.

The CPU usage for this particle system should not exceed 2% of your CPU no matter what. Creating the same particle System in Flint or Pulse would render much different results and the CPU usage should rise upto 10%. Why the CPU usage, you ask? Well, this is not a problem with the Particle Engines themselves but with how Flash manages Display Objects. Adobe needs to concentrate on the Display engine and optimize it. If you need another example, try doing this and see how this affects the CPU usage and you’ll know what I mean:

in the particle class, go to the render function and change the following line:

graphics.drawEllipse(loc.x1,loc.y1,r,r);

to

graphics.drawEllipse(loc.x,loc.y,r*timer,r*timer);

You will notice a CPU increase from 7%-15%. This is fairly large and the reason why Pulse and Flint both end up using too much CPU. In a previous post, I stated how Flash compares to other graphic APIs and this holds true here as well.

I hope you enjoyed and learned how to create simple particle systems in Flash ActionScript 3. I will soon post more tutorials on particle systems and we will then move on to create complex particle Systems based on this one. We will further analyze how we can port this code to create a particle engine. So keep an eye out for more stuff to come.

Regards,
M.H.A.Q.S.

Download simpleparticlesystem.zip

Read full story »

Vector3D for AS3 (ActionScript 3)

Update: I updated the Vector3D class with usage information and copyrights. The original library was created by Daniel Shiffman and is being used widely in Processing and Java.

This post is a launching gift as promised. While working with many projects, I had used many nifty functions and there were some that I needed from time to time. This called for a Vector3D class to be used at many places and so I compiled a version of my own. I know many people have already made a Vector3D class but I know this will help people anyway.

The class is also attached with this post. It is for use with Flash/Flex/AIR (all based on AS3).

Thanks,
M.H.A.Q.S.

Download Vector3D.as

Read full story »