

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.
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.
Sunday, November 8, 2009
PushButton Game Engine Example: Arrow Walker
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 idv.cjcat.net 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 idv.cjcat.net 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 idv.cjcat.net package works.
//creates an EchoServer object and starts the server on port 2266
Sever server = new EchoServer(2266);
server.start();
//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) {
super(port);
}
@Override
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 {
@Override
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() {
@Override
public void update(Signal signal) {
getWriter().println(signal.getMessage());
}
});
}
} 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
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() {
@Override
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.









