As shown earlier in this chapter, you draw lines and shapes on three classes of objects: Shape, Sprite, and MovieClip. In effect, these objects are canvases for the drawings. To make drawings move from one location to another, you move the canvas. You can think of the Shape, Sprite, and MovieClip containers as transparent sheets of film with the drawings inked on top. You place the film on the stage. Then to create motion, you reposition the film on the stage. If you want to move objects together, you can place them on the same piece of film. If you want to move them independently, you have to place them on separate pieces of film.
One popular animation technique makes use of Flash's TimerEvent. It's sort of like setting one of those kitchen minute timers, and each time it goes "ding!" you move the drawing. ActionScript's Timer class uses two constants: TIMER_COMPLETE and TIMER. In earlier examples (Keeping Time with TimerEvent) you saw TIMER_COMPLETE in action. It triggers an event when the time has completely run out. You use the TIMER constant when you want to trigger repeated events at regular intervals.
Here's how it works: When you create an instance of the Timer class, you provide two parameters. The first parameter is called the delay. Think of it as the time in milliseconds before the timer goes "ding." The second parameter is the repeatCount. Think of it as the number of times you want to reset the timer to run again.
You can find a copy of this code in the Flash file 18-6_Animate_Shape.fla on the Missing CD page at www.missingmanuals.com/cds.
Select File→New and choose ActionScript 3.0.
A new, empty Flash document appears.
Press F9 (Option-F9).
The Actions panel opens, where you can enter ActionScript code.
Type this line into the Actions panel to create an instance of the MovieClip class named mcShapes:
var mcShapes:MovieClip = new MovieClip();
MovieClip is one of three data types that let you draw vector graphics.
Create an instance of the Timer class.
var tmrMover:Timer=new Timer(500,12);
The parameters set the timer's delay value to 500 milliseconds and the repeatCount to 12.
Define the line and fill style for the circle.
mcShapes.graphics.lineStyle(4,0x000033); mcShapes.graphics.beginFill(0x0099FF,.5);
You've set the line and fill colors to shades of blue. The code sets no alpha value (transparency) in the line style, so ActionScript assumes it should be 100%—that is, opaque. The fill has an alpha value of .5, making its transparency 50%.
Draw the circle with the drawCircle() method and then stop the fill with endFill().
mcShapes.graphics.drawCircle(250,100,75); mcShapes.graphics.endFill();
The first two parameters place the center of the circle at 250, 100 in the movie clip. (You haven't positioned the movie clip, so Flash automatically positions it at 0, 0.)
Add the movie clip to the Display List.
addChild(mcShapes);
This code adds the movie clip to the Display List, making it visible.
tmrMover.start();
The timer starts.
Register a TimerEvent listener.
tmrMover.addEventListener(TimerEvent.TIMER,timerMoverListener);
Write the function for the TimerEvent listener.
function timerMoverListener(evt:TimerEvent):void { mcShapes.x = mcShapes.x + 10; }
The timerMoverListener() function assigns a new value to the x property of the mcShapes movie clip, which makes it move horizontally. To calculate the new value for x, the function takes the current value of x and adds 10 to it. Each time the TIMER event triggers, the movie clip moves.
When the animation runs, the blue circle moves across the stage 10 pixels at a time. It moves 12 times and then stops, as shown in Figure 18-7.
mcShapes.graphics.drawRect(100,300,75,75);
Now, if you test the animation, both the circle and the square move across the stage in sync.
The world and your animations don't always move in lockstep. So to make objects move independently, you can place them in different containers. Here's a variation on the previous example that places a circle, a rectangle, and a triangle in separate containers. The code uses the Shape class as a container because it keeps the size of the published .swf file at a minimum, but you can do the same thing with Sprites, MovieClips, or any combination.
You can find a copy of this code in the Flash file 18-7_Move_Three_Shapes.fla on the Missing CD page at www.missingmanuals.com/cds.
1 var shpCircle:Shape = new Shape(); 2 var shpRectangle:Shape = new Shape(); 3 var shpTriangle:Shape = new Shape(); 4 5 shpCircle.graphics.beginFill(0x000077,1); 6 shpCircle.graphics.drawCircle(250,100,75); 7 shpCircle.graphics.endFill(); 8 9 shpRectangle.graphics.beginFill(0x009900,1); 10 shpRectangle.graphics.drawRect(200,100,150,100); 11 shpRectangle.graphics.endFill(); 12 13 shpTriangle.graphics.moveTo(200,150); 14 shpTriangle.graphics.beginFill(0x880000); 15 shpTriangle.graphics.lineTo(300,250); 16 shpTriangle.graphics.lineTo(100,250); 17 shpTriangle.graphics.lineTo(200,150); 18 shpTriangle.graphics.endFill(); 19 20 addChild(shpRectangle); 21 addChild(shpTriangle); 22 addChild(shpCircle); 23 24 var tmrMover:Timer = new Timer(250,30); 25 tmrMover.start(); 26 27 tmrMover.addEventListener(TimerEvent.TIMER,timerMoverListener); 28 29 function timerMoverListener(evt:TimerEvent):void 30 { 31 shpCircle.x += 3; 32 shpRectangle.x -= 3; 33 shpTriangle.y += 3; 34 }
What distinguishes this example from the previous one is that the first three lines create three instances of the Shape class, appropriately named shpCircle, shpRectangle, and shpTriangle. Lines 5 through 18 define the objects. None of them have a lineStyle() definition, so they're all fill and no stroke. The alpha value is set to 1, so they're completely opaque. The circle and the rectangle are drawn using built-in shapes, but the triangle is drawn line by line. Lines 20 through 22 use the addChild() method to place each shape on the stage.
The TIMER portion of the code is similar to the previous example. On line 24 when the tmrMover is created, the delay is set to 250 and the repeatCount is set to 30. This means this timer will tick off events twice as quickly as the earlier example, where the delay was set to 500. Line 27 registers the event listener timerMoverListener(). By using the TIMER constant instead of the TIMER_COMPLETE constant, this timer will trigger 30 events, instead of just one. (For more details, see Keeping Time with TimerEvent.) The function timerMoverListener() from line 29 through the last line of the code runs each time the event triggers.
To move the circle 3 pixels from left to right, this line
shpCircle.x += 3;
increments the value of the shpCircle's x property by 3. It's simply an abbreviated way of saying:
shpCircle.x = shpCircle.x + 3;
The other two lines in the function work similarly, except that by decrementing the x property, line 31 moves the rectangle from right to left. Line 32 operates on the y property of shpTriangle, so it moves down the stage.
Each time the clock ticks, the objects move. There are a couple of ways to make them move at different rates of speed. Make the values smaller, and the objects will move a shorter distance in the same time period. Or, for the most versatility, you can create separate timers for each object. That way, you can change the delay and the intervals, as well as the distance that the objects move.