Archive for the 'Flex/Flash' Category


Functional Programming in AS3 1

I’ve never done a lot of functional programming. Sure, I did a bit of required Scheme in my Programming Languages class in college. Didn’t do anything real though — well, maybe a bit of decent AI stuff, but no actual apps. The point is, I’ve never really worked extensively with functional programming largely because the languages/tools I’ve been working with haven’t been purely functional.

Well, apparently I’ve just been missing it in AS3. It was staring me plainly in the face but hadn’t really thought about it in those terms. Bruce Eckel did, though. He shows how we can use the various Array methods (and add some of our own since Array is dynamic) to work functionally. There’s some very clever stuff in there, particularly the in-line functions that leverage closures to return results to the calling method… very clever use of AS3.

There is quite a bit of noise in the article related to his working with Flex Builder and writing the MXML to display the results of his tests. He also has a very — aheminteresting code style that I wouldn’t suggest anyone follow if you plan on sharing with other AS3 coders. I’m referring to his mixing of MXML and AS3 (and I’m not talking mx:Script blocks, either). First time I’ve ever seen that…

This is why I use Flash. 1

Peter Christensen explains why I feel no shame for moving from the world of cutting-edge console games to web-based Flash games.

The Craft of Gamemaking 6

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.

Too good to be true? Box2D for AS3 1

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!

Dynamic code loading in ActionScript3 3

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).

Using PHP for Code Generation 2

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).

Pixel-Perfect Collision Detection in ActionScript3 21

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. }

Flex rhymes with… 6

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.

Stuck in Limbo 1

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.)

Perfect and Simple 1

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!

Next Page »