This post discusses the various workflows for producing SWFs with the standalone compiler that use graphical assets and animations created in Flash Professional (“Flash Pro”). At time of writing the latest version of Flash Pro is CS4, with CS5 briefly out in beta for a short while. Specifically we look at the methods that involve exporting SWCs and using the [Embed] metatag within class files.
Recently I posted a bug report regarding the [Embed] metatag, which led me to write this post in order to find out whether people are happy with their current workflows and how well others receive projects when it comes to handovers and maintenance.
Background
So you’re building an application, a game, or a website. Immediately you have two options when it comes to setting up your Flash project. You can create an FLA file, assign a document class and get coding, or you can fire up Flash(/Flex) Builder/FDT/Flash Develop et al, create a new Flex or AS3 project and compile it using the Flex SDK compiler. Pretty much every time I’ll opt for the latter because of the increased reliability of the application, and faster compile times.
Even if you use the first option, compiling in Flash Pro itself, you may be actually editing your code in Flash Builder or some other IDE, but the point is the compiler being used in the former is Flash Pro, and in the latter mxmlc/compc the Flex SDK compilers. For the purpose of this post we’ll be looking at Flex or AS3 projects using the Flex SDK compiler, and how to get assets from a FLA, into your project.
I’ve written the following to the best of my knowledge, but there are always tips and tricks that I may be missing, perhaps an entire workflow. If you spot any inaccuracies or flaws please let me know in the comments and I’ll change it ASAP.
Why an FLA at all?
You probably already know you can embed PNGs, SVG and other file types in your classes and never go near an FLA to get graphics into a SWF. When it comes to animations, you may use TweenLite or GTween to perform transitions, but when it comes to frame-based animation, character animation, or simply buttons and panels with hand-made flourishes you may want to use an FLA to create and animate these using the powerful timeline, graphics and animation tools within Flash Pro.
It’s at this point you ask yourself, how do I get these assets from a FLA into my project if I’m not compiling my project in Flash Pro?
The Workflows
Here are 5 methods for getting assets from an FLA, into a Flex or “pure AS3″ project. I’ve excluded those which are MXML-only as this post is not about Flex specifically.
1. Publish SWC from FLA
This method involves linking library symbols to classes, so instead of “MySymbol” in the class field, you have “com.package.MyClass” which refers to a class file in one of the FLAs classpaths. You must then turn on SWC export in the FLA Publish Settings panel, and most likely turn off “Automatically declare stage instances” in the ActionScript 3 settings panel to avoid errors where your class has defined properties for items on stage. Finally add all of the required classpaths that the linked classes will be using (that could include 3rd party libraries) to avoid any compile-time errors.
When you publish the SWF it’ll also publish a SWC in the same folder. You add that SWC to your AS3 project and the classes/symbols compiled into it become available for use in your code.
Pros:
This method keeps any timeline ActionScript, great for complex, nested or multi-state animations.
Cons:
You have to compile the FLA every time you change a class linked to a symbol, in reality that can mean toggling to Flash, exporting the SWC, toggling back to Flash Builder, refreshing the project to re-build the SWC indexes and then recompiling the project here also.
You have to make sure the classes your symbols are linked to are not in the main project source directory (or any directory the project is set to reference as source code). If you don’t do this you will likely not see your graphics/animations appear because the Flex linker will find the class definition first, not the definition that is inside the SWC due to the compilation order.
You have to add all required classpaths to the FLA, possibly every classpath your project is using.
Flash Builder will not report errors in the code used and you lose the ability to Ctrl/Cmd+Click to go to source.
You don’t have access to items on stage immediately, the workaround is pretty painful (link).
Summary:
Whilst this is really the only sensible method for keeping timeline code, the cons make it a really un-intuitive and frustrating process. If anyone can suggest a way to improve this I’ll owe you quite a few beers.
2. [Embed] tag above a class declaration
Example:
Code:
Pros:
You don’t have to re-compile the FLA unless your graphics actually change.
You can spend more time in your coding environment and not toggle back and forth between it and Flash Pro.
You get real-time compilation errors in the Problems panel of Eclipse because the code is not coming from a SWC.
Cons:
It strips ActionScript from the timeline of your symbols. If your symbol is an animation, and you had a few stop frames in there, perhaps one per labelled segment of animation, you’ll lose these and the animation will just run through on loop. What you see coders do to circumvent this is use addFrameScript(5, stop); for every stop frame, or even using lots of frame labels to act as meta-tags for code replacement (link).
Any children of the symbol lose any typing, so if you’ve added a couple of MyButton’s or a MyCustomWidget to your symbol on it’s timeline, those become plain MovieClips. This is a huge problem which relegates this method to animations only.
3. [Embed] tag above a class property declaration
This method involves using the [Embed] tag above a class property, for example:
Code:
With this method you’re instance will either be a SpriteAsset (extends Sprite) or a MovieClipAsset (extends MovieClip), you cannot cast it to a custom class, so for a symbol that is meant to represent a contact form, with an instance of MyButtonClass or even just some TextFields in it, this will fail.
4. Embed metatag to embed a whole SWF
There’s also another attribute available to the Embed metatag, that’s mimeType. If you remove the symbol attribute and replace it with mimeType=”application/octet-stream” it will embed the entire SWF and preserve the class associations set up in the library, i.e. you won’t have to have the instances typed to Sprite(/Asset) or MovieClip(/Asset).
When you embed a symbol from a SWF in this way, you can then use Loader to get at the classes within:
Code:
Great way to provide a library symbol a class/some behaviour without having to constantly re-compile the FLA.
Cons:
I think you’ll agree that’s not a great option if you have a lot of symbols or symbols which have others nested within. There are libraries to help with this, but…
No strict typing.
5. Runtime loading a SWF
Perhaps the oldest option here, loading a SWF at runtime allows you to pull out symbols/classes using the applicationDomain.getDefinition() function as described in method 3. If you’re already familiar with the getDefinitionByName() utility this works pretty much the same, but you are targeting a specific SWF’s classes.
Pros:
Great for loading content that rarely changes, such as fonts.
Cons:
Magic strings. Making a string a constant does not make it any less hacky, if you change the string in your FLA, your constant is meaningless, and you’ll only find out about it at runtime if that piece of code executes.
You’ll have to export your SWF from an FLA or using one of the other techniques which means you’ll also have some of the problems associated with those.
Feedback
So what route do you take? Please also state the type of project: application, game, website; it’s quite possible that people building applications simply never encounter these issues due to the primarily scripted animation and simple non-hierarchical graphical assets.
You may also want to consider how easy it will be to start compiling in Flash Professional in order to take advantage of CS5’s export to iPhone, this can impact your decision on which method you use.
Overall I feel that whilst choice is great, each method seems to have pretty serious downsides, and I’m yet to find one that doesn’t make for a less than pleasant rinse-and-repeat workflow. It would be nice to be able use Flash Pro to speed up the process of preparing game assets, laying stuff out on stage, animating on the timeline… but there are too many down-sides associated with this, and too many idiosyncrasies to learn just to get things working, I hope in future the two tools can be brought closer together perhaps through the new file format.
As usual, all comments welcome, unless you’re the bargain-dishwasher spammer.
Further reading
http://www.bit-101.com/blog/?p=853
http://www.bit-101.com/blog/?p=864
http://gskinner.com/blog/archives/2007/03/using_flash_sym.html
http://www.airtightinteractive.com/news/?p=327
Also the Flex Livedocs, which certainly don’t explain all of these methods in nearly enough detail or context, which makes using the Flex SDK a darker art than it could be.