Saturday, December 26, 2009

Stardust v1.1 - Now with Linked Lists

Stardust project homepage
Particle collection documentation

After a few days of struggle, I've finally done it! Now Stardust implements linked lists internally for particle collections instead of arrays. Linked lists are better than arrays for rapidly adding and removing elements at random positions, theoretically. I found the performance to remain pretty much the same after this major change. However, the internal particle list implementation is now hidden from clients, which makes it much safer, preventing direct access to the particle array as in version 1.0.

To iterate through particles in a particle list, you use the ParticleIterator interface. You shall be familiar with this interface if you have worked with the C++ STL library or the Java collection APIs.

I'll illustrate this iterator interface by some sample code. Here's how you set all the particles' positions in an emitter to (0, 0), the origin.

var particles:ParticleCollection = emitter.getParticles();
var iter:ParticleIterator = particles.getIterator();
var particle:Particle2D;
while (particle = iter.particle as Particle2D) {
particle.x = particle.y = 0;;

And this is how you add completely-customized particles to an emitter.

var particles:ParticleCollection = new ParticleList();
for (var i:int = 0; i < 100; i++) {
var p:Particle2D = new Particle2D();
p.x = 100 * Math.random();
p.y = 100 * Math.random();

Pretty clean and self-explanatory code, isn't it? I'm quite satisfied with how the interface ended up. From now on, I can tweak the internal implementation and algorithm of the particle list without having to change the code outside of the black box. Gosh, I should have done this long ago.

Tuesday, December 22, 2009

Stardust Video Tutorial - More On The Main Loop

View Video
View playlist
Stardust project homepage

It's been a long time since my last update for Stardust video tutorial. Thanks a lot to Clockmaker - his article introducing Stardust gave me a great motivation boost to get down to recording more new vids. Clockmaker inspires me a lot, including tilting illustrations in blog articles for 5 degrees :p

This video covers more in-depth details on the main loop, including emitter events, initializer/action priorities, and particle masking, which are very important must-knows if you really want to do some serious coding and complex behavior handling with Stardust.

Monday, December 21, 2009

Clockmaker's Stardust Butterfly Demo

View Clockmaker's article & demo
Stardust project homepage

I'm very honored to come to know that Clockmaker, one of my favorite Japanese ActionScripters, has gotten his hands on Stardust! He's created a couple of awesome Stardust demos at Wonderfl, a Japanese ActionScript community that provides online Flex compiling service. You don't have to have the Flex compiler to test your ActionScript code: just type the code on the website and see it work the magic on the fly, literally. You can check out his demos in his Wonderfl gallery.

Clockmaker's Stardust Butterfly demo is very, very astonishing. The glow effect, the fluid butterfly motion, and the reflection...they've all left me in silent awe. Just watch the demo on his blog and you'll know that I'm not joking!

Saturday, December 12, 2009

Boundary Collision Sparks

View SWF
View source
Stardust project homepage

That's it. I've always wanted to create an action trigger that is triggered by "collision" with a deflector, or "deflection" with a deflector not acting as an obstacle. Now I've finally got it done :)

The magic behind the scene is quite simple: the Deflect class is modified so as to map a deflector to a boolean value, a flag for determining if a "collision" or "deflection" has occurred, through a dictionary object; the DeflectorTrigger class then simply check the flag to determine if the trigger is triggered.

However, extra caution is now required when creating custom deflectors. If you decide that a deflector does not "deflect" a particle, the overrided calculateMotionData4D method must return a null value instead of a "new MotionData(particle.x, particle.y, particle.vx, particle.vy)" copy of the particle's original position and velocity, which tells the DeflectorTrigger class that it should not be triggered.

My next target should be creating a trigger that can detect interparticle collision, which would not be an easy task. Well, it's easy, but what I mean is that it's not going to be easy to implement it with action trigger structures; at least now I don't have the slightest idea about how to do it. I'll try and figure out a way to do it cleanly and efficiently.

Thursday, December 10, 2009

Stardust + ZedBox Example: Duo Firewheel

View SWF
View source
Stardust project homepage

I've always felt like the ZedBox extension for Stardust has been left out for quite a while, so today I decided to spent some time revising the extension by improving the performance, and add a couple of new features, one of which being the ZBBillboardOriented action, which is essentially a ZedBox version of the BillboardOriented action.

This example demonstrates the use of the ZBBillboardOriented action and the use of a custom gravity fields, the VortexField3D class. It also makes use of what the native Stardust 3D engine cannot do: hierarchical object structures. The two wheels are actually rotated "disk" ZedSprite objects added to the display list of a parent ZedSprite. These two disks originally lied on the XZ plane ,Y axis being the horizontal axis on the screen.

I'm planning on using the ZBBillboardOriented action heavily on one of my personal projects. I'll bring it into public once it's finished.

Monday, December 7, 2009

Asynchronous Computation

Trevor McCauley's article about asynchronous ActionScript execution provides a brilliant way to distribute CPU-consuming computation from one frame to multiple frames. I was so excited when I first read this article, eager to try it out so much, and finally, today I had the chance to give it a try.

One of my classmate was working on a project for a course on social networks. He used ActionScript for his project, trying to parse an XML file representing a graph of over 80 thousand nodes and reconstruct the graph using his own classes. If you, whether intentional or not, had somehow make your Flash program enter an infinite loop, you might know that Flash Player throws a time-out error if a single frame takes more than 15 seconds to render.

His XML file was so big that even parsing it from string to the AS3 internal XML type took a couple of seconds, let alone instantiating his own classes representing nodes and edges for that graph, and as I expected, he was faced with the 15-second-error nightmare.

I applied Trevor's idea to solve this problem by factoring out the instantiation of his classes and distribute it across multiple frames, and things worked out perfectly and beautifully!

Thanks Trevor. Love you :)

Here's some code snippet:

//loader for loading external XML file
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onLoad);

//start loading the XML file
loader.load(new URLRequest("myXML.XML"));

//XML variables
var xml:XML;
var nodes:XMLList;
var edges:XMLList;

//graph model
var graph:Graph = new Graph();

//asynchronous computation variables
var currentIndex:int; //this index keeps track of the progress of asynchronous computations
var length:int;
var startTime:int;
var allcatedTimePerFrame:int = 16; //approximately 60fps

//loader complete event handler
function onLoad(e:Event):void {
xml = XML(;
nodes = xml.node;
edges = xml.edge;

//initialize asynchronous computation variables
currentIndex = 0;
length = nodes.length();

//start building nodes asynchronously
addEventListener(Event.ENTER_FRAME, buildNodes);

//asynchronous computation for building nodes
function buildNodes(e:Event):void {
//take a snapshot of the current time
startTime = getTimer();

for (var i:int = currentIndex; i < length; i++) {
//build nodes in the graph model

//check if the computation is complete
if (currentIndex == length) {
//stop this listener
removeEventListener(Event.ENTER_FRAME, buildNodes);

//initialize asynchronous computation variables
currentIndex = 0;
length = edges.length();

//start buliding edges
addEventListener(Event.ENTER_FRAME, buildEdges);

//check if the time spent on this loop exceeds the allocated time per frame
if (getTimer() - startTime() > allocatedTimePerFrame) {
//display the current progress in a text field
progress_txt.text = "building nodes: " + 100 * (currentIndex / length) + "%";

//asynchronous computation for building edges
function buildEdges(e:Event):void {
//take a snapshot of the current time
startTime = getTimer();

for (var i:int = currentIndex; i < length; i++) {
//build nodes in the graph model
graph.createEdge(edges[i].@node1Name, edges[i].@node2Name);

//check if the computation is complete
if (currentIndex == length) {
//stop this listener
removeEventListener(Event.ENTER_FRAME, buildEdges);

//we're done!!
//display the graph on the stage


//check if the time spent on this loop exceeds the allocated time per frame
if (getTimer() - startTime() > allocatedTimePerFrame) {
//display the current progress in a text field
progress_txt.text = "building edges: " + 100 * (currentIndex / length) + "%";

Thursday, December 3, 2009

Synchronized Movie Clip

View SWF
View source
Stardust project homepage

The new SynchronizedMovieClip class is a StardustMovieClip subclass, which is for "time step synchronization" I mentioned in this article. In this demo you can notice that there's a slider bar for tweaking the time scale of the particle simulation (which tweaks the Emitter.stepTimeInterval property).

In the absence of the SynchronizedMovieClip class, the movie clips will play at the original speed even if the simulation time is scaled down, which is pretty logical since the frame rate is not changed, only the internal time scale for simulation changed.

Now the movie clips are SynchronizedMovieClip instances and the emitter has a StardustSpriteInit initializer and StardustSpriteUpdate action added to it, the movie clips can be synchronized with the particle simulation time scale. The StardustSpriteInit initializer stops the movie clips at the very beginning by calling the init() method defined in the IStardustSprite interface, which the StardustSpriteMovieClip class implements, and the StardustSpriteUpdate action sets the movie clips' frames according to the simulation time scale through the update() method, also defined in the IStardustSprite interface.

This is how the synchronization of movie clips and Stardust particle simulation is done.

Wednesday, December 2, 2009

Stardust Movie Clip

Stardust project homepage

If you've played with Stardust for a while, you might notice that there's an Emitter.stepTimeInterval property which allows you to dynamically adjust the particle simulation timescale. Here's one demo showing you the adjustable timescale feature in action.

Now that you can adjust the timescale of particle simulation, the next problem is how to synchronize your movie clips with the timescale.

Originally, there was only a StardustSprite class that extends the Sprite class. My original intent was simple: allow a display object to respond to each Emitter.step() method call and to have access to timescale information, in turn updating itself correspondingly. If a particle's display object is a subclass of the StardustSprite class, and the emitter has a StardustSpriteUpdate action added to it, then the display object's update() method is invoked upon each emitter step, with a reference to the emitter, timescale information, and a reference to the particle's data passed in as parameters.

In order to synchronize movie clips with the dynamically adjusted timescale, I wrote the StardustMovieClip class, which pretty much is just a movie clip version of the StardustSprite class, and I extracted the update() method into a separate interface, the IStardustSprite interface. Now if you use a movie clip that extends the StardustMovieClip class for the particles and add the StardustSpriteUpdate action to the emitter, you can handle timescale change by overriding the update method() in your class. I'll write a base class just for this purpose when I have time. But for now, you can try it yourself if you're interested.

Another addition to the StardustSprite family is the IStardustSprite.init() method. My original intention was to provide a way to "reset" recycled display objects for particles initialized by the PooledDisplayObjectClass. Since used display objects are recycled into a pool and taken out again for future use, they indeed need a way to reset themselves when they are taken out from the pool and used again. For instance, you might want reset the playhead of your movie clips back to the first frame. To invoke the IStardustSprite.init() method, add the StardustSpriteInit initializer to the emitter.

Tuesday, December 1, 2009

Pooled Display Object Initializer for Stardust

Stardust project homepage

One of the major CPU consumption cause of Stardust is the display object instantiation, since new display objects are created rather rapidly along the particle simulation. So I think using an object pool to store display objects that are no longer needed for future use is a nice way to improve performance.

The new PooledDisplayObjectClass and PooledDisplayObjectClass3D initializers are "pooled" versions of their counterparts, the DisplayObjectClass and DisplayObjectClass3D initializers, respectively.

I've run a quick performance test, and found that when using the PooledDisplayObjectClass initializer to initialize particles with display objects, the performance improves by approximately 10%~15%, compared to the original DisplayObjectClass initializer. It's not a significant improvement, but at least it's better :)

Wednesday, November 18, 2009

Pyronova 1.0 Beta & Butterfly Example

Pyronova project homepage

View documentation

I lied. I cannot wait until my midterm ends to finish Pyronova :p
Now it's in 1.0 Beta, and supports XML serialization.
Also, it's currently half-documented. I'll complete the documentation ASAP.

I've created this example combining Pyronova and Stardust. I think the outcome looks pretty nice :)

View SWF

The logics behind this effect is rather simple: the butterflies are created using Stardust (well, that's another story); the HueNode shifts the hue of the butterflies, and the BlurNode blurs the butterflies to create the glowy effect.

Tuesday, November 17, 2009

Pyronova Logo

Pyronova project homepage

View logo in full size

Whew, I'm kind of all-thumbs with Illustartor. It took me quite a while to get this lousy logo done :p

How do you think?

Friday, November 13, 2009

New Project for Post-Processing FX

View SWF

I'm starting a new project called Pyronova, which is a post-processing FX framework. It features a network-based design, which allows you to connect "Pyro nodes" as you like to create your own post-processing effects. The project is still under development, so the source you find in the repository is just its prototype.

Here's the network diagram for this example.

A BitmapDataNode represents a BitmapData object. A PerlinNoiseNode generates Perlin noise bitmaps. A DisplacementNode takes two inputs: one regular input and one as a displacement map. A BlurNode, as its name suggests, blurs a bitmap up. A RedrawNode redraws a bitmap with additional settings such as transformation matrices and color transforms. "Pyro layers" are final destinations for post-processing networks, each layer having one single root node as its "final appearance".

In this example, a BitmapDataNode is used to hold reference to the Bunny-In-Black (BIB) bitmap data. The BlurNode blurs the BIB bitmap (previously processed by the DisplacementNode with Perlin noise distortion) and then pass it to the RedrawNode. The RedrawNode is assigned a ColorTransform object with RGB multipliers of values 1.3, essentially lightening things up. Finally, Layer 2 presents this final "blurred and lightened-up" bitmap and is assigned an ADD blend mode, serving as a "glow overlay" to the original bitmap, which is displayed through Layer 1.

Here's some sample code that sets up the network:

I'll push this project into Beta as soon as possible.

Sunday, November 8, 2009

PushButton Game Engine Example: Arrow Walker

View SWF
View Source

This example is my first attempt to try out PushButton Engine, an AS3 component-based game engine. I must say that the guys working on this project really have done a fantastic work. This engine is highly flexible, highly extensible; moreover, it supports XML serialization and advanced asset management (such as run-time loading).

In a component-based game engine, everything is regarded as an entity, be it as concrete as characters, obstacles, or as abstract as scene, renderer. If, you might ask, everything is regarded as equal, how may their behaviors differ? The answer is component. Each entity can possess different set of components, which can store properties like position, and carry out behaviors such as moving. This component-based structure would solve the problems present in inheritance-based designs. If you are interested what problems can be caused by inheritance-based designs, you can check out this video by Ben Garney, the lead developer for PushButton Engine.

Alright, that's enough for the introduction. Now let's get down to the example. This example , called Arrow Walker, is basically just an arrow that can move around, controlled by the arrow keys.

NOTE: This example is built with the latest PushButton Engine, revision 615 so far. And the code shown in this post is partially stripped out and modified from the original source for clarity. You can check out the complete source code here.

First off, use the PBE.startup() method to start up the engine. This method essentially tells the engine which Stage instance is the main stage. Then for a most minimalistic example, at least a scene and an object are needed. In this example, I split the codes for these two entities apart for clarity (the setupScene() and setupArrow() method).

The allocateEntity() method is the method that must be used whenever you want to create a new entity.

Now lets look at the setupScene() method. All that we need for a scene is a DisplayObjectScene component. This component renders entities with a spatial component, which stores spatial information including position and rotation, and a DisplayObjectRenderer component. A SceneView object is a sprite the renderer can render onto.

Next, let's look at the setupArrow() method. The DisplayObjectRenderer component points to a movie clip named arrow_mc, which would be constantly rendered by the scene entity after the DisplayObjectRenderer component is added to the DisplayObjectScene component of the scene entity. The PropertyReference objects tell the renderer to query a specified spatial component for position and rotation information. For instance a property reference with a string "@spatial.position" assigned to it tells the renderer to look for a component named "spatial" and check the component's "position" property, in order to obtain the entity's position information. The same logic applies to a property reference with a string "@spatial.rotation" assigned to it.

Finally, let's look at the SimpleController component, which controls the arrow's moving behavior and handles border conditions, confining the arrow within a 640x480 rectangle region. This component extends the TickedComponent class, whose onTick() method is called every "frame". The _keyMap property is a dictionary object for storing key data (whether a key is pressed). You can check out the source code for this class to see it's complete implementation.

Note that the "frame" here doesn't mean the frame in Flash Player, but the PushButton Engine's own internal frame system handled by the ProcessManager class. It's designed this way so that the game's numeric data can update independently of the Flash Player's current framerate.

Alright, we're done. You can view the result here and check out the source code here.
For those advanced PushButton Engine users, this example seems to be way too easy.
But for those who are interested in this engine and are about to try it out, I hope this example helps understand the basic usage of PushButton Enigne.

Wednesday, November 4, 2009

Stardust Video Tutorial on Actual Coding

04 - Basic Workflow part 1

05 - Basic Workflow part 2
View Complete Playlist

Stardust project homepage

At last, the video tutorials have begun covering actual coding. If you've watched the video of my speech for the 2009 PTT Flash Workshop, you might have noticed that I used a tablet to hand-write in OpenCanvas, using it as a digital whiteboard. The second half of the 4th episode of the video tutorials is actually a remake of the whiteboard hand-writing, in a form of an *cough* elaborate *cough* PowerPoint animation.

Enjoy :)

Sunday, November 1, 2009

Stardust Video Tutorials!

01 - Introduction
02 - Class Responsibilities
03 - Getting Started

Stardust project homepage

Finally! I've started recording video tutorials for Stardust.

This is my first time trying to use PowerPoint in video tutorials. I think using premade slides does make the videos look better, and, more importantly, helps me remember what I should say :p

I haven't gone to the parts where actual coding takes place, but still, these videos are worth watching, since they give you a full understanding of Stardust features and class responsibilities.

Monday, October 26, 2009

My Speech on Stardust for PTT Flash Workshop 2009

Actually this workshop was held a couple of months ago (Aug 31st to be specific).

PTT is the most popular bulletin-board system in Taiwan. This workshop was for the PTT Flash forum members and people from the Taiwan RIA industry. I gave an one-hour speech on Stardust for this workshop. And here's the vid: WATCH VIDEO.

This was a workshop in Taiwan, so I spoke in Chinese :p
I'll start recording video tutorials on Stardust in English as soon as I have time.

Thursday, October 22, 2009

Stardust Tutorial And Examples by Matt Eley

Matt Eley has recently written a tutorial and some examples for Stardust!
Thanks a lot, Matt :)

View tutorial

Check it out! Matt has written this very detailed tutorial on the nitty-gritty of Stardust. He covered all the things you need to know to build a Stardust particle effect from the ground up, including initializers, actions, emitters, clocks, and renderers. I think reading this tutorial might help learning Stardust even more easily than reading the Stardust Manual. It's probably because I'm not a native English speaker...oh well, this gives me a rather nice motivation to practice English harder :p

View example

In this example, Matt showed the magic of combining bitmap filters with Stardust, creating this fantastic glowy spaceship thruster effect.

View example

I have to admire Matt for creating this example. He's done a brilliant job on integrating Stardust with Papervision3D, using particle effects to bring 3D Flash into an even higher level!

Thinner Builder, Smaller Stardust

Stardust project homepage
Stardust Manual (PDF)

I should have done this long time ago.

As listed in the feature list, Stardust supports XML serialization. The XMLBuilder class is in charge of converting a particle system to XML representation and reconstructing a particle system from a give XML representation.

How does the XMLBuilder class know the mapping from an XML tag's name to an actual Stardust class? The answer is the registerClass(), registerClasses(), and registerClassesFromClassPackage() methods. The XMLBuilder relies on these methods to acquire the knowledge of which XML tag name maps to which actual class.

These methods have to be called by the programmer: the more classes you wish the builder to build from XML data, the more classes you must register. The more classes you register, the larger the compiled file size, since more classes are linked together.

The registerClassesFromClassPackage() method is worth mentioning in particular. Subclasses of the ClassPackage class, which is essentially a collection of classes for convenience, all override the populateClasses() method to populate the classes (an array) property with class references. The registerClassesFromClassPackage() would register all the classes in a ClassPackage object in just one line of code. There are already several build-in class packages at your disposal: CommonClassPackage, TwoDClassPacakge, ThreeDClassPackage, ZBClassPackage, PV3DClassPackage, and ND3DClassPackage. All these class packages provide a getInstance() method to return a singleton object, since it's not necessary to instantiate a collection with a fixed set of elements yourself.

Class packages are convenient. But please beware: it's very likely that you would not use all the classes in a class package during XML deserialization, thus wasting some file size. It doesn't matter when the file size is of no concern; however, when you are working with a file-size-sensitive project, such as banner, file size becomes critically. In such circumstances, I would highly recommend you register classes one by one through the registerClass() method, just registering the class you would like to use when deserializing from XML data.

Originally, the XMLBuilder class registers the CommonClassPackage, TwoDClassPacakge, and ThreeDClassPackage by default. I've removed this default action in the latest revision (1.0.110 Beta), which I should have done long time ago.

You can see this class registering process in action in the 6th step of the XML reconstruction example in the Stardust Manual on page 41, which I just updated today.

Monday, October 12, 2009

CJLibrary Java - Client/Server and Signals

I chose Java as primary language for my Internet & Multimedia Lab class, and I decided to start the CJLibrary Java project. Eventually, I'll port some useful code from my CJLibrary (for AS3) to CJLibrary Java.

Here's the documentation for CJLibrary Java.

Currently the project mainly consists of the and the idv.cjcat.signals packages; the former is for client-server connection and the latter is an Observer Pattern framework inspired by Robert Penner's AS3 Signals project.

The package encapsulates complex client-server connection handling and exposes a set of user-friendly interface, including the use of the idv.cjcat.signals package.

Here's a quick look at how the package works.

//creates an EchoServer object and starts the server on port 2266
Sever server = new EchoServer(2266);

//creates two clients that connects to the server
Client client1 = new EchoClient();
Client client2 = new EchoClient();
client1.connect("localhost", 2266);
client2.connect("localhost", 2266);

Note that the Server and Client classes are both abstract. You have to extend them to create concrete subclasses. The createListener() method is the only method that has to be implemented. In this method you should return your desired SocketListener object, which is also abstract and whose mainLoop() method should be implemented.

Here's the EchoServer class:
(Sorry for the ugly intending. I'm still unable to get the code highlighter to work properly.)
public class EchoServer extends Server {
public EchoServer(int port) {
protected SocketListener createListener() {
return new EchoSocketListener();

As you can see, this concrete class is only overriding the createListener() method to tell this server which socket listener it should use, which listens to socket input.

The same logic is the same for the EchoClient class:
public class EchoClient extends Client {
protected SocketListener createListener() {
return new PrinterSocketListener();

Now let's take a look at the EchoSocketListener, which sends back, i.e. echoes, whatever it receives.
public class EchoSocketListener extends LazySocketListener {
public EchoSocketListener() {
onReceive().add(new SignalListener() {
public void update(Signal signal) {

This class extends the LasySocketListener class instead of SocketListener, because the LasySocketListener class further encapsulates the socket IO, providing a getReader() and getWriter() accessors to give user an even easier way of socket IO handling.

This class also demonstrates the usage of the idv.cjcat.signals package. The onReceive() accessor returns a Signaller object that dispatches signal objects of the Signal class. The add() method adds a listener that listens to signals of the Signal class, therefore the listener must implement the SignalListener interface and implement the update(Signal signal) method. This listener object simply tells the writter to print whatever message the signal is containing, which is the direct message sent over by the other end of the socket.

Finally, here's the PrinterSocketListener class for the client, which simply prints out whatever message received.
public class PrinterSocketListener extends LazySocketListener {
public PrinterSocketListener() {
onReceive().add(new SignalListener() {
public void update(Signal signal) {
System.out.println("client received: "+ signal.getMessage());

Now in the main program, the following additional lines of code would cause the two clients to send messages to the server and receive messages that are echoed back.
//sends messages to the server
client1.send("Hello. I'm client #1.");
client2.send("Hello. I'm client #2.");

And this is what you'll get from the console output:
Hello. I'm client #1.
Hello. I'm client #2.

These are messages that are echoed back by the server, and the order might be reversed, since the two clients have independent socket listener threads.

Thursday, September 24, 2009

Star Fish - A Game That Uses Stardust

Play this game

Stardust project homepage

Richard Davey created this fantastic game. The gameplay is very smooth, and the graphics is very appealing. The game rule is rather simple: get all the starfishes without hitting other fishes.

The bubbles in the background is created with Stardust Particle Engine. The bubble's motion is controlled by a Gravity action and a RandomDrift action. When the bubbles hit the stage boundary, they're killed by the DeathZone action with a RectZone as the death zone. Richard also added a little details to the bubbles in the menu scene: the bubbles bounce off the fish upon collision. This is probably achieved by using a CircleDeflector that follows the position of the fish.

Cute as the fishes may seem, the game is actually kind of hard to play as it gets to later levels, or it's just because I suck at playing games :p

Wednesday, September 23, 2009

Brilliant Fireworks

View SWF and source

Stardust project homepage

This is my entry for the 3rd WonderFL Checkmate Contest.

What could be better than a fireworks effect to show the power of Stardust?

I've subclassed an initializer (or spawn action) and an action for each of the four particles: Seed, Streak, Fireworks, and Spark. I've also extended the Renderer class to create a LineRenderer class, taking charge of drawing particle trails.

I think this is a good example to demonstrate the flexibility and extensibility of Stardust.

Wednesday, September 9, 2009

Stardust Now Available on WonderFL

WonderFL homepage
Stardust project homepage

Yep, you're right. Stardust is now available on WonderFL!!
I've created a couple of easy examples. You can check them out here.

Being in a rush, I only created 2D examples.
I'll be working on some 3D examples when I have enough time :p

Monday, September 7, 2009

Particle Snapshot Restoration

View example

Stardust project homepage

Click anywhere in the demo to explode particles, and click the "Restore Image" button to see the magic of snapshot restoration!

I mentioned this "snapshot" restoration stuff on my previous blog post.
This feature is now complete. You can grab it from the SVN repository.

The logics behind are pretty simple: the Snapshot class stores particle states (i.e. "snapshots") using an internal VO (value object) class, SnapshotData, and the SnapshotRestore class simply uses the easing equations to tween particles back to the previous taken snapshots.

I've also provided a ParticleRestoreFlag class for you to specify whether you want to restore the positions, rotations, scales, or more than one of these properties of the particles.

Friday, September 4, 2009

Left Out Stardust Template: Random

Get Stardust templates for FlashDevelop

Stardust project homepage

Oopsy. I just found out that I've left out a template for the Stardust template pack for FlashDevelop: the Random template. I've added the template and committed it to the SVN repository.

And for some info on the Stardust current development, I'm now working on a "snapshot" functionality for Stardust, which allows you to take "snapshots" of the current particle states, and then tweening particles back to this state afterwardg. You can optionally choose your restoration to work on position, velocity, rotation, angular velocity, or scale, and you can choose the easing equation at work as well.

My motivation for this functionality came out of a talk with Mark Vann from the ActionScript division at Medialand, back in the middle of August. He said he would like to create an effect using Stardust, causing shattered pieces of a bitmap to regroup. It involves no pro coding to create such effect, but he would like to have it done in Stardust; so I'm working on it now, trying to push the limit of Stardust another step further.

Tuesday, September 1, 2009

Linked List Failure for Stardust

Stardust project homepage

This is my second attempt to try using a linked list for particle engine. The first attempt was for Emitter, and this time it's for Stardust.

Theoretically, a liked list data structure is the best choice for a particle engine. Linked lists are well-known for their efficient removal of arbitrary nodes from the list. There's no way knowing the dying order of particles in a particle list, hence no way knowing the order of particle removal from the list. It seems that using a linked list for a particle engine's particle list is a good idea, but after my experiments, it turned out not to be the case.

I've tried to use a linked list for Stardust's particle list, and then recompile some of my existing examples. The result showed that the performance didn't improve; actually, it's quite the opposite: the CPU consumption got even higher (approximately 5% higher than the original).

I'm pretty sure when the number of particles is large enough, linked lists shall yield far better performance than arrays, but for common particle effects and daily uses, the number is simply not that large, thus the result. I got the exact same result from the attempt to use linked lists for Emitter.

The original array version of Stardust makes use of object pools to improve performance; however, I encountered some difficulty in implementing object pools for the linked list version (yeah, I'm just an amateur programmer). I think the performance gained by using object pools compensate for not using linked lists. I'll just stick with arrays for Stardust, unless I somehow get motivated to make my third attempt to try linked lists for particle engines (this really is time-consuming).

If you are interested, I've saved a copy of the linked list version in the SVN repository. Click here to download the RAR archive.

Friday, August 28, 2009

PureMVC Painter

View demo

View source

Whew...I just finished my very first PureMVC project. It's just a simple painter application, with standard pen, eraser, and clear functions, not appealing at all.

I've gone through PureMVC classes and documentations a couple of times, but never taken my time to actually try using it to build a complete application. Finally, I've put things together and create this little app. You can take a look in the source files if you're interested.

Stardust FlashDevelop Templates

Get Stardust FlashDevelop templates

Stardust project homepage

I've created a FlashDevleop template pack for Stardust. Now you can extend Stardust at ease without worrying about forgetting which methods to override. The templates include all abstract methods that need to be overridden for you.

Tuesday, August 25, 2009

Particle System XML Reconstruction Example

View manual (PDF)

I've added an XML Reconstruction example chapter after the Working with XML chapter. This chapter gives a brief example demonstrating how to reconstruct a Stardust particle system from XML data. And at the end it shows you the power of tweaking parameters of a particle system without recompilation, simply by modifying the external XML file.

Monday, August 24, 2009


View example

Stardust project homepage

Believe me, it looks much better in motion.

This example uses Perlin noise to create turbulence and a UniformField to pull particles toward the bottom left, preventing particles from being "blown" too far away from the intended direction by the turbulence. To add some flavor to the interactivity, I've also created a circle deflector following the mouse cursor.

Stars & Sprinkles

View example

View example

Stardust project homepage

I've ported these two basic examples from Emitter.
I think these effects are also very common.

The first one involves a SinglePoint zone following the mouse cursor, acting as the zone for the Position initializer.

The second example uses the Damping action to slow stars down, creating a damping effect.

Stardust Example: Drips

View example

Stardust project homepage

I saw this Flash & Math article, and tried to use Stardust to imitate the dripping & splashing effect :p

I though I could go back and make some simple Stardust examples unlike the recent fancy ones. After all, we all do need easy examples to help us get started, don't we? So here it is, a very simple drip-and-splash particle effect.

Sunday, August 23, 2009


View example

Stardust project homepage

I've added a new action: FollowWaypoints.

Used along with the Waypoint class, this action causes particles to follow waypoints in series, creating a path-finding behavior. There's also an option for whether particles loop back to the first waypoint after passing through the last waypoint. A 3D version is available as well: the FollowWaypoints3D class.

The algorithm used by the FollowWaypoints class was inspired by the Path Finding section in the Steering Behavior chapter of AdvancED ActionScript 3.0 Animation, by Keith Peters.

Saturday, August 22, 2009

Masked Collision & Turbulent Pixels

View example

View example

Stardust project homepage

Here are two more examples for Stardust.

The first one demonstrates the particle masking feature: each particle is assigned an integer mask, and two particles would only collide against each other if the bitwise-AND of their masks is non-zero. In this example, red particles are given a mask of (1 | 2 | 4), green ones 2, and blue ones 4. The result is that each particle collides with others of the same color; moreover, red particles also collide with particles of the other two colors. You can notice that a green particle does not collide with a blue particle, since the bitwise-AND of 2 and 4 is zero.

The second example shows the PixelRenderer class in action. This class renders pixels into a BitmapData object. The turbulence effect is created using Perlin noise along with a BitmapField object used as a gravity field.

Friday, August 21, 2009

ZedBox Carousel Effect with Depth-of-Field

Launch Site

ZedBox project homepage

Milkmidi at Medialand created this carousel effect using ZedBox, my 3D billboard engine.
He also used the BlurZFilter class to create a depth-of-field effect.

Using ZedBox, to create this carousel effect simply involves placing objects into a parent container, and tweaking the parent container's rotationY property.

Tuesday, August 18, 2009

Pixel Star Fireworks

View example

Stardust project homepage

I've added a Color initializer and PixelRenderer renderer.
As the renderer's class name suggests, it draws pixels into a BitmapData object.
This example was inspired by this Flint example.

Monday, August 17, 2009

Stardust Class Inheritance Diagram for Kids

View diagram

That's it. I've had enough of UML class diagrams.
They look professiona, but are visually...uh...tasteless.
So I decided to create class diagrams of my own style for the Stardust manual.
This is the class inheritance diagram in the manual.

Sunday, August 16, 2009

Stardust Manual

View manual (PDF)

Behold! It's the Stardust manual!
Although it's still not complete, it has already covered the features and class responsibilites of the engine.
And it also includes a minimalistic example at the end. I'm sure this will help understand the basic usage and workflow of Stardust.

Thursday, August 13, 2009

Stardust Particle Engine Goes Beta

Project homepage

Yes, Stardust goest beta!
There are already a bunch of examples to watch, source files provided.
Check them out on the project homepage or download them directly.
I've also added a very abstract class diagram.
I'll make more diagrams and tutorials to help you understand and use Stardust :)

Here's the class diagram.

View Stardust class diagram

Tuesday, August 11, 2009

Pink Triangles

View example

Stardust project homepage

This is a test for the CalculateScreenVelocity BillboardOriented actions for Stardust 3D (the Stardust native 3D engine). The CalculateScreenVelocity action projects a particle's velocity vector in 3D space onto the screen, yielding a 2D vector. The BillboardOriented action then align 2D display objects' rotation values to these 2D vectors.
You can pause the example by pressing the "Pause" button at the bottom left. The simulation will stop, but the particles will still align to their projected 2D velocities as you rotate the camera.

The source files for this example can be found here.

Monday, August 10, 2009

Stardust Sakura 3D

View example

Stardust project homepage

After the Sakura examples for ZContainer and Emitter, this is the third generation of Sakura example, for Stardust! It's seems that Sakura demo is a must for all my engines now.
I didn't use the ZedBox, Papervision3D, or ND3D extension. Stardust has a native 3D rendering engine.

You can press the "Pause" button at the bottom left to pause the petals, and rotate around the camera to look around. Enjoy the bullet time :p

The source files for this example can be found here.

Sunday, August 9, 2009

Exploding Image

View example

Stardust project homepage

Looks familiar? Yes, it's imitating this example from Flint Paritcle System.
The only difference is that Flint uses a static method defined in the Particle2DUtils class to create particles from a bitmap, and Stardust uses the BitmapBurster class, a subclass of Burster, to do the same thing.

The source files for this example can be found here.

Uniburst Is Back in Stardust!

View example

Stardust project homepage

As a left-out feature from the upgrade of Emitter 1.0 to 2.0, Uniburst is back in Stardust!
Now there's a Burster class whose sole responsibility is to allow user to create custom particles with full control over the particle properties, which means you can create particles that shows randomness (which is pretty much what Stardust is doing) or particles whose properties conform to a regular, uniform pattern. The latter is what Burster is mainly meant for. So far there's only one subclass, the PointUniburster class. It works just like the uniburst() method of the PointSource in Emitter 1.0: it bursts out particles spreading out at uniformly distributed angles. I'll make more Burster subclasses in the future.

The source files for the example can be found here.

Saturday, August 8, 2009

Stardust Example Screenshot Wall

Right on! This "wall of examples" sure looks attractive, doesn't it? And I'll add more tiles to it!
Things to do: complete documentation and official tutorial website.

Two More Stardust Examples

View example

View example

One of the best features of Stardust is the Spawn action (and yes, there's a 3D version, I'll make an example of it as soon as possible), and I made a fireworks example out of it.

Also, the ZedBox extension is now complete, so I made use of the BlurZFilter provided by ZedBox to create the depth-of-field example.
If you are using a debug Flash Player, you'll notice that there're some errors being thrown, something concerning FocusManager class in the fl.* package. This happens when you use Flash UI components with ZedBox. I have no idea how this happens, but you can simply ignore the error since it has no impact on the Flash movie.

The source files for these examples can be found here.