Web DevCenter    
 Published on Web DevCenter (http://www.oreillynet.com/javascript/)
 See this if you're having trouble printing code examples


ActionScript for Non-Coders

by Sham Bhangal, author of Flash Hacks

Author's note: In this article we'll look at how the Flash authoring environment allows an ActionScript coder to work and share ideas with designers who have no ActionScript experience, while at the same time allowing the designers to make full use of scripting. The article assumes Flash MX 2004.

Introduction

To use Flash effectively, you do not just use the features available in the authoring environment. To be frank, such features are fairly basic, and you won't get very far using only the directly available drawing tools and ActionScript. In many cases, you have to create your own authoring building blocks using the default Flash tools, and create your application or site with the building blocks. Nevertheless, the great thing about the Flash environment is the way it is so open-ended, once you see how it is meant to be used.

If there's an authoring building block or tool you want that you can't find, it is often easy to build it yourself, using either components or the JSAPI (JavaScript API). I'll illustrate how this works in practice, using work I have carried out over the last month (July 2004) as an example. During this time, I was working with Adam Phillips to create a web site for a future project.

Animating that Which Can't Be Animated

A while ago, Adam sent me an email. He wanted to animate some gnats.

He sent me the image (see Figure 1) to illustrate his problem.

He had a forest with a light source illuminating them from above, and to show this directional light, he wanted a small swarm of gnats at the bottom of the forest reflecting the light.

Figure 1. Adam's gnats. Click on the image to see the Flash movie (opens as a popup)
Figure 1. Adam's gnats. Click on the image to see the Flash movie (opens as a popup).

To do this with traditional tween-based animation is problematic. You need a layer full of tweens for each gnat, and to get a good-size swarm, you need an awful lot of tweens.

This reminded me of the time I went to Flash Forward (a large Flash developer conference), and a particular developer was speaking, telling us about a text effect he had spent the whole summer creating with tweened letters. He went on to learn ActionScript and realized that text effect was really a day's work (because in ActionScript, you can create a script that works for one letter, and then apply it to all your letters, thus quickly solving the problem).

(Incidentally, that's also why there are a few pages in the Flash Hacks book telling you all about creating a general text-effects engine in ActionScript.)

Summer is for the sun.

So anyway, I emailed Adam back and said, "Hey, Adam, that's a particle effect. You can do this quicker with a script. How often will you need to do this?" He told me it was one of the things that really slowed him down, because he needed to do particle effects all the time, and they take forever with tweens.

It is not just gnats either. A refection of the moon over water also takes a long time to do with tweens, but it can be done quickly with a few lines of code, because with a script, all the reflections can be controlled via the same code (see Figure 2).

Figure 2. Reflections created by a tweened and repeated particle effect.
Figure 2. Reflections created by a tweened and repeated particle effect. Click on
the image to see the Flash movie (opens as a popup).

Because Adam said he needed to create particle effects so often, and because he is an animator who doesn't use ActionScript, I decided to create a component for him. A component is a self-contained and configurable movie clip that you can just drag-drop onto the stage, configure, and you're done. Flash MX 2004 has a vast set of components that are based on a large, class-based framework, but you don't need to do anything so intense -- a few lines of code and half an hour of development time is also fine if that's all it takes.

Here's what I did to create the component (which you can have a look at by downloading it here).

  1. First I created a movie clip called "swarmEnvelope" that consists of nothing but a rectangle. This is the appearance the component will take when it is placed on the stage. The rectangular area defines the area the particle effect will appear in.
  2. Next, I selected the movie clip in the library pane and right-clicked on it (CMD click on the Mac) and selected Component Definition to bring up the Component Definition window (see Figure 3).

Here, you define the values that can be added by the developer to configure the component. I created three number values:

Figure 3. The Component Definition window
Figure 3. The Component Definition window.

Within the component are two layers, a layer called graphics (which holds the graphic for the rectangle), and a layer called actions. The latter layer is the important one, because it contains the following code, attached to frame 1:


function flyInit():Void {
  this.speedX = Math.random()*speed;
  this.speedY = Math.random()*speed;
  this.onEnterFrame = flyMove;
}
function flyMove():Void {
  this._x += this.speedX;
  this._y += this.speedY;
  if (Math.abs(this._x-sX)>sWidth) {
    this.speedX = -this.speedX;
    this._x = this._x+this.speedX;
  }
  if (Math.abs(this._y-sY)>sHeight) {
    this.speedY = -this.speedY;
    this._y = this._y+this.speedY;
  }
  if (Math.random()<jitter) {
    this.speedX = Math.random()*speed-speed/2;
    this.speedY = Math.random()*speed-speed/2;
  }
}
function flyDie():Void {
  for (var i = 0; inumFlies; i++) {
    var fly:MovieClip = _parent["fly"+i];
    fly.removeMovieClip();
  }
}
// make speed higher to make gnats faster
// make jitter higher to make the flies take quicker, shorter paths (and stay 
closer to their initial position)
var sWidth:Number = this._width/2;
var sHeight:Number = this._height/2;
var sX:Number = this._x;
var sY:Number = this._y;
for (var i = 0; inumFlies; i++) {
  var fly:MovieClip = _parent.attachMovie("fly", "fly"+i, 
_parent.getNextHighestDepth());
  fly._x = sX+(Math.random()*sWidth*2)-sWidth;
  fly._y = sY+(Math.random()*sHeight*2)-sHeight;
  fly.onEnterFrame = flyInit;
}
this._visible = false;
this.onUnload = flyDie;

This code does the following:

All an animator needs to do with the component is place it onto the stage and scale the rectangle. He then has to select the component and, using either the Properties panel or the Component Inspector, is able to configure the swarm by varying the values shown (as shown in Figure 4).

Figure 4. Setting up the swarm
Figure 4. Setting up the swarm.

Once configured, all the animator has to do is test the movie. The rectangle will disappear, and in its place will appear the particle effect. Click on Figure 5 to see the Flash animation.

Figure 5. The finished effect. Click the image to see a popup showing the final animation
Figure 5. The finished effect. Click the image to see a popup showing the final animation.

Of course, Adam was so pleased with never having to tween swarm animations again that he created a few animations using the component. Click on Figure 6 to see the Flash animation as a popup.

Figure 6. Another test animation showing the finished effect. Click on the image to see a popup containing the final animation
Figure 6. Another test animation, showing the finished effect. Click on the image to see a popup containing the final animation.

Although this effect is nothing new, the way I created some code encapsulated in a component for a non-programmer to include the code in their own work is one of the cool things about Flash. A team of animators/designers and one or two programmers can work together to create compelling content, without the designers having to learn coding, and without the coders having to learn the finer points of graphic design or character animation.


Related Reading

Flash Hacks
100 Industrial-Strength Tips & Tools
By Sham Bhangal

A Virtual Camera

One of the systems that Flash doesn't have that many other animation environments have is a virtual camera. Many professional animation systems allow you to set up a virtual camera that can itself be animated. This allows you to create the sort of camera work seen in traditional films, including pans, zooms, and fades.

Flash uses a more old-fashioned system based around a stage. Rather like a theater stage, the audience view is fixed, and it becomes harder to create the sort of close edits and camera effects we are used to seeing in Hollywood films.

Adam mentioned this one day in passing, to which I replied, "OK. If Flash doesn't have a camera, let's make our own."

Although a virtual camera sounds like a world away from the simple particle effect we just looked at, the way I did it is almost exactly the same. Again, there is no complex code, and the time to develop the camera was insignificant. It will, however, most likely save Adam literally days in some of his longer animations, because the alternative to a scripted camera is to simulate the camera pans, fades, and zooms using only tweens, and this can take a very long time to set up or change.

Adam sent me the animation in Figure 7 to illustrate the need for a virtual camera. The Flash stage is set up here to show a short scene in Adam's next production. The trouble is, he would like to create a number of camera movements and effects that are difficult with tweening. Although using embedded movie clips is one solution, the large number of separate animations needed in a typical animation make their use just as troublesome. We really need that Vcam to create a clean solution.

Figure 7. The waterfall. Click on the image to see the waterfall animation.
Figure 7. The waterfall. Click on the image to see the waterfall animation.

After some discussion (and a few failed trains of thought regarding what a Vcam should look like and do), we settled on the following implementation.

The Vcam will appear in the authoring environment as a rectangle that defines the Vcam viewfinder. You can download the source FLA for this animation here. Note that if you test the FLA, you will see the best results if you publish to the browser rather than view the result in the authoring environment (text movie will not cut out the content that appears outside the viewfinder, whereas the final effect when seen in a browser does). See Figure 8.

Figure 8. The virtual camera as seen in the Flash authoring environment
Figure 8. The virtual camera as seen in the Flash authoring environment.

All the animator has to do to use the camera is to tween the viewfinder around the stage. In the final animation, the code inside the camera component scales and pans the stage such that only the content within the viewfinder is seen. See Figure 9a.

Figure 9a. The virtual camera in use. Click on the image to see the flash animation in a popup
Figure 9a. The virtual camera in use. Click on the image to see the Flash animation in a popup.

The Vcam is nothing more than a simple component -- a rectangle with a short script attached to its first keyframe.

Here's the code that drives the camera:

function camControl():Void {
  parentColor.setTransform(camColor.getTransform());
  var scaleX:Number = sX/this._width;
  var scaleY:Number = sY/this._height;
  _parent._x = cX-(this._x*scaleX);
  _parent._y = cY-(this._y*scaleY);
  _parent._xscale = 100*scaleX;
  _parent._yscale = 100*scaleY;
}
function resetStage():Void {
  var resetTrans:Object = {ra:100, rb:0, ga:100, gb:0, ba:100, bb:0, aa:100, ab:0};
  parentColor.setTransform(resetTrans);
  _parent._xscale = 100;
  _parent._yscale = 100;
  _parent._x = 0;
  _parent._y = 0;
}
// make frame invisible
this._visible = false;
// Capture stage parameters
var oldMode:String = Stage.scaleMode;
Stage.scaleMode = "exactFit";
var cX:Number = Stage.width/2;
var cY:Number = Stage.height/2;
var sX:Number = Stage.width;
var sY:Number = Stage.height;
Stage.scaleMode = oldMode;
// create color instances for color 
// transforms (if any).
var camColor:Color = new Color(this);
var parentColor:Color = new Color(_parent);
// Make the stage move so that the 
// v-cam is centered on the
// viewport every frame
this.onEnterFrame = camControl;
// Make an explicit call to the camControl
// function to make sure it also runs on the
// first frame.
camControl();
// If the v-cam is ever removed (unloaded)
// the stage, return the stage to the default
// settings.
this.onUnload = resetStage;

The function camControl will run every frame. This function uses the position- and percent-scaling properties of the movie clip (_x, _y, and _xscale, _yscale) to continuously scale and move the stage so that the viewable content in the final movie is constrained to the stuff seen in the viewfinder (much as would occur in a real movie camera). See Figure 10.

As well as zooming and panning, we decided it would be cool to have some way of applying video transitions to the final content, allowing the camera to add fade effects as well as color tints (tinting can be important in adding ambience to an animation). Although using the color class in Flash can be daunting, the way the camera does it makes it very easy -- all the animator has to do is apply a color tween to the camera, and the following line (first line of camControl) will programmatically apply whatever color tweening it sees in the camera onto the stage (in much the same way that adding a color filter cap to a movie camera would tint the recorded movie in a real camera).

parentColor.setTransform(camColor.getTransform());

When the camera is no longer needed, the animator can delete it from the timeline. The code uses the event that occurs when a movie clip is removed in this way (onUnload) to cause the stage to be returned to the normal size. This is performed via the function resetStage.

It cannot be understated how useful we found the virtual camera in creating Flash animations that have the sort of pace and movement associated with mainstream cartoons and live-action movies. Although it may seem like a minor piece of code to a scripter, it is something that many animators have always found missing in Flash.

Of course, that's not a problem, because the Flash environment not only allows you to create your own content-creation building blocks, but in most cases, almost requires you to create them.

Finally, it is worth noting that, unlike a real camera, our virtual camera allows you to create distorted viewfinders. These result in stretched animations.

Figure 9b. A flattened viewfinder
Figure 10. The result (a vertically stretched movie)
Figure 9b, 10. The effects of using irregular shaped viewfinders: the image on the top shows a flattened viewfinder; the image on the bottomshows the result (a vertically stretched movie)

Although this may seem like a minor point to some (you can keep the viewfinder proportions the same throughout the animation if you hold down CONTROL every time you scale the camera with the scale tool), and a bug to others (it would be easy to add some code to the camera to make sure that the view was never distorted in this way), we left it in because it led Adam to a rather surprising hack: distorting an image as you zoom and pan can give a very cool, faux 3D effect.

Click here, here, and here to see this effect in action.

This works because the distortion makes the scene appear as if it is mapped onto a curved 3D surface rather than onto a flat plane.

So, in setting out to create a 2D virtual camera, we seem to have also stumbled onto a hacky 3D camera as well.

Bonus!

Also, I am working on integrating the camera as a custom tool in the Flash toolbar (via JSAPI), given that it is proving to be such a useful animation tool. It just goes to show how far Flash can be altered through scripting to make the process of creating content easier for both scripters and non-scripters.

Figure 11. A prototype camera tool (currently in production)
Figure 11. A prototype camera tool (currently in production).

Conclusion

Although many people wonder how the Flash authoring tool is used to create some of the Flash content out there, one of the big secrets is the way the authoring tool can be used to create building blocks to aid development via components, as well as optimize the authoring environment in other ways.

Despite the fact that many non-scripters find ActionScript off-putting, there is nothing wrong with that, and it shouldn't prevent them from gaining the advantages of scripting. ActionScript can easily be written and encapsulated within the workflow such that a designer or animator doesn't have to know about the code at all.

The creation of tools to change your workflow is not only useful in accelerating content creation, but can often throw up totally new techniques, as illustrated by our stumbling on a 3D-camera effect whilst developing a 2D camera. Working with Flash is like that!

Sham Bhangal is an author of and contributor to numerous books on Flash and ActionScript, including Foundation ActionScript for Flash MX, Flash MX Designer's ActionScript Reference, and Macromedia Flash MX Upgrade Essentials.


Return to the Web Development DevCenter.


In June 2004, O'Reilly Media, Inc., released Flash Hacks .

Copyright © 2009 O'Reilly Media, Inc.