Goal

In this exercise you will learn how to incorporate procedural animation in your Director Movies.

 

Methods of 2-D Animation:

Adobe Director provides powerful and versatile tools for creating animation. Typically, there are two methods developers use to animate in Director: 1) Keyframe animation, and 2) Scripted animation. We will go over each animation method briefly.
 

2-D Keyframe Animation

Keyframe animation in Director is an extension of traditional cel-based animation where the animator draws "key" poses that define the action or movement within a scene. The keyframe method translates nicely to a visual paradigm in a computer interface, so it should come as no surprise that programs such as Director, Flash, and powerful 3-D animation applications like Maya, Softimage, and Blender make extensive use of keyframe animation tools. Keyframe animation in Director involves placing sprites in various channels in the Score and using Director's timeline animation tools to alter sprite position, size, rotation, and other visible qualities of each sprite to achieve the desired effect.

For many animation needs keyframing is effective and relatively easy to work with because each sprite can be modified visually. However, as useful as keyframe animation can be it is not without disadvantages. Keyframe animation is only as versatile as the tools the software provides to work with it, and the tools are sometimes not enough. For example, keyframe animation in software frequently makes use of linear interpolation, which finds intermediate positions from one or more specified screen coordinates. To gain more animation precision using keyframes requires more keyframes. At some point there may be so many keyframes that the animation process becomes counterproductive. Another disadvantage of keyframe animation is that it is not particularly well suited for games, where complex logical conditions often determine the visible actions of sprites. Here are some considerations to take into account when thinking about 2-D keyframe animation.

Consider creating keyframe animation when:

  • The animation task is relatively simple.
  • The animation is relatively short in duration.
  • There are few cyclic (looped) animation needs.
  • You don't need interactivity, such as that required by a game.
  • You have to create an animation in a hurry.



2-D Scripted Animation

When precise sprite choreography is required in your animation, Lingo is often the best solution. Scripted animation is commonly used for game development where animated sprites must react, in real time, to the user's actions, and perform their pixel gymnastics based on complex logical conditions.

Animating with Lingo has many advantages. Primarily, Lingo removes virtually all restrictions pertaining to the movement and actions of each sprite. If a developer can dream up a series of movements for a sprite, the chances are that it can be accomplished with a series of Lingo statements. Lingo animation also breaks away from the restrictions of timeline based animation where subtle sprite property changes can be difficult to realize. The only disadvantages for using Lingo to animate is that it requires some proficiency with the language, and it is sometimes a more time consuming process than Score and timeline animation. Other than that you are only limited by your imagination and how well you can spin the propeller on your head to make Lingo work for you.

Consider creating scripted animation when:

  • The animation task is relatively complex, or requires precise movement.
  • You have multiple cyclic animation sequences that need to play repeatedly.
  • You need the artwork to be interactive, and respond to user input.
  • The animation task would be too tedious to create by hand with keyframes. For example, a moving star field, snow, or rain.
  • You need a reusable graphic manipulation system that can be modified.
  • Your artwork needs to have random qualities such as speed of movement, or animated textures.

 

The Director Coordinate System

The cartesian coordinate system is one of the most fundamental and important concepts to understand when you begin to work with 2-D graphic software. The purpose of a coordinate system is to provide a form of notation to describe a spatial position, or point.

Screen Coordinates

The image above shows a representation of Director's coordinate system. A two-dimensional coordinate system like this always assumes the horizontal ( X ) value is shown before the vertical ( Y ) value, so the upper left part of the screen is (0, 0), indicating 0 pixels on the X-axis, and 0 pixels on the Y-axis. If the screen were 800 pixels across and 600 pixels high, the bottom right corner of the image would have (800, 600) as the coordinates. The middle of the screen would be (400, 300).

The green lines show the direction each respective axis increases in value. The X-axis increases in value toward the right, and the Y-axis increases in value from top to bottom.
 

Working the Numbers

One of the most important Lingo skills for procedural animation is a solid understanding of how to make the computer count from one number to another. The way this is generally accomplished is to use either a repeat loop, or a script structure that allows numbers to be incremented, decremented, or otherwise logically limited to stay within a specific range. These Lingo gymnastics are necessary for sprites to move around the screen in a controllable way.

Using a Repeat Loop

When you want the computer to repeatedly execute a given set of instructions the repeat command is often a good way to handle it. The repeat with structure looks like this:

-- count from 1 to 100 and display it in the Message Window
on mouseUp me
spacerrepeat with i = 1 to 100
spacerspacertrace(i)
spacerend repeat
end

The repeat with loop in the above example creates a variable named i that stores a number. The first number it stores is the first number to the right of the equals sign operator. Each time repeat iterates through a loop it automatically adds 1 to the value stored in the variable i. It keeps doing this until it reaches the limit you have set. In the above example the limit is 100. Any code appearing between the repeat and end repeat block of code is executed the number of times the loop runs. The above handler will count from 1 to 100 and print the result in the Message Window.

To have the computer count from 100 down to 1 using repeat with looks like this:

-- count from 100 down to 1 and display the result in the Message Window
on mouseUp me
spacerrepeat with i = 100 down to 1
spacerspacertrace(i)
spacerend repeat
end

The repeat with loop in the above example creates a variable named i that stores a number. The first number it stores is the first number to the right of the equals sign

The above handler is nearly identical to the one above it, except for the addition of the word 'down,' in front of the word 'to.' The down to command tells Lingo to count from a higher value number to a lower value number. In either handler, any number may be substituted so the computer can count from one number to any other. Sometimes this "counting" is just what you need to move something across the screen, or repeatedly execute code that animates a sprite.

Another form of repeat is the repeat while loop. In this structure the loop repeats until a specific statement is true. The statement the computer evaluates in the following example tells it to compare the value stored in the variable i with the number 101. As long as the variable i is less than 101 the loop repeats.

-- count from 1 to 100 and display the result in the Message Window
on mouseUp me
spacerrepeat while i < 101
spacerspacertrace(i)
spacerspaceri = i + 1
spacerend repeat
end

Alternatively, the statement could include a , which tells the computer to repeat until the variable iis less than or equal to 100.

-- count from 1 to 100 and display the result in the Message Window
on mouseUp me
spacerrepeat while i spacerspacertrace(i)
spacerspaceri = i + 1
spacerend repeat
end

The output of the above handler is identical to all the other examples, but the method used to get the computer to count from one number to another differs, depending on the form of the repeat loop that is used. No method is better than any other, and the repeat loop style you choose to use in a given situation is a matter of personal preference and scripting style.

The repeat command is extremely useful for many Lingo applications, but it is not always the best choice for sprite animation because while the computer is repeating the code within a repeat and end repeat block it can't easily update other changes and animation that may need to happen on the Stage with other sprites.

Using Frame Messages to Animate

To achieve the same "counting" effect as shown in the above examples while still maintaining the ability to animate multiple sprites at once requires a different method known as frame animation. Essentially, this technique involves the use of exitFrame messages to drive the changes to numbers that alter sprite properties such as position and size on the Stage. Any frame or sprite can be easily programmed to respond to exitFrame messages.

The following, when placed in a frame script, tells Lingo to count from 1 to 100 and displays the result in the Message Window.

property pCount -- the value of the counter
on exitFrame me
spacerpCount = pCount + 1
spacerif pCount < 101 then
spacerspacertrace(pCount)
spacerend if
spacer_movie.go(_movie.frame)
end

A property variable named pCount is declared to store the counted value. Each time the exitFrame message is sent, which is typically 30 or 60 times per second, 1 is added to the variable pCount. When pCount equals 101 the if statement no longer prints the value of pCount because the condition is FALSE. That is, when pCount = 101 it is no longer less than 101. If statements are a key part of getting frame animation to work because they provide a means by which the value of variables can be given limits.

It is important to understand that property variables are local to the sprite or frame they are a part of. That is, the above handler could be used on any frame of a movie and the variable pCount, though named the same, would be independent for each instance (frame) for which the script was attached. Sprites can respond to exitFrame messages as well, but they do not need the go the frame statement because sprites cannot control the playhead directly. The following modified version of the above script will work for any number of sprites you attach it to.

property pCount -- the value of the counter
on exitFrame me
spacerpCount = pCount + 1
spacerif pCount < 101 then
spacerspacertrace(pCount)
spacerend if
end

The script is identical, except that the go the frame statement has been removed, since it doesn't apply to sprites. Since pCount is a property variable, each sprite the script is attached to will have its own instance of pCount. This is a unique and extremely handy object-oriented quality of behaviors attached to sprites.

 

So far, the code examples in this exercise have only shown how to make the computer count. Using the same technique, it is a relatively easy task to move a sprite across the screen. Here's a simple example that moves a sprite across the screen from left to right indefinitely. It assumes the Stage is set to 640 x 480.

on exitFrame me
spacer-- move 5 pixels to the right for each iteration
spacersprite(me.spriteNum).loc = sprite(me.spriteNum).loc + point(5,0)
spacerif sprite(me.spriteNum).locH > 640 then
spacerspacersprite(me.spriteNum).locH = -20
spacerend if
end

If we leave off the if statement the sprite would quickly move off the screen, never to be seen again. It would continue to move to the right, 5 pixels at a time, but it has no limit, and goes on forever until stopped. By checking the sprite's locH position on the screen we can set a horizontal limit, and have the sprite disappear on the right side of the screen, then reappear from the left side of the screen over and over again.

Here's a more interesting example that uses frame animation to make a sprite do several things at once. The following handler should be attached to a sprite.

on exitFrame me
spacersprite(me.spriteNum).rotation = (sprite(me.spriteNum).rotation + 5) mod 360
spacersprite(me.spriteNum).width = sprite(me.spriteNum).width + 1
spacerif sprite(me.spriteNum).width > 200 then
spacerspacersprite(me.spriteNum).width = 50
spacerend if
spacersprite(me.spriteNum).loc = sprite(me.spriteNum).loc + point(5,0)
spacerif sprite(me.spriteNum).locH > 640 then
spacerspacersprite(me.spriteNum).locH = -20
spacerend if
end

Here's the handler as it would appear in the Script Window in Director.

Sprite Animation Code Example

This handler works with three properties primarily, the rotation of a sprite, the width of a sprite, and the location of a sprite. All of these properties are altered by comparing the sprite properties to the current value of the sprite's properties plus another value. Each line of the script is described below:

It is important to note that in this handler exitFrame is the message that drives the animation. That is, the number of times per second the exitFrame message is sent determines how quickly changes to the sprite take place on the Stage. Effectively, the Frames Per Second (FPS) of the Movie determine how fast or slow the sprite animation will occur. To adjust the speed of change either the FPS of the movie can be altered, or the number values that increment or decrement the sprite properties can be altered. The best overall quality of this behavior is that it can be dropped onto as many sprites as you like, and all of the sprites that use this script will animate accordingly. Using a repeat loop to do this would be much more difficult to implement.

Line 2 of the script compares the current rotation of the sprite to the current rotation of the sprite plus 5 degrees. The mod (modulo) operator ensures that the rotation of the sprite is between 0 and 360 degrees. It is important to enclose the part of the statement that adjusts the position of the sprite in parentheses, like this: (sprite(me.spriteNum).rotation + 5). The parenthesis pair tells the computer to evaluate the part of the expression between the parentheses first, then to apply the result of that to the mod operator. In effect, the parentheses pair group parts of an expression so that a specific part of the statement will be handled as its own expression, before the rest of the expression is evaluated.

Line 4 of the script alters the width of the sprite so it increases by 1 each time the handler is called.

Lines 6-8 check the width of the sprite, and when the sprite grows to a width greater than 200 it is reset to a width of 50 on line 7. This logical if condition is self-adjusting because it compares its current width to a pre-determined value. The use of a logical statement when driving sprite animation with frames is a good method to employ when you want the same "stream" of numbers to alter more than one sprite property.

Line 10 of the script adjusts the horizontal position of the sprite. By adding 5 to the X component of a point, point(5,0), the sprite is moved toward the right horizontally by 5 pixels each time the handler is called. Changing the point(x,y) value to point(0,5) would move the sprite down the screen vertically because the Y component of the point is changed. You can experiment with different positive and negative numbers for point(x,y) to get the sprite to move in different directions.

Lines 12-14 check the locH (horizontal position) of the sprite and move it off screen to the left when it moves past the horizontal position of 640.

Scripts like this may seem complex at first, but the structure of the elements can be easily modified to serve a multitude of animation purposes, so it's worth studying until you have a solid understanding of how each statement within the script changes the sprite's animation and appearance on the Stage.

Procedural animation is as complex or as simple as you design it to be. There are times when keyframe animation will work just fine, and other times when Lingo-driven animation is the best. Being familiar and comfortable with both techniques offers you as a multimedia author the most versatility in implementing animation in your Director Movies.

Below are Director Movie examples to peruse and study. The example movies include simple and advanced animation techniques that make use of Lingo to create a variety of procedural animation sequences.
 

Example Movies to Download:

Simple Procedural Animation Example (19 KB) - This movie shows basic methods for using Lingo to animate a sprite.

Change Sprite State (7 KB) - This is an example of how to implement a simple state machine to switch a sprite from one animated state to another.

Scheduled Animation Example (9 KB) - This movie demonstrates a very useful technique for creating a more complex state machine that cascades from one state to the next.

Hairspray Demo (61 KB) - This movie makes use of repeat loops and mouse button states to create an unusual hairspray effect.

Drag Race (16 KB) - Demonstrates a drag and drop animated effect.

Dog Run Example (28 KB) - This movie makes use of timer objects to drive an animation of a dog running across the screen.
 

Exercise:

Using the example movies as a reference, create a Director movie that uses one or more Lingo behaviors to animate one or more sprites. Start with a simple idea and try to build it into a more robust procedural animation sequence.

<     Table of Contents     >