Tuesday, September 2, 2008

Fun with Particles and Filters (AS3) Part 3

In Part 1 I used Movieclips to recreate smoke.

In Part 2 I used Blitting and greatly increased performance but struggled with the alpha change (solution discussed in comments of that post).

And now for Part 3, which I promised over a month ago that I would post more detail about the Blitting process.

Here goes my attempt... let me know if I need to clarify anything:
To implement the Blitting Technique you will need create a "Canvas" bitmap that will be the only DisplayObject that you will add to the stage.

Create 1 Sprite/MovieClip of the item that you will be making copies of. Do do not add this item to the screen. Instead, just store its BitmapData to be used later.

Next, create a pool of Objects that store "x", "y", and any other parameters that you would like. These Objects will represent the Sprite/MovieClip we created above. Each time you are ready to render, loop through the Objects and update their "x" and "y" parameters.

Once all the Objects have been updated, lock your "Canvas" bitmap to prevent the Flash player from trying to render while you are updating. Now loop through each Object and copy the pixels from the BitmapData you stored at the beginning and place them on the Canvas at the Object's given x/y location. Once all the objects have been copied to the Canvas, unlock it.

If I haven't confused you yet, you just successfully implemented a basic BLIT. I say "basic" because it only uses 1 BitmapData to be copied which restricts you from having multiple frames and restricts you from making changes in rotations/alpha/scale.

In order to create the Smoke from Part 1 and Part 2, I had to change both the alpha and the scale.

To tackle the scale I created a new BitmapData for every possible scale value that I allowed (I limited the possible values to a certain range that would increment by a certain amount. ex: 1-10 by .5, so 20 BitmapData items). I stored each of these BitmapData items in a "HashMap" to be retrieved later and used their scale value as their key in the Hashmap.

I then added a "scale" parameter to the Objects in the pool and updated their scale when I updated their x/y. I would use the scale of the Object to retrieve the correct BitmapData item from the hashmap.

I tackled the alpha in a similar fashion, but instead of storing BitmapData I stored a different ColorMatrixFilter to represent every possible alpha I wanted to display. I then applied the Filter before I copied the pixels from the BitmapData.

Hopefully I explained things clearly. Please let me know if I need to clean anything up.

No comments: