Flash CS4 Professional lets you associate a document class with your FLA file. The document class is an optional class definition that controls the main timeline, and is constructed when the main timeline initializes. If you choose not to provide your own document class, then Flash generates one for you in documents configured for ActionScript 3.0. The choice is yours, which means you can migrate to this new feature at your own pace. As a note of encouragement, you won’t find anything unusual in FLA files with automatically generated document classes. The main timeline operates and feels the same as it used to. You can still put frame scripts where you like; it’s just that the main timeline has taken on a more formalized structure behind the scenes.
In FLA files with a custom document class, the main timeline can be
programmed to offer additional functionality in a way that feels built-in.
You could, for example, create a document class with a pauseFrame()
method, something that pauses the
timeline for a given number of seconds, then lets it continue. (This
suggestion is demonstrated later in this chapter.) Thanks to the document
class, using the new pauseFrame()
method
becomes as hassle-free as using stop()
or
gotoAndPlay()
: just type it into whatever
frame script meets your needs. This addition to the Flash workflow is useful
in team environments where designer and developer disciplines may not
overlap, because it allows for complete separation of assets from code. It
hasn’t always been so easy.
Shortly after the introduction of ActionScript 2.0 in Flash MX 2004
(version 7 of the authoring tool), developers began to experiment with bona
fide class files. This was the introduction of external text files capable of
defining new data types—flexible, portable, custom objects that could be
used in the same way as familiar native objects, such as Array
, Date
,
and Math
. It wasn’t long before a new
breed of Flash developer emerged: adventurous coders whose every goal
involved the reduction of the main timeline to a single frame. From a
programming standpoint, the traditional jumble of nested timeline code had
been artfully curtailed into the minimalist beauty of a Zen garden. This was
a completely new way to program in Flash, and could justly be described as
revolutionary.
The best part was, designers who chose to could happily continue
writing frame scripts where needed. Meanwhile, developers could pursue their
own passions away from timelines and drawing tools. For developers coming
from other backgrounds, such as Java or C#, the new paradigm made Flash more
comfortable, because it came closer to matching their own workflow in which
an application of any complexity begins with a single entry point, a class
usually named Main
.
In spite of such improvements, these ActionScript trailblazers had to halt one step shy of their ultimate ambition. Until Flash CS3, you couldn’t associate the main timeline directly with an entry point class file. That first and only keyframe had to have, at minimum, a single line of code to kick start the application. Something like this:
var application:Main = new Main();
Or even simpler:
new Main();
This single line of code may not seem like much of a hindrance, but keep in mind, Flash is a unique authoring environment in that it appeals equally to both artists and coders. Some Flash users prefer not to touch ActionScript at all, even if it’s only one line. Now they don’t have to, because every last shred of code can be saved in a simple text file external to the FLA file.
You have two ways to attach a document class to a FLA file: the Property inspector and the Publish Settings dialog. Here’s a look at both.
Create a new ActionScript 3.0 FLA file, and then save it as SampleDocClass.fla.
Create a new ActionScript file, and then save it as MainMovie.as in the same folder as SampleDocClass.fla.
Type the following code in MainMovie.as:
package { import flash.display.Sprite; import flash.events.Event; public class MainMovie extends Sprite { var sp:Sprite; // constructor public function MainMovie() { init(); } private function init():void { sp = new Sprite(); sp.graphics.beginFill(0x0099FF, 1); sp.graphics.drawRect(−50,−50,100,100); sp.graphics.endFill(); sp.x = 100; sp.y = 100; addChild(sp); addEventListener(Event.ENTER_FRAME, rotateSquare); } private function rotateSquare(event:Event):void { sp.rotation += 5; } } }
Save your changes, and then return to SampleDocClass.fla. To prove there’s nothing up anyone’s sleeve, select Control→Test Movie, and note the blank SWF file. The document class has not yet been assigned. Close the SWF file.
In your work area, click the Stage or pasteboard. This action
updates the Property inspector to reflect the properties of the FLA
document itself. Open the Property inspector, and then type the name of
the document class, MainMovie
, into
the Document class field, as shown in Figure 6-1. Note that the
.as file extension is omitted: this
isn’t the name of the file, but rather of the class itself.
Select Control→Test Movie again. This time, you see a rotating blue square—without any ActionScript actually in the FLA file.
Close the SWF file, and then, in the Property inspector, click the Profile area’s Edit button to open the Publish Settings dialog box (you can also open this box by selecting File→Publish Settings). Select the Flash tab, and then click the Settings button next to the Script drop-down list. This action opens the Advanced ActionScript 3.0 Settings dialog, as shown in Figure 6-2.
Notice that the Document class field is already filled in, because you previously entered it in the Property inspector. If you change or remove it here, it’s also changed or removed in the Property inspector, and vice versa.
Click the green checkmark next to the Document class field. You see an alert box that verifies the location of MainMovie.as. Click the pencil icon, and Flash switches the active document from SampleDocClass.fla to MainMovie.as, opening it if necessary. The Property inspector also features a pencil icon that does the same thing.
In the previous example, the FLA and AS files are located in the same
folder. Generally, this arrangement makes the most sense for document
classes, though strictly speaking you can place a document class wherever
you like. For example, in a team environment, you may have a number of
commonly used code libraries arranged into packages.
Packages are a logical organization of classes, arranged in hierarchical
folders that are often stored in a centralized location. Hypothetically,
your company’s in-house classes might be referenced in packages such as
com.companyname.utilies
, com.companyname.graphics
, and the like.
If your document class resides in a package structure, you must provide the fully qualified namespace to that
document class, in either the Class field of the Property inspector or the
Advanced ActionScript 3.0 Settings dialog box. If MainMovie.as was located inside a folder named
companyname, located in turn inside a
folder named com, the full namespace
would be com.companyname.MainMovie
. In most cases, however,
the document class corresponds to the specific requirements of the FLA file,
and therefore resides in the same folder for easy access. The document class
may very well depend on any number of additional classes, including shared
code libraries in other packages. In order to make use of those classes, the
document class must reference them with import
directives as needed.
For more information on the import
directive, see the Major Syntax and Structure Changes in Chapter 3 and the Associating FLA Files with AS Files in Chapter 5.
A document class must extend either the Sprite
class or MovieClip
class, depending on the application’s
needs. If the document class controls the main timeline with MovieClip
methods such as gotoAndPlay()
or gotoAndStop()
, or if the main timeline has frame
scripts—in other words, if the main timeline needs to behave like a movie
clip—the document class must extend MovieClip
.
In the MainMovie.as example, the
only methods used, addChild()
and addEventListener()
, are supported by the
smaller Sprite
class, so extending
Sprite
is sufficient. Because MovieClip
extends Sprite
, movie clip objects benefit from all the
functionality available to sprite objects, but have the additional overhead
of a timeline. In order to save memory and possibly increase performance,
it’s best to have your document class extend as small a base class as
possible.
For an example that requires MovieClip
, consider the following document class,
CompanyTemplate
, which could prove useful
in a workflow for banner ad designers. One of the perennial questions on the
Adobe support forums involves temporarily pausing, and then resuming the
main timeline. While you can certainly add filler keyframes to extend the
timeline, this manual approach quickly becomes tedious when numerous pauses
are needed, especially in FLA files with high frame rates. To make matters
worse, revisions can potentially mean the painstaking removal of extra
frames, which can be difficult in timelines with dozens of layers. Wouldn’t
it be great if something like a pauseFrame()
method were built into the
language? A document class makes it so:
package { import flash.display.MovieClip; import flash.events.TimerEvent; import flash.utils.Timer; public class CompanyTemplate extends MovieClip { private var _timer:Timer; // constructor public function CompanyTemplate() { _timer = new Timer(1000, 1); _timer.addEventListener(TimerEvent.TIMER, ¬ resumeFrame); } // Pause frame public function pauseFrame(seconds:Number):void { stop(); _timer.delay = seconds * 1000; _timer.start(); } // Resume frame private function resumeFrame(evt:TimerEvent):void { play(); } } }
This class’s methods, pauseFrame()
and resumeFrame()
, employ the stop()
and play()
methods of the MovieClip
class, which means CompanyTemplate
must extend MovieClip
in order to go about its
business.
A Timer
instance is declared as the
private _timer
property, which is then
instantiated in the constructor function and associated with the resumeFrame()
method. The pauseFrame()
method is
conveniently called from any number of frame scripts in main timeline. It
halts the timeline via MovieClip.stop()
,
and then sets the Timer.delay
property of
_timer
to a value in seconds provided by
the frame script. Because the delay
property expects milliseconds, the incoming seconds
parameter is multiplied by 1,000. At this
point, _timer
is told to begin its work,
which is to eventually call resumeFrame()
—but all this complexity is neatly
tucked away for designers who simply want to pause the main timeline with a
simple line of code.
There’s a reason why the _timer
property is preceded by an underscore. By popular convention, many
developers set private properties apart by the using this punctuation.
This was a source of potential conflict in ActionScript 2.0, because many
built-in properties formerly featured underscores for unrelated reasons.
Their removal in ActionScript 3.0 eliminates this confusion.
To use this document class, save it as CompanyTemplate.as, associate it with a FLA file as described earlier, and then add a keyframe where desired (Figure 6-3).
Use the Actions panel and enter, for example, pauseFrame(5);
, which pauses the chosen frame for
5 seconds, and then resumes. Because the CompanyTemplate
class is associated with
the main timeline—in fact, is the main timeline at
runtime—the pauseFrame()
method executes
as naturally as stop()
, play()
, or any other MovieClip
method.
Company-wide technical policies of any stripe can be managed in this way for whole teams of designers/developers, who needn’t be bothered with the underlying mechanics of the custom functionality. As policies and requirements change, the document class can be updated without interrupting the workflow of the team members who use it. Because the document class imports other classes as needed, the complexity of its custom features isn’t tied to a single class file.