AS3 & Flash


3
Apr 08

The Craft of Gamemaking

I presented this evening at the ACC. I think it went well. I’m definitely out of practice. The slides probably won’t be interesting without the talking, but in case anyone is curious: The Craft of Gamemaking.

If you saw the presentation, I’d love to hear from you in the comment section.


19
Nov 07

Too good to be true? Box2D for AS3

Just caught this on the feeds today (sorry, forgot where): Box2D for AS3.

Just “wow.” I had been jealous of the C++ guys with Box2D as it’s a very impressive, cleanly written 2D physics API, something Flash really needed. Sure, we’ve got Fisix if you want to pay for it, or APE if the feature set is right (and it’s what we’ve been using for the last year). But Box2D always appeared to be the best of both worlds: feature-full and open/free.

And seeing the demos on the page, it appears to be pretty freak’n fast as well. I’ve not downloaded it yet and done any tests, but my gut is telling me its 2x to 3x faster than APE, which is really impressive considering that it’s rigid bodies (as opposed to APE’s particle-based approach).

I’m looking forward to what the community produces with this resource, and I’m looking forward to getting to play with it myself!


25
Sep 07

Dynamic code loading in ActionScript3

In my post regarding using PHP for Code Generation, Cyrus Lum asked the following question:

I was wondering about being able to load .as3 code snippets or classes at run time – Let’s say a user can download the swf, then through sockets, I can deliver a section of the code as a bytearray that would allow the swf to function.

This is definitely doable, though I’ve not done in exactly the way requested (via ByteArray via sockets). The Flex Framework provides a Module API that does exactly this, and if you Google around a bit you’ll find the Module API’s original author’s blog where he outlines his early experiments in building the API. Basically, you compile your “plugin” object as a stand-alone ActionScript project, producing an SWF. You then load that SWF with the Loader class (which accepts a URLRequest for the SWF, or a ByteArray for the bytes you pull from a socket). Once you have the SWF, you simply cast it to some known class and begin working with it.

The Module API has a Module class as the container for your plugin. Using MXML, the user creates a class that inherits from Module. The Module API loads the SWF and casts the object to a Module (which inherits from UIComponent, which inherits from Sprite, which is what any SWF that you compile from AS3 turns into). The Module API assumes your module is a component, so it places it on the stage somewhere, but you wouldn’t have to do that (thanks to the AS3 DisplayObject API).


31
Aug 07

Using PHP for Code Generation

I’ve been using PHP lately to write the server-side of our product. One of the nice mechanics of PHP is that a PHP file is actually a text file that is output as it is read and the PHP code is simply escaped/executed… in other words, PHP is a templating language. While that’s not news for most folks, it hadn’t really hit home with me that because PHP is a templating language its an excellent tool to use for doing code generation. So, if its good enough for generating HTML pages then its certainly good enough for generating ActionScript source files! ;-)

A month or so ago I went looking for a command-line tool to take a list of assets (PNGs, MP3s) and make an SWF library out of them. My first stop was the excellent Swfmill. Unfortunately for me, Swfmill only supports up to version 8, and I’m using 9, and the last thing I wanted was to have to cross between AS’s two virtual machines just for loading assets.

I posed the question to the excellent Flexcoders group. I promptly got a suggestion from Alex Hurai (member of the Flex team at Adobe) that I could just do a bit of codegen to create an AS class full of embedded assets (using Flex’s embed metadata). So that’s what I did!

I’ll post the code sometime this weekend, once I’ve tested it completely and cleaned it up a bit, but it seems to work. I did a bit of reading on how the module loading code for Flex was written to give me a solid basis for how to handle things. Basically, I generate a class that implements my own IAssetLibrary interface, which is basically an interface that provides methods for querying and retrieving the embedded assets. The PHP codegen simply scans a specified directory, grabs the appropriate filenames, and populates a standard AS3 class. It then populates a few arrays (mapping filenames to embedded asset classes) and its done.

The way PHP-on-the-command-line works this just all spews out to stdout, so I just wrapped it all up in batch file that pipes things to .as file, then calls mxmlc (ActionScript3/Flex compiler) on that .as file. The result (after a very long time … mxmlc is dog slow because it has to fire up the Java VM, etc.) is a SWF with a single class in it, a Sprite (because root classes in an SWF have to inherit from Sprite or MovieClip) that implements the IAssetLibrary interface. I can then use the Flash API’s Loader class to load the SWF, cast it to IAssetLibrary, then retrieve my assets by filename!

The big reason for doing this is that our current build loads each asset individually from a URL (like a web browser rendering a webpage). This was entirely by-design (modeled after a web browser), but in practice (after many months of design revisions) we no longer require that degree of flexibility. And it comes with a cost: the current build makes 228 separates GETs to our server to gather all the assets, most of which are in the 5-10k ballpark. That’s a lot of network overhead. And code overhead, in both my code to manager all those requests and the Flash Player dealing with all those async calls.

And magically, an SWF compresses PNGs/MP3s smaller than just the raw files (elimination of redundant headers or something, I’m not sure)… the total weight of all the assets is 300k smaller (6.5MB compared to 6.8MB).


25
Jun 07

Pixel-Perfect Collision Detection in ActionScript3

UPDATE: Check out the most recent update to this post.

The Flash Player provides vector-perfect collision detection with the hitTest() method. The drawback of this method is that if you use Bitmaps it sees just the bounding-box of the Bitmap, i.e. it ignores alpha. This is pretty frustrating when it comes to a sprite-based game.

A bit of digging on the web found a quick and simple solution from Andre Michelle [.zip]. A slightly more robust version was written for AS2 by Grant Skinner, then ported to AS3 by Boulevart. I grabbed their version to start with...

First, I cleaned up the code and commented it. It's pretty straightforward: you render two display objects to separate color channels, combine the color channels, then search the resulting image for any overlapping color (the previous two sites have deeper explanations).

I found two problems with the code. First, it unions the bounding boxes of the two display objects. This is unnecessary, we only care about the pixels in the intersecting rectangle. And since performance hit of this technique grows with the size of the overlap, this is a critical optimization (you're allocating significantly less BitmapData each test).

Second, the code doesn't account for a display list of any complexity: it assumes the two display objects have the same parent (and are thus in the same coordinate space), and it assumes the display objects do not have any scale or rotation (it only considers linear transformation, i.e. the objects' positions). I fixed both of these.

So, the new code will determine if two DisplayObjects are visibly overlapping with pixel precision. Enjoy!

Actionscript:
  1. package
  2. {
  3.     import flash.display.BitmapData;
  4.     import flash.display.BitmapDataChannel;
  5.     import flash.display.BlendMode;
  6.     import flash.display.DisplayObject;
  7.     import flash.display.DisplayObjectContainer;
  8.     import flash.geom.Matrix;
  9.     import flash.geom.Point;
  10.     import flash.geom.Rectangle;
  11.    
  12.     public class PixelPerfectCollisionDetection
  13.     {
  14.         /** Get the collision rectangle between two display objects. **/
  15.         public static function getCollisionRect(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Rectangle
  16.         {
  17.             // get bounding boxes in common parent's coordinate space
  18.             var rect1:Rectangle = target1.getBounds(commonParent);
  19.             var rect2:Rectangle = target2.getBounds(commonParent);
  20.            
  21.             // find the intersection of the two bounding boxes
  22.             var intersectionRect:Rectangle = rect1.intersection(rect2);
  23.            
  24.             if (intersectionRect.size.length> 0)
  25.             {
  26.                 if (pixelPrecise)
  27.                 {
  28.                     // size of rect needs to integer size for bitmap data
  29.                     intersectionRect.width = Math.ceil(intersectionRect.width);
  30.                     intersectionRect.height = Math.ceil(intersectionRect.height);
  31.                    
  32.                     // get the alpha maps for the display objects
  33.                     var alpha1:BitmapData = getAlphaMap(target1, intersectionRect, BitmapDataChannel.RED, commonParent);
  34.                     var alpha2:BitmapData = getAlphaMap(target2, intersectionRect, BitmapDataChannel.GREEN, commonParent);
  35.                    
  36.                     // combine the alpha maps
  37.                     alpha1.draw(alpha2, null, null, BlendMode.LIGHTEN);
  38.                    
  39.                     // calculate the search color
  40.                     var searchColor:uint;
  41.                     if (tolerance <= 0)
  42.                     {
  43.                         searchColor = 0x010100;
  44.                     }
  45.                     else
  46.                     {
  47.                         if (tolerance> 1) tolerance = 1;
  48.                         var byte:int = Math.round(tolerance * 255);
  49.                         searchColor = (byte <<16) | (byte <<8) | 0;
  50.                     }
  51.  
  52.                     // find color
  53.                     var collisionRect:Rectangle = alpha1.getColorBoundsRect(searchColor, searchColor);
  54.                     collisionRect.x += intersectionRect.x;
  55.                     collisionRect.y += intersectionRect.y;
  56.                    
  57.                     return collisionRect;
  58.                 }
  59.                 else
  60.                 {
  61.                     return intersectionRect;
  62.                 }
  63.             }
  64.             else
  65.             {
  66.                 // no intersection
  67.                 return null;
  68.             }
  69.         }
  70.        
  71.         /** Gets the alpha map of the display object and places it in the specified channel. **/
  72.         private static function getAlphaMap(target:DisplayObject, rect:Rectangle, channel:uint, commonParent:DisplayObjectContainer):BitmapData
  73.         {
  74.             // calculate the transform for the display object relative to the common parent
  75.             var parentXformInvert:Matrix = commonParent.transform.concatenatedMatrix.clone();
  76.             parentXformInvert.invert();
  77.             var targetXform:Matrix = target.transform.concatenatedMatrix.clone();
  78.             targetXform.concat(parentXformInvert);
  79.            
  80.             // translate the target into the rect's space
  81.             targetXform.translate(-rect.x, -rect.y);
  82.            
  83.             // draw the target and extract its alpha channel into a color channel
  84.             var bitmapData:BitmapData = new BitmapData(rect.width, rect.height, true, 0);
  85.             bitmapData.draw(target, targetXform);
  86.             var alphaChannel:BitmapData = new BitmapData(rect.width, rect.height, false, 0);
  87.             alphaChannel.copyChannel(bitmapData, bitmapData.rect, new Point(0, 0), BitmapDataChannel.ALPHA, channel);
  88.            
  89.             return alphaChannel;
  90.         }
  91.  
  92.         /** Get the center of the collision's bounding box. **/
  93.         public static function getCollisionPoint(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Point
  94.         {
  95.             var collisionRect:Rectangle = getCollisionRect(target1, target2, commonParent, pixelPrecise, tolerance);
  96.        
  97.             if (collisionRect != null && collisionRect.size.length> 0)
  98.             {
  99.                 var x:Number = (collisionRect.left + collisionRect.right) / 2;
  100.                 var y:Number = (collisionRect.top + collisionRect.bottom) / 2;
  101.        
  102.                 return new Point(x, y);
  103.             }
  104.        
  105.             return null;
  106.         }
  107.        
  108.         /** Are the two display objects colliding (overlapping)? **/
  109.         public static function isColliding(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Boolean
  110.         {
  111.             var collisionRect:Rectangle = getCollisionRect(target1, target2, commonParent, pixelPrecise, tolerance);
  112.        
  113.             if (collisionRect != null && collisionRect.size.length> 0) return true;
  114.             else return false;
  115.         }
  116.     }
  117. }


18
Jan 07

Flex rhymes with…

Have I mentioned how much I like Flex? The ActionScript3 (EMCAScript/JavaScript) language is a pleasure to program in (garbage collected, dynamic *and* static typing, single-inheritance class hierarchies and built in XML (E4X) manipulation). Flex Builder 2 (which is Eclipse) is a spectacular IDE (trumping, dare I say, VS.NET 2003, my prior fave, but only with Visual Assist -- Visual Assist still trumps all). And the inclusion of declarative (MXML) programming hits a perfect sweet spot in my long time HTML coder's heart. It just seems perfect.

You know, kinda like exactly what I said would be the perfect game development environment back in March 2006. I sung the praises of the mindshift in software development brought on my "web 2.0" where production-quality development truly is agile: they divide the problem into structure, behavior and styling. Of course. The Holy Trinity of Interaction. You find it time and time again when you dissect anything one would describe as interactive: model-view-controller, input-process-output, listen-think-speak... structure, behavior and styling.

To recap: structure defines the layout of things, their relationships, both spatially and conceptually; behavior consumes the structure, plays on the structure like monkeybars, moves through it. And styling determines how the structure is presented, provides feedback, expresses.

In practical software development terms, I've discovered that means one needs a declarative language (MXML), an imperative language (ActionScript3), and support for skinning and/or style sheets (Flash, CSS). Flex bundles all three together.

Of course, it has a good application framework provided out of the box (that's free, in fact, along with the compiler... you just pay if you want the IDE, which is Eclipse, so you're actually just paying for the visual MXML editor, which is probably worth it, but certainly not required if you're patient or are experience with HTML/CSS). I can't imagine if there was a gamedev framework for it... that'd be sweet. ;-)

Chalk up one for Adobe (via Macromedia): Adobe Flex 2 is the finest software development kits -- nay, platform! -- that I've ever had the pleasure of dealing with. And this coming from a guy who's spent the last five years convincing game studios to adopt a commercial SDK (RenderWare), so I can smell my own kind... and I don't smell Flex at all! Clean as a whistle...

I think they will seriously give C#.NET a run for its money. Sure, C#.NET is probably faster on a Windows box, no doubt about that... but is it that much faster? And .NET certainly doesn't have the Flash graphics engine backing it up (your toolchain is already finished!). And it only really works on MS devices. And you have to download and install (and in Vista, enter an admin password!) because its a native EXE with all of the potential problems.

While Flash... well, Flash is ubiquitous. Hell, it's more standardized across user machines than Java or web browser and most certainly operating system. And your input, output and everything in-between is identical on whatever platform your user is using.

And, and, and... it's all sorts of integrated with and designed to a leverage the always-on-net-connection world that many, many of us live in.

Go now, you can buy it off the shelf. I did. Best $500 I've spent in a long time. No regrets.


10
Oct 06

Stuck in Limbo

I'm looking forward to getting stuck in Limbo. He's looking for C++ programmers, but I was first struck with how perfectly this game could be done in Flash. With Flash's new filters and improved performance, I'd guess he could get the exact same results, cross-platform and with a lot less development pain than C++.

It's a great example, though, of the kind of results we'll see as more people with classic art and graphic design backgrounds (with a sprinkling of programming experience) are brought into the gamedev fold. The in-development footage on his sight is hauntingly beautiful, and an inspiration to say the least. Makes me remember those first few hours playing Out of this World, still one of the few games to deliver so much on so little.

Speaking of Out of this World, I've always thought it'd be awesome to see that game remade in Flash (it's largely rotoscoped with a vector-like graphic style, very applicable to Flash development). Hell, if it fit on a 1.44MB floppy and ran on a 286, surely it can run full-speed in Flash on a modern day machine? Those are the kind of side-scrollers people need to be making... there's a lot of life left in that very simple mechanic! (And the side-scroller view? Well, that aesthetic has worked for "comics" for a hundred years.)


15
Sep 06

Perfect and Simple

TonyPa first came to my attention with his impressive tutorials on tile-based games in Flash. Later, I discovered his games page, which includes a maddening simple and addictive game called "Gear Taker." If you go to his site, click on "games" then click on the first game in the list "GEARTAKER" that'll lead you to it (sorry, no direct links available). This is the finest example of a "one button game." To play the game only requires pressing a single button (the left mouse button, of course). Yet with only that one means of input the gameplay is as addictive as any good game of Tetris or Bejeweled. And the aesthetics... well, the visuals are black-n-white, stick figures and gears (as simple as it gets), and the music has a single sample played at various pitches and tempos. And while the aesthetics perfectly understate the simple design, the music perfectly understates the incredible tension induced as your hapless stick figure flies across the screen.

Two words: perfectly simple. TonyPa, your creation serves as an inspiration to the rest of us. Thank god I don't have this on my mobile phone.

I would only add one option, an advanced mode for the masochists that involves timing. But it's probably for the safety of the masses that he didn't include something such as that.

My best score is between 2500 and 3000, around level 6 or 7. Good luck!


29
Aug 06

Physics in Flash

I've been most impressed with the collision detection and response (i.e. "physics") tutorials provided by Metanet, creators of N. They explain some fairly robust 2D collision detection and response in ActionScript, in particular their grid-based and raycasting solutions. Definitely check out their slides from their FiTC 2005 presentation.

There's also the Flash Dynamics Engine, which uses some proper physics algorithms (Verlet integration) to do a more general physics solver, though it's more expensive (but more realistic) than Metanet's stuff above.


28
Aug 06

Getting Started with Flash Game Development

Okay, I'm going to make this quick and to the point. I'll leave digging up all the details to the interested reader, but that shouldn't be a problem with the likes of Google, etc. I'll go into more detail about each element of Flash Game Development in later posts, but first for some basic concepts...

  • The Flash IDE -- by this I mean the original/traditional Flash authoring tool released by Macromedia (now Adobe). It's a fully integrated development environment for Flash by definition as it essentially represents the official feature set. The software is primarily targetted at artists and designers, with programmers (and larger application-like development) being a secondary concern.
  • The Flex IDE -- this is the most recent offering from Adobe in the Flash line and is targetted at rich internet application (RIA) developers (programmers). It's more similar to something like Java or C#. It's still al of the same Flash technology (well, Flash 9 technology) just packaged for application development. This is a very interesting development, but it's a little early for web-based games because of the lower version penetration than Flash 8. But this is changing rapidly as MySpace "officially" requires Flash 9 now for security reasons, and the Flash 8 player can update automatically (and very quickly) to Flash 9 as well. As a result, Flash 9 will probably achieve the necessary 85%+ penetration by this time next year (based on past Flash version pentration trends).
  • SWF -- ShockWave Flash, the output of the Flash IDE, and what runs in your browser (or technically, it runs in the Flash Player plugin in your browser or on your desktop). SWFs is a compact, streaming file format that is somewhat documented by Adobe/Macromedia... their documentation is usually just bad enough to slow down efforts to replicate their Flash IDE's full feature set. And it is not an open standard, though it practically is because it has been so often reverse-engineered with a high degree of accuracy (and Adobe has no problem with this). Many non-Adobe/Macromedia Flash-related projects operate with the term "SWF" instead of "Flash" as "Flash" is a trademark of Adobe/Macromedia and they don't take kindly to folks incorporating it into their product names (they prefer folks use "SWF").
  • ActionScript -- the programming language for Flash. ActionScript was originally a very stunted language used for some rudimentary scripting, but was soon morphed into a real language (EMCAScript, i.e. JavaScript). It's a full-blown object-oriented language that supports both strong/static typing and weak/dynamic typing. It is executed by a virtual machine in the Flash player, thus it is not as fast as native-compiled code (C++) and Flash currently does not have a JIT (just-in-time compiler) like Java or C#. But, Flash Player version 8 and version 9 both made significant strides in improving virtual machine performance. One caveat of the VM is that the Flash Player will allow the user to kill any long-running (i.e., a few seconds) loops. The most commonly discussed/used version of ActionScript is ActionScript2 (AS2); ActionScript3 (AS3) was released as part of the Flex/Flash 9 package.
  • MTASC -- the Motion-Twin ActionScript Compiler is what really blew open the open-source Flash community. Initially a replacement for the Flash IDE's slow (and buggy) compiler, it has turned into the gcc (Gnu C Compiler) of the Flash universe. It can compile raw ActionScript (text files, just like every other programming language) into SWF's. These SWF's can then be imported into the Flash IDE or used directly.
  • SwfMill -- an XML to SWF to XML processor, this tool serves as the "linker" in our open-source toolchain. SwfMill can take a list of images, SWF's, and sounds and convert them into an SWF file. Combined with MTASC one can go from a directory full of text files, PNGs and WAVs to a stand-alone SWF game that runs in practically any web browser.
  • FlashDevelop -- the open-source IDE for Flash. Written in C#, open-sourced, and actively developed, this is one of the best IDE's available for Flash (or rather, ActionScript). It uses MTASC and SwfMill under the hood and provides a great editor on top. Includes all of the features one would expect: auto-complete, projects, plug-ins, integrated help, library browsing, etc... Highly recommended.

Okay, now to ramble a bit... sorry for the poor organization of this post, but I'm wanting to just get some of this information out there in one place and I'm trying to do it quickly (while at work!)...

There are a few tutorials that nearly all Flash game developers have seen, and they discuss Flash game development from a "traditional" perspective using the Flash IDE. They don't really cover how to develop using only the free tools. But, they are useful for understanding the basics of Flash as they relate to games. TonyPa's tutorials on tile-based games (and check out his games they're quite a bit of fun!). Kirupa also has some excellent Flash tutorials. Flashier Flash has some excellent tile-based games tutorials as well.

In general, I'd suggest aiming to do Flash development very similar to traditional, 2D sprite-based development. With Flash 8, there are raw bitmap structures that you can access. And bit-blits are fast in Flash (from one bitmap to another), so you can implement sprite-based stuff just as you would in a traditional language. You can then take advantage of Flash's extras, such as fast custom filters and great font support.

Like I said, I'll speak about all of this in greater detail in a series of future posts, this is just the start.