From Design to Reality

This article will cover techniques in dealing with application state and complex animations. Additionally, I've included a few quick primers on how to implement some of the designs a Flash developer can be expected to put into Flash as well as a sample application file. This article will cover techniques in dealing with application state and complex animations. Additionally, I've included a few quick primers on how to implement some of the designs a Flash developer can be expected to put into Flash as well as a sample application file.

There are many articles dealing with application state, from Visual Basic to PHP. My goal is not to rehash those topics, but to show you some tips and tricks I've learned in merging state and animation in Flash, since one of the main features that draws people to utilizing the Flash Player in a browser is its ability to keep application state.

The term "application state" is very broad, especially when applied to Flash development. Through the use of a timeline, you can lay out your application's states. A programmatic example is keeping the user's name in a variable that doesn't go away when the user navigates from page to page, as would happen on a Web page since the Internet is stateless. A less attractive example is playing "variable toss," where the variable is thrown on the end of the URL variable, with developers praying they never break the chain... or making the assumption that cookies are working on the end user's machine and attempting to use session variables, which is typically done in a PHP or ASP/.NET environment.

This article addresses the ability for components to have state utilizing complex animations. The challenge is changing state and having the interface follow suit, as well as transitioning between states. Because Flash allows timelines within timelines, you can easily build complex animations and nest them in your application state timeline without affecting it adversely in timing. More simply, a designer gives you a complex animation that you're supposed to make use of in your application and/or one of your components. I'll first cover ways you can go about implementing the design, and describe the pros and cons of each technique. Next, I'll describe methodologies in constructing your application as a whole. Finally, I'll describe the code used to keep track of state and manipulate the animations within your component.

If you're already familiar with implementing designs in Flash, and you have your own Flash application construction methodology, then you can skip to Part 3. A discussion on what can be done in the management and meetings up front to get to this phase can be seen at my Web site (www.jessewarden.com/archives/000309.html).

What's the best way to take a designer's comp, a compositor's video, an audiophile's mix, or an illustrator's layout and merge it with your code?

Image Editing Quick Primer
First, it helps to know your options. In Flash 5 and up, you can import PNGs, a bitmap format that is lossless (no quality loss in saving to this format) and supports up to 32 bit (8 bit alpha channel). A Photoshop comp can be exported straight from Photoshop to PNG, or, if the effect layers are flattened, brought into Fireworks and converted there. For complex- shaped interfaces and interface elements, this is the most common way to implement them inside Flash so you don't get the white or black background filling in the gaps. Since bitmaps are drawn to the screen in squares, designers use an alpha channel (unknowingly) to mask certain areas. Wherever possible, use a JPEG compressed outside of Flash. Square bitmaps are faster to render than their irregular-shaped bitmap counterparts (they don't negatively affect animation speed as compared to irregular bitmaps). Additionally, depending on the depth of your target monitor, sometimes the bitmap alpha channels show up. Yes, an invisible part of the image can be seen, I know. On 24 bit/16 bit monitors, this can sometimes happen with PNGs. The way to fix it is to put the PNG into a graphic and use the graphic instead of the PNG. Then, duplicate the image on a new layer and guide one of the layers (so you have a copy after you modify the copy; you never know when you'll need to go back to the original, and guided assets do not affect the final SWF file size [exclusion of sounds]). Select the image that is not on the guided layer, and then choose Modify –> Break Apart. Then select the Lasso tool. You'll notice three new tools on the bottom of the tool palette. Choose the Magic Wand Properties, change Threshold to 0, Smoothing to Pixels. This will usually ensure that you'll be able to select all of the alpha channel. Select the invisible alpha channel areas and delete them. Now you don't have to worry about the bitmap falling apart because it's contained in the graphic, and you can animate the graphic. However, the alpha is gone, but you still have your irregular shape intact. The one gotcha is this "autosmoothes" your image. This option (Flash's custom smoothing of images) can usually be turned off by right-clicking the asset in the Flash Library, selecting properties, and unchecking the checkbox. Now you're stuck with it.

Quick Video Primer
You can import the video directly into Flash MX and Flash MX 2004 and Pro. However, it is highly recommended that you do two things to ensure that your video will look professional:

Quick Audio Primer
As with images, it's best if you compress your audio outside of Flash. However, this really is best only if done with MP3 compression. For shorter sounds, it's okay to use Flash. Flash has ADPCM for short sounds, its own Speech codec for voice-overs (MX+), and MP3 internally, or you can import your own MP3, which won't be recompressed, or just use it RAW. Believe it or not, you're better off mixing down a bunch of sounds rather than compressing each one individually. Sometimes you can gain very slight compression increases if you separate the sounds out, as some sounds compress better than others, but the loss in processing power from uncompressing and playing all of those sounds together, as well as using most if not all of the eight sound channels Flash provides, is not worth the marginal file size savings, not to mention a bigger timeline.

Vector Art Primer
Although you can import some Illustrator files, my suggestion is to save yourself some heartache by transferring it to a Freehand file or making a bitmap equivalent in Photoshop. If this is not an option, write down your color values – sometimes things do not match up exactly. The same goes for PDF and EPS.

Method 1: The RAD Prototype
The quickest way to implement an interface is to simply import it using the methods previously mentioned and lay it out on the stage. It helps to sometimes import a screen-capped version and put it on a guide layer to help in your positioning. Then, you place your code on the objects. This will be very familiar to VB form developers.

Using the new Flash Pro features – the screens, the behaviors panel – and using databinding, you can knock out most interfaces that would take weeks, in days; day's in hours. The process is the same: lay out your interface on a series of forms that are reminiscent of PowerPoint (supporting nested forms), and then click on one of the form elements, click the behaviors panel, and apply your code.

Pros
This method is very fast. So fast, in fact, that this is where the multimedia author achieved fame in the Director days, as the process was very similar. The benefit is the media support in Flash; in addition, the flexibility and cross-product editing are superior in speed to other programming environments, save Director (which supports even more media types than Flash does). If something needs to be done in a hurry, this is the way to go. Behaviors created by programmers for the Behaviors panel can still allow very complex interactions and data handling to take place.

Cons
OOP? What's that? Although Flash's new data binding and components help you connect to external data sources of all types to keep your application dynamic, the structure of the application is pretty much stuck that way. From the placement of objects to the code placed on the objects, all are there to stay. If you wish to modify code, you must go to the object as well as edit an object's properties, properties, and it isn't always apparent what has code on it and what doesn't. For wizardtype applications, slide shows, or prototypes, this doesn't usually pose a problem, but for application design, it's not very flexible nor centralized from a coding standpoint.

Method 2: The Module Approach
Another way that holds much sway in the Web-developed Flash sites arena, as well as CD-ROM and application disciplines, is the use of loaded SWF files, otherwise known as loading movies. Each SWF forms a component, section, or module of the entire project. Flash movies have the ability to load each other either into themselves or one on top of the other, forming levels. As with colored acetate (transparent paper that allows you to write text and images upon it, which you then place on an overhead projector that shows the images on the screen or wall behind you), users have no idea as they are just seeing a bunch of elements on the screen like they usually would. However, this is a very powerful option that has a great many benefits (and pitfalls). I usually recommend this for CD-ROM-type projects, large Web sites, older Flash projects that use Flash video (whether a bitmapped generated sequence or FLV file imported into a blank FLA file, exported alone into a SWF), or projects that have a lot of media such as sounds, video, and large designs. Sites such as 2advanced (www.2advanced.com) pioneered this methodology into the limelight. It has a certain affinity for design types because they are used to compositing concepts, more so than programmers.


Pros
The first thing you'll notice is that your Flash files export a lot faster in a bunch of smaller files than in one big FLA file. This is especially valuable when you're trying to test some small coding functionality, but you were originally forced to wait for Flash to compress your sounds and video again, which could take many minutes. Another nice thing is that your application uses only the RAM it needs when the content is actually loaded. Although there are still other minutiae loaded in, performance is not compromised.

You can unload the levels you're no longer using, further helping performance. Since Flash still "renders" objects off-screen, this is a great technique for keeping performance in tip-top shape.

From an interface perspective, this allows you to separate out different pieces of the interface to be present only when needed, as well as the functionality of that interface and specific states. You can have many different SWF files with the same menu, but different data, or different colors, or different menu shapes, and so on. However, loading in that SWF will only change the level or current SWF being displayed, so it keeps things pretty flexible. You can also divide functionality in your application into movies instead of deeply nested components. You can still use components, mind you, as well as Branden Hall's Outlet component (www.waxpraxis.org) to allow your SWFs to act as independent components. One level can hold your sound, one can hold the Web service code, three can hold your interface and all its pieces and states, and one can act as the manager for all of the levels.

Videos, kept in their own respective SWF files, are easily loaded in and out. This helps in previewing just the videos as well as updating their compression levels without recompiling the entire application; compressing video takes a lot of time.

Web site wise, users have to download only Web site content they actually view. This also helps in showing dynamic pages without refreshing the page (or as some call it, causing a "postback").

Cons
Although levels are very flexible, each SWF file streams. You have to keep this in mind when expecting data from other SWFs. Trying to access a variable in SWF that you just loaded into a movie clip or _level will fail miserably. Even worse, it may work once in a blue moon because the file was cached and you got lucky, and then you're left wondering if something is wrong with your code, further deviating you from the true problem.

Web site wise, you need to provide a preloader for each SWF you load, or the user will be left wondering why the application is slow the first time around. However, the biggest pitfall is mismanagement. You need to micro-manage the heck out of your _level structure as well as your file structure. Even adding just one folder to the file path mix can get confusing when levels start loading each other. Constantly updating your structure on paper helps as does keeping track of who accesses who, when, etc. However, the real problem comes at crunch time. When you want to drastically change the application or site flow, especially when animations already time the loading of certain levels, it gets really difficult not only to modify, but also to keep track of those last-minute changes.

Although it's improved a little in 2004 (e.g., showing how a level can stream in when loaded) you can debug only one level at a time using Flash's debugger. The Flash Player is single threaded, but it's sometimes confusing to keep track of which movie does what and which movie you're currently debugging, causing you to play back the sequence of events in your mind. Overall, debugging is sometimes made more difficult.

Another con is not using shared libraries and having the same global asset duplicated in multiple movies like the FScrollBar. Although a background graphic can be in its own movie and remain in the back, a scrollbar is not so flexible. There may be multiple movies that need that, and this generally forces you to use a shared library and keep hard track of what uses that asset. Otherwise, you have 10K duplicated unnecessarily in all the SWFs that use the same scrollbar. Shared Fonts, however, have to be in _level0 to work this way. Another odd thing to note is that, contrary to the performance performance increase, _level0 has the maximum frame rate. If you're seriously trying to optimize your animations, nothing will be as fast as _level0.

Loading additional movies causes additional overhead, sometimes slowing your animations down. However, if they couldn't run as well, even without using levels (as the effect is marginal), then you better rethink your animation and not your assembly methodology. Finally, not being able to preview your animations as a whole unless you compile multiple files can sometimes slow things down in the long run. Having to go through points C, D, and E just to reach point B gets frustrating after awhile. Even though the user needs to, you sure as heck don't during development.

For more pros and cons, please see www.jessewarden.com/archives/000189.html as well as the chattyfig archives; many people have offered their opinions on the methodology.

Method 3: Application SWF
The simplest way to implement an interface in your application is to have all of your components/movie clips and the interface parts in the same FLA file. You implement/skin them in, and just separate the two in your library.

Pros
Everything is consolidated; you only need to load the SWF up initially; and after that everything is already there for you (excluding external data calls). Using a combination of attachMovie and removeMovieclip/unloadMovie, you can easily make it dynamic enough because everything you need is right there. Finding a component or design asset is easy, and updating that asset is a pretty quick process. Compile one SWF, and you're done.

Depending on how you design it, you can even use Method 2 to load it in as a self-contained application. Users don't have to load any additional data, they just suffer once, and all of your assets can be loaded prior to frame 1. Not having to worry about preloaders or preloading assets in is a big help.

Cons
Try this technique on the Web and you'll get burned. First, the export before first frame option that most components come with in MX and 2004 forces that data to be downloaded first, before anything on the first frame is shown. This causes a lot of newbie Flash programmers to wonder why their users are seeing a blank white screen for seconds on end, and their preloaders don't work. Second, depending on the scope of your project, compiling as well as initialization can take a long time. First, compiling all of that code as well as compressing images, audio, and video all at one time, every time, can drag out your total compile time. If you're just making a quick code edit and wish to test it, or even a compression modification on one asset, all others must be recompressed into a new SWF – not good. Additionally, using this FLA in a source-safe type of environment (CVS) makes it really difficult because doing one minor change doesn't necessarily mean you have to check it in again, does it? For those who don't wish to have binary files in a source control system more than is necessary, this way certainly can rack up the file size, quick.

I recommend this method only for intranet/kiosk/local hard drive delivery projects, and then only for projects that don't use a lot of big media (video, sound, high-res images).

Method 4: Shared Libraries
These poor guys have gotten a lot of flak from both the designer and programmer camps – designer because they are confusing to implement and programmer because they didn't always work under every condition (like multitier). Later versions of the Flash 6 Player have remedied this, and I haven't found any problems utilizing these in Flash 7. The concept of shared libraries is that you have an asset (symbol, i.e., graphic, button, movie clip, font, etc.) in one SWF file. You export that to be available at runtime using the linkageID like you normally would, but you also check the export for runtime sharing and identify what the SWF file name will be (usually the same name as the file it's currently in, as Flash by default exports out cow.fla to be cow.swf ). You can then either drag this symbol to another FLA file to be shared, or create a new symbol in the other FLA file, and then import it in. This allows multiple SWFs to use the same symbol, but the user only has to download it once. Therefore, if your scrollbar is 10K and you use it with three other SWFs, they do not incur the 10K file size. If you update your scrollbar component, those who use the symbol are updated as well without your having to recompile the other SWFs. In later versions of the Flash 6 Player, you can also do multitier Shared Libraries (shared symbols within shared symbols).

Pros
The ability to create once and have multiple SWF files use the same symbol helps in your updates, as well as saving in file size. Instead of three SWFs using a 10K scrollbar, you now subtract that file size from them, and only incur the 10K download once to the user. Like the level approach, your compiling speed is drastically sped up in that you don't compile shared symbols symbols to a SWF… because it's already done. At author time, you still have a local copy in your FLA, though, so your FLA may still be just as big; this allows you to break the connection if the symbol needs to be unique to that SWF for some reason. Updating one SWF of components to update the look and feel or functionality of your entire application is a cool concept… and powerful. You can also use the single SWF approach in your development, but just include the asset SWFs, which will be downloaded automatically.

Cons
Shared libraries are very difficult to get comfortable with. Once you do, you get into three steps: compile the source FLAs for a change, add your components to frame 2 (or some frame not 1 in MX and before they are used code wise), and uncheck "Export Before First Frame". The multiple FLAs are another source of management…and potential debug errors since you may have forgotten to compile the source SWF, broken your linkage by accidentally editing the Shared Symbol, or had to switch to another file to edit a design change. You also have to initialize the components somehow before you use them via attachMovie or with other components. Since they're not exported before the first frame, they will not be in the final SWF file, even with a linkage ID name, unless they are used somewhere in your movie. Therefore, manually placing them on frame 2 is good. This allows your preloader to work in that all of the data is not downloaded in frame 1. You can then utilize them in frame 3 and beyond. However, for older components, or the ones that come with Flash, they use many subcomponents (subclasses), and unchecking all of these can be time-consuming. This concept of application design also spits in the face of the single frame Flash movie that programmers aspired to in 4, 5, and MX. (If you said "3 too!", you're a freak.) Although you can still emulate that "one-time download" effect, the user is still downloading multiple SWFs instead of one, and these do cache, leading to problems in testing or updates. Ever try to explain to your clients how to clear their cache, let alone what a cache is? Russian Roulette is more fun.

Application State Applied in Flash
Before we discuss utilizing one of the methodologies, let's talk about state. Application state can mean a few different things. It can refer to a design being "ready" for user input, or to a bunch of buttons grayed out because they application is "disabled," waiting for the user to choose an option on a modal dialogue, for simply "finished" or "game over man!". The nice thing about Flash's timeline and use of frames is laying this out in a timeline allows you to easily see ahead of time, create, and modify these "states." Nesting your use of graphics and movie clips allows you to have many levels of sophisticated state. Whether you actually transition between those states abruptly or gracefully really depends on skill, your time and money requirements for the project, and your style. At any rate, the simple button example in Images I and II shows how Flash handles button states when you make a button symbol.

Note: At the end of this article is information on how to get the complex mp3 radio application made using the methodologies discussed below with a complexly designed interface. And that's just for buttons. Image III is a simple timeline of a more complicated button. This is how components are sometimes set up. You'll have your component code on the top frame (which can sometimes be just an include file to your class, while in Pro, it's an external ActionScript class auto-linked to the symbol). There's also the frame labels layer that indicates the "states" of your component, which Flash can show by programmatically "playing" or "going to" these frame labels, therefore updating what is shown on those respective frames. Because this is author time, you can view and tweak your states beforehand. This helps a lot if you're required to implement a very complex animation for an "over state" and want to see how it looks beforehand (which helps show the designer how you're actually using her or his design). Scrubbing the play head back and forth (clicking on the red square, holding it, and moving it left and right along the timeline) will allow you to see your states.

Event-Based Programming vs Timeline-Based Programming
It goes without saying that the goal from the early days of Flash was to get your application into one frame. Since Flash 5, unless you were seriously pressed for time, putting anything but a "stop();" on the timeline was considered evil and hard coding. You wouldn't be flamed as people knew it would come back to bite you. Harsh justice, I know.

Viewing Image III, you would think that if one section needed to go to the next, you could just put a "gotoAnd Play(‘section')" on the frame in question, and at that point the animation would go there. Sure, that works wonders. But does your code know? Having timelines control code died in Flash 5, so picking the habit back up doesn't fly now…well, not in the long run, anyway. Having your code control the timeline from one centralized location is best since it's no longer tied to it. Initclip and his brother, endinitclip, prevent your code from running more than once, and in Pro, your code is exported on a certain frame on the main timeline and run, and you're done. Therefore, stops are just about the only thing acceptable because the timeline shouldn't control itself, but rather the code.

Informing your code of when a timeline has reached a certain point presents a problem if you can't put code on that spot, then the old adage "How do it know?" (Kenneth Payne, VB Programmer and Jack of All Trades, JRW's first mentor). Some designers and programmers new to Flash will use frames as a sequence of events. Frame 1 starts it, frame 10 does some stuff, and when ready, play frame 20, etc. This, however, has a few issues in dealing with preloading, code portability, reuse, and code centralization. What if the designer adjusts the length of the animation? What if the design itself changes and you must remove layers and animations entirely? Having code moving around the timeline, unless it's a stop, isn't safe.

"Great, Jesse, but how can we tell when we've reached that point?"

Here's my method. First, I use Method 4 in implementing the design. I decide which elements of the design can be broken into subsequent components, and then build them. Each component plays whatever animation or functionality is needed. There are common problems you run into when doing this, and I'll go over those after I describe my method.

The Process Clip Revisited
I first have constants – variables with capital names for which I make an agreement to never change their value. They're named after the frame label (plus a "_DONE"), and their value is equal when that frame label's animation is done. That way, if the timeline gets moved around, I just change the constants variables' values.

Second, I determine which state happens when. Sometimes, you get lucky and only have to code a forced state change, like a Flash button. It goes wherever you are. Sometimes, though, in assembly-type interfaces, the designer has provided a transition from point B to point C, from point C to A, etc. All the permutations I'm assuming are done for me (although I end up doing them because I have little contact with my designers on how the project is put together sometimes, or the way they created it behooves me to re-create it myself. Production Artist, anyone?). With all of these scenarios set up, I code a function that gives me a frame label to go to based on where I am at currently, passing in a frame label that says where I'd like to go. So, if I want to shut down, and my app is currently open, it'll need to play the "close menu" animation. It's generally one big arse nested switch statement (or if/else if you are so inclined). You pass in the frame label your currently at, and it determines where to go (see Code 1).

This allows you to get to any point from any point. This requires you and the designer to hash out all possible scenarios of each component/module, and then for the designer to create the animations for those transitions/scenarios. The programmer may have to modify some of the interface elements; the ones that need code associated with them by giving a movie clip an instance name on a certain frame.

Finally, we get to the engine to instantiate the change in state, as well as knowing knowing when state has been truly reached. This can be coded in two ways: lazy evaluation and strict evaluation. Since I'm a programmer, I'll show the lazy way. Strict is merely stating that you cannot change state while transitioning to another state (animating the component/movie clip/showing the animation), while lazy just plays what it needs to, knowing the stops will take care of stopping the animation at its proper time. Designers and sales people obviously love strict bcause it appears smart, and strict almost always involves transitions. What they don't realize is if you're trying to change a combo box to "open" so you can populate data that just came back from a Remoting call, but you're using strict and your code responds with a "no, sorry, not yet," then the combo box doesn't get its data. You're not allowed to code the combo box to get the data when it's ready; that's cheating. The way around it is using the constants in step one: "He's there, send the data to those who need it."You can either hard code these data broadcasts in your getFrameLabel function, or make a generic function to call whenever state is finished (a button is finally on the stage, ready to have it's label set via a Remoting call's record set result and its click handler pointed to wherever). Either way, you use an onEnterFrame function on a movie clip. The enterFrame event fires every frame iteration, ensuring that every time the play head moves, you get an event. Even though most programmers like intervals, the timing is not so exact that you'll get it fired on every frame, while onEnterFrame will. Code 2 shows the functions that go in your component.

Now, before you go asking how to animate components, you simply:

Then, your set data can be something like:

this.movingCheckBox_mc.my_ch.set
Value(true);

Now, notice the inefficiency here: either you code one function to populate all of your components on each state change with data, even if they don't exist, or hard code the data setting to the frame label. I recommend the latter; even though it's more work and you're duplicating function calls, the data that needs to be set will get set when you need it to. This is a bigger deal if the call is asynchronous, like XML or Remoting.

To pull it all together, each component uses the above process and is put in its own FLA file, with its component name as the FLA (in Pro, the component class as its class name.as). You then link the symbol for runtime sharing.

Pull them all together (drag all their symbols into the main movie's library), put your preloader on frame 1, your shared symbols on frame 2, and your app on frame 3.

Conclusion
Ultimately, the process of implementing complex interfaces and animations in Flash goes smoothly if the details on how it works (transitions from state to state, or not at all) are ironed out, up front, with face-time collaboration. Having the designer and Flash programmer work out how it can be assembled, confirming all states for each component, and having the designer create and animate those states will lead to a smooth process. It's by no means easy, but the ability to sell this application as compared to other, non-Rich Internet Applications, as well as its positive impact on the user, is profound. Besides, true Flash programmers revel in this because they know what they are creating is high-end and cool – the designer can see her or his creation work, and the user ends up reaping the benefits of a labor of love.

For an example using the code here, please see this article's accompanying Flash file, Neos Radio, at www.syscon.com/mx/sourcec.cfm.

Also, for additional discussion on application state applied to Flash, please see www.darronschall.com/weblog/ archives/000014.cfm as well as www.stalker.com/CommuniGatePro/Web App.html under "Stateless and Sessionbased Processing".

Design provided by David Allbritton (www.daveallbritton.com), hacked apart by me.

© 2008 SYS-CON Media