UPDATE: I have released a complete working port of Opensteer for ActionScript 3. Please see this post.
When I was working on the paperwork for this website, I promised that I will share source code and tutorials for people. I have been pretty active working with many projects lately, and I rarely find time to practice my interests. There are so many great examples and pieces of art out there that I take inspirations from. Much of it involves working with Visual Algorithms and I get to have a great time learning them and re implementing them to my pleasure. This serves me education and releasing them in a new form will eventually serve the community.
This time it is the famous Birds Flocking Behavior Algorithm using Boids. I converted it to Action Script 3. This algorithm can be very useful in areas of visual programming and games. Also, I have been busy working with PaperVision 3D for quite some time. I’ll release a PV3D version of this Algorithm soon. So keep an eye out for that too.
The source code is attached below and if you have questions, do ask. Also, if you need to study this algorithm, you may search around the internet and you’ll find many articles about it.
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.
publicclass 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 .
var location:Vector3D; // The location in x,y coordinate of our particlevar 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 particlevar radius:Number; // The radius/size of our particlevar 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.
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.
publicfunction 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.
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 displaypublicfunction 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?publicfunction dead():Boolean{if(timer <= 0.0){returntrue;
}else{returnfalse;
}}
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.
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 particlesvar 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.
publicfunction ParticleSystem(num:int,v:Vector3D){
particles=newArray(); // Initialize the arraylist
origin=v.construct(); // Store the origin point</em></strong>for(var i:uint=0; i < 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.
publicfunction run(){// Cycle through the ArrayList backwards because we are deletingfor(var i:uint=particles.length - 1 ; i > 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.
We add a particle to the particles array. This is simply creating a particle.
// A method to test if the particle system still has particlespublicfunction dead():Boolean{if(particles.length<= 0){returntrue;
}else{returnfalse;
}}
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:
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.
Recently, I have been working on many pixel level projects with Flash. My experience with these projects was somewhat disappointing when it came to Flash’s rendering of pixel based effects. A normal pixel based operation in Processing would not take more than 10% of your CPU, where Flash would take up to 50% of your CPU. Some functions such as ‘set vertex/point/pixel(position)’ (available in many graphic APIs these days) seem to be missing in Flash and are only available for a specific class called the BitmapData class. Performing pixel manipulations on this class can render things fast but still not fast enough. I hope Flash CS4 brings its attention towards this.
Overall, Processing is very efficient than Flash regarding pixel based operations. I have gone through many article systems made for Flash and their performance stays best to heavy CPU usage even with the use of AS3. For example, Flint, is a very good particle system but suffers with the same problems. Although, it is fairly obvious from the way Flash was designed that pixel level operations were not given a priority but I feel this takes a big chunk of users right out of Flash’s community.
Run this program in Flash AS3 and you’ll notice how much CPU is used running such a simple example. Creating sprites would take that meter to 75% at times. Run the same example in Processing:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void setup(){
size(500,500,P3D);}void draw(){
stroke(0,5);
beginShape(POINTS);for(int i =0; i <10000; i++){
vertex(random(500),random(500));}
endShape();}
The difference should be very obvious. If you have seen Flash CS4 features and the Quake Demo running on AS4, you might feel happy to think that Flash CS4 would pay much attention to the rendering engine currently used by Flash. Mostly in all cases, I give Processing an edge over many aspects of graphics routines that Flash lacks for the time being. If you’re into Particle based systems, Flash is not the tool for you.