creating a simple particle system

August 13th, 2008

This week I decided to go over creating a basic particle system. Particle systems are fun to play with, and as you will soon find out, easy to start experimenting with.

the Particle Object

First we will create a particle object. For our particle object, we will extend the Bitmap Class. We could alternatively extend sprite, movieclip or shape for our particle object. Bitmap is good in this case because we don’t need any of the functionality that the other objects offer, and helps us to keep the resource needs down. Lets look at the Particle object.

public function Particle(bitmapData:BitmapData, speed):void
{
super(bitmapData);
this.speed = speed;
}

As you can see from this constructor function, the particle object is an extremely simple object. All we are adding to the standard Bitmap object is the speed variable. By adding this to our particle object, each instance of it can have a unique speed value. This is helpful in creating a more organic feel in our system.

setting it up

The next step is to create multiple instances of particle object, storing each one in an array for access later on. In the code below, I assign the variable speed a random number. I then use that same value to affect the scale of the particle objects. The result of this is that bigger particles will move faster, (due to there higher speed value), which creates the illusion of depth in the system. I am also spreading out the particles randomly across the x and y axis of the stage. If we don’t do this they will all be created on top of one another.

var p:Particle = new Particle(myBitmapData, Math.random()*5+2);
p.x = Math.random()*myStageWidth;
p.y = Math.random()*myStageHeight;
p.scaleX = p.scaleY = p.speed/10
_particles.push(p);
addChild(p);

animating it

Now that all the particles are created all that is left to do is update their individual positions on a enterframe loop as seen in the code below.

var l:int = _particles.length;
for(var i:int=0; i
{
var p:Particle = _particles[i] as Particle;
if(p.y > myStageHeight) p.y = -30;
if(p.x > myStageWidth) p.x = -10;

p.y += p.speed;
p.x += p.speed;
}

A quick if statement checks to see if the particle has left the stage area, if so, it is repositioned on the stage where it can fall back into view. Afterwards each particle’s position is update based on its speed value, resulting in the example below.

Grab the example files here.

Pixel Tutorial

July 30th, 2008

But first…

This is the first tutorial in a collaborative project between Brett Forsyth of TheStem.ca, Pablo Kraus of pablokreative.com, and myself, where each week we will each be writing and posting a tutorial on our sites. Look forward to a growing collection of diverse tutorials. Note however, I will be away on holiday’s next week, and most likely will not have a chance to share one.

Working with pixels.

The release of Flash 8 gave us a powerful object, the BitmapData object. This object gives us a lot of control over bitmap images, and the opportunity to create some really amazing effects. In this tutorial I am going to go over the basics of manipulating a bitmapData object, and controlling the movement of each individual pixel within it.

The pixel object

A 200×200 pixel image has 40 000 pixels in it, that’s a lot of data to manage, so a simple data object comes in really handy. Here is a simple object that just contains a few values. This object will represent one pixel in our final application. In my demo, and the attached source code, this is this is the Pixel.as file.

var px:Number; //the pixel’s x position
var py:Number; //the pixel’s y position
var ox:Number; //the pixel’s original x position
var oy:Number; //the pixel’s original y position
var c:uint; //the pixels colour

Animating it

The next step is to actually take a bitmap image and create one of these objects for each of its pixels. We do this by looping over each pixel individually, and using its data to construct our object. As we create these pixels we also save them to an array so that we can access them at a later time.

In this sample code, I use a nested for loop to accomplish this task. It goes through the pixels row by row using the getPixel method of a bitmap data object to return that pixels colour value. The two loop’s values, i and j, tell me the pixels position, and with those I create the pixel object.

for(var i:int = 0; i > myBitmapData.height; i++)
{
for(var j:int = 0; j > myBitmapData.width; j++)
{
var colour:uint = myBitmapData.getPixel(j,i); //returns a unit colour value
var p:Pixel = new Pixel(j,i,colour);
_pixels.push(p);
}
}

At this point we have the information we need to perform a pixel based animation. Using an EnterFrame loop, we can cycle over our pixel objects and update their positions every time the frame refreshes. Lets take a look at an example where the pixels follow the mouse around.

private function render(e:Event):void
{
_myBitmapData.lock(); //lock the bitmapData object so it dosen’t update until I’m done
_myBitmapData.fillRect(new Rectangle(0,0,stageWidth,stageHeight),0×00000000); //clear the object of old pixels

var l:int = _pixels.length;
for(var i:int = 0; i < l; i++)
{
var p:Pixel = _pixels[i] as Pixel;

p.px -= (p.px – (p.ox+mouseX))*p.speed; //a simple chase formula determines the mouse’s new position
p.py -= (p.py – (p.oy+mouseY))*p.speed;

_myBitmapData.setPixel(p.px,p.py,p.c); //apply the information as a new pixel on the object
}
_myBitmapData.unlock(); //unlock it so the update takes place
}

In this example you will notice that a new value has been added to the pixel object called speed. Speed is a random number between 0-1, that I am creating on every new pixel object. This example works fine without this extra value, however, when all the pixels move at the same speed they don’t look like pixels, but rather an image. The random speed value allows them to move separately so that we can actually see the effect taking place.

Below is an example of what it looks like. The example files are here. If you have any questions please feel free.

This site uses icons created by Mark James, www.famfamfam.com/lab/icons/silk