This document is outdated. Please refer to (and improve the) the OSFlash wiki page
Just because. Well, actually there are a number of reasons. If you're reading this you probably have your own. In case you're interested, my main reason is to improve my workflow. Everybody has a favorite text editor -- be it Eclipse with the ActionScript plug-in, SciTE|Flash or SEPY, it almost certainly beats the internal ActionScript editor that comes with the Flash IDE. Until recently, what people did was to edit their classes in their external editor and use Flash for the rest: compiling, filling the library with assets they needed, and so on.
Then came MTASC, an open source command line ActionScript compiler written by Nicolas Cannasse. Apart from being much, much faster than the compiler that is built into the Flash IDE, it comes with various goodies, like a -strict compile option and better integration with your editor of choice, among others. Using it instead seemed like an obvious choice. The workflow now was to create an SWF with the necessary assets included in the Flash IDE, and then compile your code into it with MTASC. However, using Flash solely to fill up the SWF's library seemed silly (also, the Flash IDE is not available for all platforms).
How to use MTASC is pretty well explained on its website, how to integrate it into your editor depends on which one you use. Carlos Rovira wrote a good tutorial in which he explains how to use it with Eclipse. I will focus on the preceding steps, that is, how to use swfmill to get to the point where you have an SWF you can then compile your code into.
Several programs can export SWFs. Other assets you might want to have in your SWF include fonts, images and components. To fill the gap in the Flash IDE free production chain between having those assets and having an SWF ready to have the code compiled into, Daniel Fischer, who only by coincidence happens to be a housemate of mine (take that as a disclaimer), wrote swfmill. It's published under the GPL and can convert back and forth between a binary SWF and an XML dialect called SWFML which closely resembles the SWF file format. To faciliate usage and allow for comfortably importing assets, a simpler dialect was introduced. As a short overview, you can currently do the following:
swfmill's SWFML simple should be considered preliminary. It will almost certainly change, possibly even in its most basic structure (or its name. you can post suggestions to the mailing list).
However, it might already be useful for some as it is, if you believe you're one of them this text is for you. Be aware that you might have to modify, possibly significantly, anything you build around it. No, we don't just say that.
If you find speeling or grammer mistakes, please let me know. If you have other suggestions how this document might be improved, please post them either to me or preferrably to the mailing list.
This is simple. The example below should be self explanatory:
<?xml version="1.0" encoding="iso-8859-1" ?> <movie width="320" height="240" framerate="12"> <background color="#ffffff"/> <frame/> </movie>
Ok, that was easy. However, it's not particularly useful just yet. We have an empty SWF, 320 by 240 pixels with a white background running at a target framerate of 12 fps. Let's pack some stuff into it next.
To add a jpeg image called "foo.jpg" from a directory called "library" (located under the one you call swfmill from) into your SWF, add the following lines into the <movie/> inside the basic SWF description above:
<frame> <library> <clip id="foo" import="library/foo.jpg"/> </library> </frame>
Fonts work slightly different. To import all numerical characters of vera.ttf as "vera", you would add the following after the library node:
<font id="vera" import="library/vera.ttf" glyphs="0123456789"/>
You don't have to do anything specific to make it a shared library. Just remember the URL where you put it, and keep a local copy. To import a shared library, add this line for each SWF you want to import as a library for runtime sharing:
<import file="library/library.swf" url="http://foo.com/library.swf"/>
As a reference, below XML fills the library with some assets, adds a font and imports a shared library. it then adds another item to the library in frame 5, which is named "myFrame" so you can gotoAndPlay( "myFrame" ) to it:
<?xml version="1.0" encoding="iso-8859-1" ?> <movie width="320" height="240" framerate="12"> <background color="#ffffff"/> <!-- first frame --> <frame> <!-- add some assets to the library --> <library> <clip id="picture" import="library/picture.jpg"/> <clip id="bitmap" import="library/bitmap.png"/> <clip id="clip" import="library/clip.swf"/> </library> <!-- import the numerical characters of vera.ttf --> <font id="vera" import="library/vera.ttf" glyphs="0123456789"/> <!-- import a shared library --> <import file="library/library.swf" url="http://foo.com/library.swf"/> </frame> <!-- some empty frames --> <frame/> <frame/> <frame/> <!-- frame "myFrame" --> <frame name="myFrame"> <library> <clip id="anotherClip" import="library/foobar.swf"/> </library> </frame> </movie>
Adding components to the library is a bit trickier, but not too difficult either. They come in SWCs, which basically are zipped archives containing a precompiled SWF and various other files. We're interested in those named *.asi, because MTASC will need them as header files for typing. Ideally, use a script to go through the following steps:
<library> <!-- import the SWF that was inside the SWC archive --> <clip id="fooComponent" import="components/fooComponent.swf"/> </library> <!-- call Main.main() as an entry point --> <call object="Main" method="main"/>
To place a clip onto the stage, add a <place/> tag inside the frame you want to place it in. Note that it has to be previously added to the SWF. If you wanted to place foobar.swf onto the stage, your "myFrame" frame would look like this:
<!-- frame "myFrame" --> <frame name="myFrame"> <library> <clip id="foobar" import="library/foobar.swf"/> </library> <!-- place "foobar" onto the stage --> <place id="foobar" name="myFoobar" x="10" y="10" depth="1"/> </frame>
You don't have to import the movieclip inside the <library/> tag.
Assets declared inside a library tag will be made available to ActionScript
with their id attribute as linkage name. If you don't want to attach them
dynamically, you can simply import them anywhere inside a <frame/> tag, and
still place them with the <place/> tag like above.
Instead of importing existing SWFs into yours, you can also create them with simple swfml. Like imported assets, they can be placed onto the stage and will have a linkage id if you create them inside a <library/> tag.
You can do pretty much everything inside created clips you can do inside the <movie/>, except for importing and adding assets to the library. That is, you can create other movieclips or textfields and place them into the clip's frames.
Creating a movieclip works just like importing, only that you don't use the "import" attribute for the <clip/> tag. Below is an excample of a movieclip with two frames, "on" and "off":
<!-- import images to be displayed in the frames --> <clip id="onState" import="images/on.png"/> <clip id="offState" import="images/off.png"/> <!-- create the movieclip --> <library> <clip id="onOff"> <frame name="on"> <place id="onState" depth="1"/> <stop/> </frame> <frame name="off"> <place id="offState" depth="1"/> </frame> </clip> </library>
To create a textfield, you have to give it the necessary attributes "width", "height", "size", "font" and of course "id". Here's an excample:
<textfield id="hellobox" width="200" height="50" size="10" font="vera" text="hello world!"/> <place id="hellobox" name="output" depth="10"/>