Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning ActionScript 2.0 2006

.pdf
Скачиваний:
105
Добавлен:
17.08.2013
Размер:
12.47 Mб
Скачать

Chapter 16

holderClip.helicopter.verticalSpeed = 0;

}

updateAfterEvent();

}

function moveShipLeft()

{

holderClip.helicopter.targetX -= MOVEMENT_AMOUNT; if (holderClip.helicopter.targetX < 40)

{

holderClip.helicopter.targetX = 40;

}

}

function moveShipRight()

{

holderClip.helicopter.targetX += MOVEMENT_AMOUNT;

if (holderClip.helicopter.targetX > Stage.width - 15)

{

holderClip.helicopter.targetX = Stage.width - 15;

}

}

function moveShipUp()

{

if (holderClip.helicopter.verticalSpeed > -5)

{

holderClip.helicopter.verticalSpeed -= 1;

}

}

function moveShipDown()

{

if (holderClip.helicopter.verticalSpeed < 5)

{

holderClip.helicopter.verticalSpeed += 1;

}

}

function checkKeys()

{

if (Key.isDown(Key.LEFT) == true)

{

moveShipLeft();

}

if (Key.isDown(Key.RIGHT) == true)

{

moveShipRight();

}

if (Key.isDown(Key.UP) == true)

{

moveShipUp();

398

Using ActionScript for Animation

}

if (Key.isDown(Key.DOWN) == true)

{

moveShipDown();

}

}

15.Save the file, return to the Flash document, and select Control Test Movie. Pressing and holding the up arrow key causes the helicopter to climb; releasing the key lets gravity take over and the copter will free-fall.

How It Works

The first task is to set up the movie clips to be used for the animation. Any movie clip shapes can be used, but a helicopter fits the exercise nicely.

The code is definitely longer than most for this exercise, but most of it is framework code. The code to do the actual animation itself is quite small.

The first three lines are startup constants that define acceleration, ease-out rate, and the amount to move the helicopter for each press of the arrow keys:

var ACCELERATION_RATE:Number = 0.4; var EASING_FACTOR:Number = 10;

var MOVEMENT_AMOUNT:Number = 7;

Next, you create the movie clip to hold the animation, and then you attach the helicopter to the screen:

this.createEmptyMovieClip(“holderClip”, this.getNextHighestDepth()); holderClip.attachMovie(“helicopter”, “helicopter”, ;

holderClip.getNextHighestDepth());

Two properties are added to the helicopter movie clip so that you can manage its horizontal position and its vertical speed. These are made as properties of the movie clip rather than separate variables because it makes animating multiple objects easier, and it makes for a more object-oriented and cleaner approach:

holderClip.helicopter.targetX = 275; holderClip.helicopter.verticalSpeed = 0;

The initial x and y coordinates are set so that the helicopter starts at the bottom middle of the screen:

holderClip.helicopter._x = holderClip.helicopter.targetX; holderClip.helicopter._y = Stage.height - 14;

The interval is set up to update the animation and to check for key presses. The update rate is set at 20 milliseconds, which is fast enough to give smooth animation but not too fast for slower processors:

var intervalID:Number = setInterval(updateAnimation, 20); function updateAnimation()

{

// ...

}

399

Chapter 16

Within the function called by setInterval(), the first task performed is to check to see which keys have been pressed. Normally, the Key.onPress event is used to capture keystrokes; however, the operating system’s key-repeat delays cause problems with trying to allow continuous key presses. Also, this allows for multiple keys to be pressed and detected at once:

checkKeys();

The x position of the helicopter is updated. The left and right arrow keys update the targetX property for the movie clip. While one arrow key continues to be pressed, the targetX value continues to change and the easing code continues to chase after it. It’s sort of like the proverbial carrot-on-a-stick trick. The carrot (targetX) continues to move, so the rabbit (the helicopter) can never catch up. Once the arrow key is no longer being pressed, targetX stops moving, and the easing code finally lets the helicopter ease in on its location. If you play with pressing the left and right arrows while the helicopter is at the bottom of the screen, you can see this effect more readily.

holderClip.helicopter._x += (holderClip.helicopter.targetX - ; holderClip.helicopter._x) / EASING_FACTOR;

The rotation of the helicopter is updated. The rotation is adjusted according to how far the helicopter is from its targetX destination. The further away it is, the greater the rotation. There is an upper bound of 20 degrees so that the helicopter doesn’t tilt in a way that looks unrealistic. The Math.min() method makes sure that if the calculation causes the rotation to be below 20 degrees, that value is used, otherwise the value of 20 is used:

holderClip.helicopter._rotation = ; Math.min((holderClip.helicopter.targetX - ; holderClip.helicopter._x) / 5, 20);

The technique used to manage vertical speed is a bit different. Here, you make use of the acceleration principle that you learned about earlier. You keep track of the vertical speed of the helicopter, and based on that speed the code updates the y position. The up and down arrows add and remove an amount to and from the speed value, so once the helicopter starts falling, it takes a little while after pressing the up arrow for it to start to rise again:

holderClip.helicopter.verticalSpeed += ACCELERATION_RATE; holderClip.helicopter._y += holderClip.helicopter.verticalSpeed;

The helicopter is checked to see whether it has hit or passed the bottom of the screen. If so, it is snapped to the bottom and is stopped:

if (holderClip.helicopter._y >= Stage.height - 14)

{

holderClip.helicopter._y = Stage.height - 14; holderClip.helicopter.verticalSpeed = 0;

}

The last step within the animation function is to redraw the screen:

updateAfterEvent();

400

Using ActionScript for Animation

The left and right arrow key handlers add to or subtract from the targetX property, and they make sure that targetX does not go outside the bounds of the screen. These functions do not actually move the ship themselves. By changing the property, the animation routine will move the helicopter to catch up to the location specified by the targetX property:

function moveShipLeft()

{

holderClip.helicopter.targetX -= MOVEMENT_AMOUNT; if (holderClip.helicopter.targetX < 40)

{

holderClip.helicopter.targetX = 40;

}

}

function moveShipRight()

{

holderClip.helicopter.targetX += MOVEMENT_AMOUNT;

if (holderClip.helicopter.targetX > Stage.width - 15)

{

holderClip.helicopter.targetX = Stage.width - 15;

}

}

The up and down arrow key handlers add to or subtract from the verticalSpeed property, and they throttle just how much they affect the vertical speed. Without the throttling, the helicopter would quickly zoom up rather than slowly climb up:

function moveShipUp()

{

if (holderClip.helicopter.verticalSpeed > -5)

{

holderClip.helicopter.verticalSpeed -= 1;

}

}

function moveShipDown()

{

if (holderClip.helicopter.verticalSpeed < 5)

{

holderClip.helicopter.verticalSpeed += 1;

}

}

The checkKeys() function is called every time an animation pass is performed, and it takes a look at which keys are pressed. Individual keys are checked within their own if statements rather than if..else or switch..case statements because it is possible to have multiple keys being pressed at one time:

function checkKeys()

{

if (Key.isDown(Key.LEFT) == true)

{

moveShipLeft();

}

if (Key.isDown(Key.RIGHT) == true)

401

Chapter 16

{

moveShipRight();

}

if (Key.isDown(Key.UP) == true)

{

moveShipUp();

}

if (Key.isDown(Key.DOWN) == true)

{

moveShipDown();

}

}

Summar y

This chapter covered many different aspects of ActionScript-based animation. Some of the things that you learned include the following:

How to animate using the timeline.

Two different fundamental techniques for script-based animation, namely the onEnterFrame technique and the setInterval technique.

The relationship between onEnterFrame- and setInterval-based animation with movie frame rate.

Frame rates of between 24 and 50 fps, or 42 to 20 milliseconds per frame, are generally optimal.

How to attach and animate multiple movie clips.

How to add random behavior to animation.

How to use easing to create smoother, more natural transitions.

Exercises

1.Use the onEnterFrame animation technique to close in on the cursor’s position. It should slow down as it gets closer to the cursor. Hint: apply easing separately to the x and y coordinates, and use the MovieClip properties _xmouse and _ymouse to find the cursor’s position.

2.Rework exercise 1 so that it uses the setInterval() animation technique instead. Modify it so

that there are three movie clips that follow the cursor, and give them different easing values.

3.Modify the snowstorm exercise to make the snowflakes look like they are tumbling as they fall. Make the snowflakes more irregular in shape by redrawing them in the library and then vary the _rotation of each snowflake to create the tumbling effect.

4.Use either the onEnterFrame or the setInterval() technique to create a bouncing ball effect where the ball accelerates as it drops, then slows down as it rises up. For each bounce it should lose some of its height.

402

17

Automated Transitions

So far, you have been creating animations at a low level, where you implement all of the animation code yourself. This certainly yields maximum control over animation and interactivity; however, Flash also gives you a more automated way of animating in the form of the Tween class. This class allows you to create transitions with any movie clip property.

The Tween Class

The Tween class was actually available in Flash MX 2004; however, it was not immediately documented. This is too bad, because it is an immensely useful class. The idea behind this class is that you can take any numeric movie clip property and transition the property values from one number to another number. The general form for the Tween class is as follows:

import mx.transitions.Tween;

var myTween:Tween = new Tween(clipHandle:Object, propertyName:String, ;

easingFunction:Function, startValue:Number, stopValue:Number, ; duration:Number, useSeconds:Boolean);

The first parameter, clipHandle, holds the movie clip being targeted for animation. It can actually hold a handle to any object, such as a component or an instance of a custom class. The second parameter, propertyName, is a string representing which property to change. Some examples are _x, _alpha, and _rotation. The easingFunction parameter takes a handle to a function that calculates how the animation accelerates and decelerates when going from the start to the end values. Each of the six built-in easing classes has four easing methods. Next, startValue and stopValue can be any numerical values. If useSeconds is set to true, then duration sets the number of seconds that the animation will take to complete. If useSeconds is set to false, then the duration value sets the number of frames that the animation will take to complete.

The clipHandle and propertyName parameters can actually be empty if you are not using the tween to directly manipulate a movie clip. If you use the onMotionChanged event, you can still get each tweened value, and you can indirectly animate one or more objects based on that. The next Try It Out exercise shows this in action.

Chapter 17

The following code moves a movie clip called circleClip from an x value of 0 to an x value of 200 in 2 seconds, with strong easing applied to both the start and the end of the tween:

import mx.transitions.Tween;

var myTween:Tween = new Tween(circleClip, “_x”, ; mx.transitions.easing.Strong.easeInOut, 0, 200, 2, true);

The following code fades a movie clip called circleClip from an alpha value of 100 to an alpha value of 50 in 30 frames, with elastic easing applied at the end:

import mx.transitions.Tween;

var myTween:Tween = new Tween(circleClip, “_alpha”, ; mx.transitions.easing.Elastic.easeOut, 100, 50, 30, false);

Absolute Versus Relative Tweens

Sometimes you might want to set absolute start and end points for a tween; other times you might want the tweens to be relative to existing values. For example, if you have a movie clip called circleClip in the middle of the stage, the following code moves it from an x value of zero to an x value of 200, regardless of where it was initially placed on the stage:

import mx.transitions.Tween;

var myTween:Tween = new Tween(circleClip, “_x”, ; mx.transitions.easing.Strong.easeInOut, 0, 200, 2, true);

To instead move the movie clip 200 pixels to the right of the current position, set the start and end values relative to the current x position of the movie clip:

import mx.transitions.Tween;

var myTween:Tween = new Tween(circleClip, “_x”, ;

mx.transitions.easing.Strong.easeInOut, ; circleClip._x, circleClip,_x + 200, 2, true);

Built-In Easing Classes and Methods

These are the classes that are available to set how the transition accelerates and decelerates between the starting and ending values. They are used in conjunction with one of the four easing methods:

import mx.transitions.Tween;

var myTween:Tween = new Tween(circleClip, “_x”, ; mx.transitions.easing.Back.easeIn, 0, 200, 2, true);

import mx.transitions.Tween;

var myTween:Tween = new Tween(circleClip, “_x”, ; mx.transitions.easing.Back.easeOut, 0, 200, 2, true);

import mx.transitions.Tween;

var myTween:Tween = new Tween(circleClip, “_x”, ; mx.transitions.easing.Regular.easeInOut, 0, 200, 2, true);

import mx.transitions.Tween;

var myTween:Tween = new Tween(circleClip, “_x”, ; mx.transitions.easing.None.easeNone, 0, 200, 2, true);

404

Automated Transitions

The following table lists the available easing classes:

Name

Description

 

 

mx.transitions.easing.Back

Pulls the animation back outside of its travel range,

 

giving an elastic effect.

mx.transitions.easing.Bounce

Bounces the animated object so that it takes multiple tries

 

before it stops at the target value, or when applied at the

 

beginning, makes each bounce higher until it gets to the

 

target property value.

mx.transitions.easing.Elastic

Oscillates at the beginning or at the end of the transition.

 

Similar to the Back class, only it oscillates several times

 

instead of only once.

mx.transitions.easing.Regular

Slowly transitions from start to stop or vice versa.

mx.transitions.easing.Strong

Performs the same effect as the Regular class, only the

 

acceleration and the deceleration are more pronounced.

mx.transitions.easing.None

Transitions from start to end with no variation in

 

acceleration.

Here are descriptions of each of the built-in easing methods:

Name

Description

 

 

easeIn

Provides easing at the start of the animation.

easeOut

Provides easing at the end of the animation.

easeInOut

Provides easing both at the start and at the end of the

 

animation.

easeNone

Does not apply any easing. This method applies only to

 

the None class.

Tween Class Methods

The following table describes the methods that are available from each Tween class instance:

Method

Return

Description

 

 

 

continueTo

Nothing

Continues the transition from the current property

 

 

value of the movie clip to the new property value

 

 

passed to the method, taking a duration that is

 

 

passed to the method to make the new transition.

fforward

Nothing

Fast-forwards to the end of the tween.

 

 

Table continued on following page

405

Chapter 17

Method

Return

Description

 

 

 

nextFrame

Nothing

Goes to the next frame of a stopped tween.

prevFrame

Nothing

Goes to the previous frame of a stopped tween.

resume

Nothing

Resumes a stopped tween from the point at which

 

 

the stop() method was called.

rewind

Nothing

Goes back to the beginning of the tween.

start

Nothing

Starts playback of the tween from the beginning.

 

 

When a new tween is created, it is automatically

 

 

started without the need to call this method.

stop

Nothing

Pauses the tween.

yoyo

Nothing

Reverses the direction of the tween.

The following sections take a closer look at the Tween class methods.

continueTo()

The continueTo() method overrides the target property value and the duration value and continues the tween using the current property value as the new start point. This method is useful for continuous animation based on user input, such as for games. Using continueTo() allows you to update the transition based on a new destination based on an action such as the arrow keys being pressed.

This method takes two parameters. The first parameter is the new target value for the tweened property. The second parameter is a value for how long the tween should take to get from the current property value to the target property value. If the useSeconds constructor parameter was set to true, this parameter represents the number of seconds, otherwise it represents the number of frames.

myTween.continueTo(endValue:Number, duration:Number);

Here’s an example using continueTo():

import mx.transitions.Tween;

var myTween:Tween = new Tween(circleClip, “_x”, ; mx.transitions.easing.Regular.easeOut, 100, 300, 2, true);

var keyHandler:Object = new Object(); keyHandler.onKeyDown = function()

{

var newDestination:Number;

if (Key.isDown(Key.LEFT) == true)

{

newDestination = myTween.finish - 50; myTween.continueTo(newDestination, 2);

}

if (Key.isDown(Key.RIGHT) == true)

{

406

Automated Transitions

newDestination = myTween.finish + 50; myTween.continueTo(newDestination, 2);

}

}

Key.addListener(keyHandler);

Future invocations of the same tween will use the new start value, end value, and duration.

fforward()

The fforward() method immediately goes to the end of the tween, bringing the tweened parameter to its final value. This method takes no parameters. Here’s its syntax:

myTween.fforward();

Following is an example use of fforward():

import mx.transitions.Tween;

var myTween:Tween = new Tween(circleClip, “_x”, ; mx.transitions.easing.Regular.easeOut, 100, 300, 5, true);

var keyHandler:Object = new Object(); keyHandler.onKeyDown = function()

{

if (Key.isDown(Key.LEFT) == true)

{

myTween.rewind();

}

if (Key.isDown(Key.RIGHT) == true)

{

myTween.fforward();

}

}

Key.addListener(keyHandler);

nextFrame()

The nextFrame() method advances to the next frame of a stopped tween. This method takes no parameters. Its syntax is as follows:

myTween.nextFrame();

Here’s an example of its use:

import mx.transitions.Tween;

var myTween:Tween = new Tween(circleClip, “_x”, ; mx.transitions.easing.Regular.easeOut, 100, 300, 100, false);

var keyHandler:Object = new Object(); keyHandler.onKeyDown = function()

{

if (Key.isDown(Key.LEFT) == true)

407