Wednesday, July 23, 2008

Whatever frame rate you set to your Flash project to, always test it under a low frame rate setting (such as 10fps) to make sure everything still works solidly, and this will allow you to see how your app behaves on low end machines.

Saturday, July 19, 2008

Debugging Tip #2

Another snippet that is useful for debugging is the flash.system.System.totalMemory.

trace(Number(System.totalMemory / (1 << 10));

This will display the total memory in KB.

To display it in MB,

trace(Number(System.totalMemory / (1 << 20)).toFixed(2));

Debugging Tip

At times you might find yourself wanting to know if your swf is running in a debug version of Flash and behave accordingly. You can do this by making use of the fact that Error class's getStackTrace() returns null when running in non-debug version of Flash player.

function isDebugPlayer( ) : Boolean
{
return Boolean(new Error().getStackTrace());
}

Actionscript 3's Array and String are now more improved and has a lot of methods found only in the popular scripting languages such as Perl, Python, etc.

If you are not aware of these changes, you should hop over to
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/Array.html
right away.

New array methods you will find useful:

indexOf, lastIndexOf
every, some
filter - filter out the items that pass your test into a new array
forEach - transform all array items in one fell swoop in place
map - similar to forEach, but returns the new transformed items in new array


Some of the new useful string methods:
search
match
replace - no more custom solution!

Tuesday, July 15, 2008

Colin Moock had a blog post today on the things you need to do to totally unload a swf from your code, I am attaching them here for convenience:
--- snip ---
  • Tell any loaded .swf child assets to disable themselves.
  • Stop any sounds from playing.
  • Stop the main timeline, if it is currently playing.
  • Stop any movie clips that are currently playing.
  • Close any connected network objects, such as instances of Loader, URLLoader, Socket, XMLSocket, LocalConnection, NetConnections, and NetStream.
  • Release all references to cameras and microphones.
  • Unregister all event listeners in the .swf (particularly Event.ENTER_FRAME, and mouse and keyboard listeners)
  • Stop any currently running intervals (via clearInterval()).
  • Stop any Timer objects (via the Timer class’s instance method stop()).
-- snip --

More info can be found at http://www.moock.org/blog/archives/000279.html

One thing to take away from this is that when you are working out your code architecture, you can try to obtain a lot of the resources above through a single point of access. While this will inherently increase the coupling of your code to that one component, it does have the benefit of allowing you to easily manage all your resources in one place and do all the cleanup work in one place. Something to think about.

Monday, July 14, 2008

Actionscript 3 Class Destructor (in my dream)

I wish Actionscript 4.0 will come with a destructor. It's so useful to not only know when your object is born, but when it's about to die as well. Even though AVM implements garbage collection scheme, there is still no reason why we can't have a destructor. The moment an object becomes a candidate for garbage collection, its destructor can be called and us the users can do whatever we want (such as doing cleanup work, tracking for memory leaks, prepare an epitaph for the object (jk), ...)

Sunday, July 13, 2008

Loader and URLLoader

If you are just starting out coding in Actionscript 3, at times you might find yourself asking: What is the difference between Loader and URLLoader? Well, before you get asked by someone to RTFM, just remember that Loader inherits from DisplayObjectContainer, so anything that you might use for display purposes (such as swf, jpg, png etc.) you will load it via Loader. URLLoader, on the other hand, inherits from EventDispatcher, so anything that you use as data (such as xml, text file, etc.) you will load it via URLLoader.

Using namespace for your Flex library swc

I downloaded degrafa today, and built the swc from source. I wanted to use the library like so in my MXML file:

First time when I built it, I got an error trying it the above way.
Read up on the doc, and this time I included the Namespace URL and Manifest file path in Project Properties->Flex Library Compiler.
Tried it again and still no go, got some dumb "Could not resolve x to component implementation" error.
Read up the doc one more time on the compiler option one more time, this time I included another parameter -include-namespaces and rebuilt the project, and it worked.




Tuesday, July 08, 2008

Collision detection code is usually one of the most CPU intensive part of any game engine. Done improperly, it can severely cripple your frame rate, and worse, make your game looks unrealistic. After all, it's never realistic to see a bullet flying through thick walls or one car stacking on top of another.

One important key to doing collision detection is to know when not to do it. If you could reject a potential test early on, then you just saved yourself some CPU there. Another thing to be mindful of is the boundary condition. That is, what happen if a bullet is on one side of the wall in this render cycle, but appears on the next side of the wall in the next render cycle? What happen if your game is running on a slow machine and therefore render at a very low frame rate? Usually that means your collision detection code will get call less, making it less accurate and therefore all that more important to work for things that are moving at relatively higher speed.

Let's say you have a driving game that is a top-down scroller. In the game, the player's car can switch lane very quickly. To reduce the amount of collision detection needed, you have made it so that the player's car only detects for collision when it's switching lane. Let's also assume that you employ a very simple scheme of collision detection by using hitTest of the player's car against all the cars in the next lane that is' switching to. In the event of collision, the car will abort its lane changing operation and goes back to its original lane. If the car has successfully switches lane without hitting any car in the process (based on when its position snaps with the new lane's position), no lane change abortion will be performed.

Now imagine everything is going good, and suddenly your game is running at 10fps. That means your collision code will only be run every 100msec. One very possible scenario is that the collision code only gets to run once while the car is switching lane, and the next time it runs, the car has already snapped onto the new lane and then collide with another car there. But since the lane change has already finished, it will not abort and end up getting stuck on top of that car.

In a situation like this, a simple hitTest might not suffice. You will likely need to employ a different collision check scheme (such as a simple ray trace), enlarge the bounding box of the car when the frame rate is low, etc.

As you can see, collision detection is a huge subject, knowing and doing it properly is the key to making your game perform well both from the performance standpoint and gameplay standpoint.

Friday, July 04, 2008

Quiz of the Day

If class A implements interface IA and class B inherits from class A. We know that class A is an instance of interface IA by virtue of the interface implementation, but is class B an instance of interface IA through inheritance?

There is a bizarre limitation in MXML that if you were to create a container with child tags in it, you can no longer include any child tag if you were to use it when using the container in another MXML file.

Here is what the documentation says:

"...If you include child tags of the root container tag in an MXML component file, you cannot add child tags when you use the component as a custom tag in another MXML file. If you define an empty container in an MXML file, you can add child tags when you use the component as a custom tag.

Note: The restriction on child tags refers to the child tags that correspond to visual components. Visual components are subclasses of the UIComponent component. You can always insert tags for nonvisual components, such as ActionScript blocks, styles, effects, formatters, validators, and other types of nonvisual components, regardless of how you define your custom component."

Essentially, if you are creating a custom component that is a container, it will no longer be a container if you add child elements to it!

There may be a technical reason behind why this is not possible yet, but from a user's standpoint, it's an annoyance because it goes against the intuition and certainly violates the Principle of Least Surprise.

I ran into a strange issue with the Flex debugger today. Basically, it would take a long time for the swf file to be connected to Flex builder's debugger.

I checked the port usage (netstat -ano), didn't see anything suspicious -- I am seeing Flex is listening on port 7935, which is a correct behavior when debugging Flex app (Flex basically listens on that port, and the debug version of Flash plugin would attempt to connect to that port upon launch).

I checked mm.cfg, didn't see anything strange there. Looked at hosts file, looked good (127.0.0.1 is mapped to localhost). Tried installing a new version of Flash debugger plugin, no go. Cleaned the project, it didn't refuse to work. Finally, I tried to debug things with a different Flex project, and it worked fine! I looked at the difference between the two projects and the only difference is that one is a project running locally, another one is running through Apache + ColdFusion via a virtual host. A quick look at the services in the service browser (type services.msc in Run dialog box) and I saw that ColdFusion Application Server had been stopped. I restarted it and voila, everything worked like before!

While looking for a solution, I also came upon the link below, it didn't end up helping me, but it might to someone out there.

http://therush.wordpress.com/2008/03/11/resolved-flex-builder-3-debugger-stopped-working/