Avocado Blog Zen and the Art of Flash Development

1Oct/094

Dynamically compiling assets to an SWC file

Although the projects I usually work on are quite code-based, there are always some number of visual assets that need to be included in the project. As the people making these things probably know, there are basically two methods of including these assets into the project at design time: using the embed -metatag, or compiling the assets into an SWC -file and linking that into your project.

I generally like the SWC -method better because it gives you better code hinting and strong typing, and it preserves the possible actionscript code in case there are swf files being linked. An SWC-file is basically a renamed zip file containing the compiled SWF and an XML-file that defines the stuff the SWF includes. You may try to unzip SWC:s with a regular zip-program to find out what it actually contains.

The problem with SWC:s is that they are binary files. I use SVN version control in all my projects, and binary files are basically unmanageable by the SVN server. It can see which version of the file was modified last, but combining two different binary files together is impossible for it. This is no problem when coding solo, but when there are multiple developers working on the same project, problems will occur. For example, if Mr. White adds an asset to the SWC, and Mr. Orange adds another asset at the same time, Mr. White commits his changes to the version control, and Mr. Orange commits shortly after, Mr. White's asset will be gone, as the SWC that Mr. Orange committed is the latest modified file, and the version control only sees that as the latest version.

This problem can usually be tackled by frequent commit/update from the version control and keeping tight contact with other developers, but it still allows mistakes to happen, and usually quite catastrophic ones, too. So what to do...

I've never really gotten around to use Ant tasks. I have been aware of the technology, but I've never seen any actual benefit of using them, until now. If you're not familiar with Ant, it's basically a way to script the compiler's build process with XML-files and Java. More information about using Ant in Flex Builder can be found from the Adobe Flex 3 Help.

So anyway, one sunny morning these two things came to my mind at the same time and I realized I could use Ant to dynamically compile an SWC file from files in a given directory. This would eliminate the need to:

  • Open the Flash IDE at all (which is a huge plus) ;)
  • Constantly commit/update changes to version control (although you should still do that)
  • Keep tight track of the assets embedded in the SWC and watch that you don't overwrite what anyone else might have changed

Basically, when you would want to add an asset, you would just add it to the given folder and build the SWC again with the Ant task, and if someone else commits changes to the SWC at the same time, it doesn't matter. Both of your assets are commited and in the version control, so you both just build the SWC again.

I'm aware that I'm not the first one who has thought about this approach, but when I googled for available solutions, I couldn't find anything that would be generally suitable for all kinds of projects, and most importantly, all the solutions handled only image files. As I need the same kind of behavior for both image and sound files, I decided to write my very first Ant-task (beer!). It came out quite nice, so I decided also to share it.

If you want to use this task to handle your assets, the first thing you need to do is to install the support for Ant-tasks. Here is the tutorial for Flex/Flash Builder. If you're using Eclipse/FDT/something else, google can help you. Just search

install ant <your favorite development tool>

Installing and using this Ant-task is quite easy, and there is a readme file included in the package which has these same instructions:

  1. Install the Ant support
  2. Unzip the package and copy the contents of lib-directory into the folder where you would normally place your swc-files.
  3. This task requires the Ant Contrib add-on, so copy ant-contrib-1.0b3.jar to your Flex Builder's ant/lib library. Usually that's something like /Applications/Flex Builder/sdks/3.2.0/ant/lib
  4. In Flex/Flash Builder Add FLEX_HOME environment variable to your environment variables:
    1. In the package explorer, right click the build.xml -file and select Run As -> External Tools Configurations
    2. Click the "Environment" tab
    3. Add a new variable and give it a name "FLEX_HOME", and set the value as "${eclipse_home}"
    4. Click Apply and close the dialog
  5. Open up the build.xml -file, and and in the line 20 check that the FLEX_PATH points to the directory of the SDK-version you're using.
  6. Bring up the ant-view by selecting Window > Other views -> Ant -> Ant
  7. Click the tiny ant icon with a plus sign, and locate the build.xml file you copied from the lib-folder.
  8. Launch the ant task target: Dynamic Shared Assets: Build Asset SWC

What the task does, is quite simple. It loops through files in given directory (which you can specify yourself), temporarily creates AS3 class files based on a template (default template is templates/class.template.general), compiles these classes into an SWC-file and deletes the temporary classfiles.

There are few lines that you may want to edit in the beginning of the build.xml -file:

 
<!-- User defined variables, modify these as needed -->
<property name="asset.path"            value="assets"/>
<property name="asset.bitmap.template" value="templates/class.template.general"/>
<property name="asset.bitmap.prefix"   value="Ext"/>
<property name="asset.bitmap.package"  value="ui.assets.bitmaps"/>
<property name="asset.sound.template"  value="templates/class.template.general"/>
<property name="asset.sound.prefix"    value="Ext"/>
<property name="asset.sound.package"   value="ui.assets.sound"/>
 

These properties define where the assets are found, which template to use for which kind of asset (so, for example, you may write your own functions for every sound asset if you want), and a prefix for the asset classes (so you may find them more easily with code hinting). Also you may set the package path according to the asset type.

Download the ANT-task and related files.

As usual, these files are provided with no guarantees, especially as this is my first experiment with Ant. You may use them in your projects whether they are commercial or experimental, but don't blame me if it all goes wrong. :)

29Sep/091

Scale9Bitmap Class

I often use Actionscript's native scale9grid -feature for scaling user interface elements. That's a neat concept as it allows the elements to have crisp borders and shaped corners, and still scale nicely to accommodate the needed space. The sad thing is that the scale9grid -feature only works for vector graphics and I often want to use bitmap graphics for the smaller user elements in order to minimize the amount of vector graphics that has to be rendered for screen, and because that obviously allows more flexibility for design.

For this reason I developed the Scale9Bitmap -class, which allows me to make, for example, a button in Photoshop, define a scale9grid for the image's bitmapData and just scale the button image so that the text or glyph fits nicely inside the button. The solution is to slice the given bitmapData into 9 pieces according to the scale9grid Rectangle, and then just to scale each one in the correct axis.

Here is a sample how the scale9grid affects the bitmap scaling:

Example of Scale9Bitmap in action

So, if this is a feature that you think you would find useful, go ahead and download Scale9Bitmap.

A more detailed specification of the scale9grid functionality is available at Actionscript 3.0 Language Reference.

This class is provided "as is", and still needs some development. In particular, there is one key feature still missing: the bitmap doesn't scale correctly below the given grid border size. So if, for example, you define a grid that has a 10px left column and the 20px right column, the bitmap is not scaled correctly if you set the width below 30px. Besides that, it should work nicely,  and I use it very often in my daily work.