Uli's Web Site
[ Zathras.de - Uli's Web Site ]
Other Sites: Stories
Pix
Abi 2000
Stargate: Resurgence
Lost? Site Map!
 
 
     home | blog | moose | programming | articles >> blog

 Blog
 
 Archive
 
 Blog Topics
 

15 Most Recent [RSS]

 Less work through Xcode and shell scripts
2011-12-16 @600
 
 iTunesCantComplain released
2011-10-28 @954
 
 Dennis Ritchie deceased
2011-10-13 @359
 
 Thank you, Steve.
2011-10-06 @374
 
 Cocoa Text System everywhere...
2011-03-27 @788
 
 Blog migration
2011-01-29 @520
 
 All you need to know about the Mac keyboard
2010-08-09 @488
 
 Review: Sherlock
2010-07-31 @978
 
 Playing with Objective C on Debian
2010-05-08 @456
 
 Fruit vs. Obst
2010-05-08 @439
 
 Mixed-language ambiguity
2010-04-15 @994
 
 Uli's 12:07 AM Law
2010-04-12 @881
 
 Uli's 1:24 AM Law
2010-04-12 @874
 
 Uli's 6:28 AM Law
2010-04-12 @869
 
 Uli's 3:57 PM Law
2010-04-12 @867
 

More...

The Flashy Mill...

At work I'm getting into Flash. I've been meaning to do Flash for quite a while, but I'm not really desperate enough to shell out big bucks for an application with such a ... unique ... user interface. But thanks to my boss, I now know about SWFMill.

SWFMill is a nice little open-source tool for generating .SWF files. It's intended mainly for assembling image files into film clips, though. If you wanted to add ActionScript logic to a movie, you'd use the Motion Twin Action Script Compiler (MTASC) in addition to that.

Anyway, since the docs aren't quite perfect, I thought I'd walk you through a simple SWFMill-based Flash movie. You'll need four image files: foo.png (which we'll use as our background), and person1.png, person2.png and person3.png (an animation). You're free to use other names, but these are the ones I'll be using. SWFMill can take PNG-24 and PNG-32 files as well as JPEGs. I'm using PNG-24s created using Photoshop Elements' Save for Web... feature. They'll have nice alpha transparency.

MTASC is installed into /opt/mtasc/, so I decided to copy swfmill into /opt/swfmill/.

Have that setup? Okay. Now, create a new folder for your project, and create a library folder in that in which you put the images. You'll also want to create an index.html file for testing your flash movie. Mine contains:
<html><body>
    <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
         codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"
         width="320" height="240" id="video"
         align="middle">
         <param name="allowScriptAccess" value="sameDomain">
         <param name="movie" value="test.swf">
         <param name="quality" value="high">
         <embed src="test.swf" quality="high"
                  width="320" height="240"
                  name="video" align="middle"
                  allowScriptAccess="sameDomain"
                  type="application/x-shockwave-flash"
                  pluginspage="http://www.macromedia.com/go/getflashplayer">
         </embed>
     </object>
</body></html>
I basically just ripped this out of another web site and inserted test.swf, but it's enough for testing. It's simply an HTML page that you can open in Safari to run the test.swf file next to it. The second part of our setup rig is a little script that lets us run SWFMill by double-clicking. If you insist, you can simply type that into Terminal each time, but I have better uses for my time ;-) I'm saving this to a file named build.command. This suffix makes Terminal.app claim this file and run it in a new window upon double-clicking it.
cd `dirname $0`
/opt/swfmill/swfmill simple resources.xml test.swf
What this does is make the folder containing the script current and then it calls swfmill on it to process the project file resources.xml and generate the file test.swf from it. The plot thickens...

All finished? Okay, now let's get to the complicated part, actually generating the Flash file. SWFMill uses an XML file containing SWFML tags to describe what to put in the file. A Flash file essentially consists of a bunch of resources. Images, frames, sounds etc. So, create a new file named resources.xml. The basic structure of an SWFML file is:
<?xml version="1.0" encoding="iso-8859-1" ?>
<movie width="320" height="240" framerate="12">
    <background color="#eeeeee"/>
    <frame />
</movie>
The parameters are pretty self-explanatory. Width and height should match those in your object tag. You can pick any background color you want, but pick one if you want to see that transparency works, because default is white. Now, double-click the build.command file and then the index.html file and you'll see a nice empty box in the color you chose. not very impressive, eh? Leave it open anway.

Okay, first, we need to import our images into the Flash file. To do that, add the following statements to the top before the <frame /> tag:
<clip id="foo" import="library/foo.png"/>
<clip id="person1" import="library/person1.png"/>
<clip id="person2" import="library/person2.png"/>
<clip id="person3" import="library/person3.png"/>
These import the images in the specified files (e.g. library/foo.png) into the flash file under the names specified as the "id" parameters (e.g. foo). So, the names foo, person1 etc. are the ones by which we'll refer to the images in the rest of the file.

These images will only be accessible by the SWFMill file. If you later plan to use MTASC to access any of the images directly, you'll have to wrap those in a <library> tag. Now we've only made our file bigger. So, let's add a new frame to our Flash movie and place the first image on it, by replacing the empty <frame /> tag with the following:
<frame>
    <place id="foo" name="foobarA" x="10" y="15" depth="1"/>
</frame>
As you see, this takes the image we gave the ID foo and places it at a horizontal offset of 10 pixels from the left edge of the movie and 15 from the top edge onto the screen. It also gives this particular copy of the movie clip foo the name foobarA (you can pick any name you want, just as you can give the images any ID you want). Finally, it places this image on the layer 1 (indicated by the depth parameter), where higher numbers mean that an image is closer to the front (i.e. an image with depth 5 will cover an image with depth 2). Note that, inside one frame (or clip, more on that later), only one object can be at the same index. If you have two with the same "depth" value, one of them won't be shown.

Now, you can run the build.command script once again and then reload index.html in Safari. Ooo. Our picture!

Now, you could simply add additional frames to the resources.xml file with the other images to have a nice, single animation. But what if you have animations with different numbers of frames or you want to be able to later add more frames? Easy. You can define a clip that contains several frames and other clips. To do that, add the following <clip>-tag and its sub-tags below the clip tags we already have for the various frames:
<clip id="person">
    <frame name="person1frame">
        <place id="person1" name="personPlaced1" depth="1"/>
    </frame>
    <frame name="person2frame">
        <place id="person2" name="personPlaced2" depth="1"/>
    </frame>
    <frame name="person3frame">
        <place id="person3" name="personPlaced3" depth="1"/>
    </frame>
</clip>
This simply defines a little movie inside our movie and makes it just another clip that can be used just like the single image-clips we already have. It's called person, and you can place it just like the other clip by adding a place tag to the frame in the main movie where we already have one:
<place id="person" name="personA" x="100" y="50" depth="5"/>
And yup, that's Layer 5, so it won't be covered by our background image. Build and reload index, and you should see a nice animation alpha-composited on top of the image. It's not much, but hey, it's my first Flash animation.

If you look at all those names and IDs, you'll probably realise that it may be a good idea to come up with a good naming convention to avoid namespace collisions.

Reader Comments: (RSS Feed)
Gabino writes:
Hi Uli I've read a handful of SWFMill tutorials, you just took it a little bit farther and that last example really helped me out. Thanks.
Comment on this article:
Name:
E-Mail: (not shown, hashed for Gravatar)
Web Site URL: (optional)
Comment: (plain text only)
Please Enter the following word:
Or E-Mail Uli privately.
 
Created: 2005-10-18 @955 Last change: 2014-09-18 @107 | Home | Admin | Edit
© Copyright 2003-2014 by M. Uli Kusterer, all rights reserved.