Learning ActionScript 3.0: Chapter 7, Motion
Pages: 1, 2, 3, 4, 5, 6, 7, 8
1 var ball:MovieClip = new Ball();
2 ball.x = ball.y = 100;
3 addChild(ball);
4
5 var xVel:Number = 4;
6 var yVel:Number = 4;
7
8 addEventListener(Event.ENTER_FRAME, onLoop, false, 0, true);
9 function onLoop(evt:Event):void {
10 ball.x += xVel;
11 ball.y += yVel;
12 }
Because the updated values are always 4 pixels, the ball is said to have a constant velocity. If you think of the onLoop() function executing once per second, the velocity would be 4 pixels per second, South-South-East. However, the function is executed every time the playhead enters the frame, so it's tied to the temp (frame rate). A frame rate of 20 frames per second (fps), therefore, would yield a velocity of 80 pixels (approximately one inch on a 72-pixel-per-inch monitor) per second. Let's see what happens if we vary the velocity over time.
Changing the velocity over time adds acceleration to an object. Consider the previous example of a constant velocity of 4 pixels down and to right. At 20 frames per second, this constant velocity (equivalent to 4 + 4 + 4 + 4, and so on) would take 3 seconds to move 240 pixels. However, if we accelerate the object 1 pixel per function execution, the changing velocity would look like 4 + 5 + 6 + 7 + 8, and so on. At that rate, using our 20 fps frame rate, the velocity would reach 23 pixels per iteration, and the ball would travel 270 pixels, in only one second. Acceleration is the compound interest of movement!
To realize this change, all you have to do is increment the velocity by the acceleration (rate of change of velocity) every time the function executes. Start with typed variables with initial values in lines 7 and 8, and then use them to increment the velocity in lines 15 and 16. This yields the effect of moving 4 pixels the first time, adding 1 to the velocity, moving 5 pixels the second time, adding 1, and so on.
1 var ball:MovieClip = new Ball();
2 ball.x = ball.y = 100;
3 addChild(ball);
4
5 var xVel:Number = 4;
6 var yVel:Number = 4;
7 var xAcc:Number = 1;
8 var yAcc:Number = 1;
9
10 addEventListener(Event.ENTER_FRAME, onLoop, false, 0, true);
11 function onLoop(evt:Event):void{
12 ball.x += xVel;
13 ball.y += yVel;
14
15 xVel += xAcc;
16 yVel += yAcc;
17 }

The effect is a rapid acceleration of the ball along its set direction. Figure 7-2 illustrates this effect by depicting the increasing distance between ball positions.
The opposite of acceleration, deceleration can be simulated by decreasing the velocity. Later on, we'll use this technique, in part, to illustrate gravity, and we'll also look at a more sophisticated deceleration technique to simulate friction.
While many people find geometry and trigonometry intimidating, the small investment required to understand a few basic principles in these disciplines can pay large dividends. For example, what if you needed to find the distance between two points, or rotate one object around another? These small tasks are needed more often than you may think, and are easier to accomplish than you may realize.
This excerpt is from Learning ActionScript 3.0. Learning ActionScript 3.0 gives you a solid foundation in the Flash language and demonstrates how you can use it for practical, everyday projects. The book does more than give you a handful of sample scripts, defining how ActionScript and Flash work. It gives you a clear look into essential topics such as logic, event handling, displaying content, migrating legacy projects to ActionScript 3.0, classes, and much more. Written for those new to the language, this book doesn't rely exclusively on prior knowledge of object-oriented programming (OOP). Instead, it helps you expand your skillset by first focusing on clear, concise examples in the timeline, evolving into OOP examples over time-allowing you to choose the programming approach with which you are most comfortable.
Let's say you are programming a game in which a character must be pursued by an enemy and must exit through one of two doors to safety. However, the enemy is close enough that the character must choose the nearest exit to survive. The player controls the character, but you must make the game challenging enough for the enemy to catch the character if the player makes the wrong decision. To do that, the enemy must know which exit is closest.
To determine which of two objects (the doors) is closest to a given point (the enemy), you need only one formula called the Pythagorean theorem. Simplified, the theorem says that the length of the longest side of a right triangle is equal to the square root of the sum of the squares of the horizontal and vertical sides. For our needs, this can be determined by finding the differences between the two x values and two y values, and then checking the square root of the sum of those two squares. Figure 7-3 illustrates both descriptions.
To determine the distance between two points in ActionScript, you must calculate the difference between the x values of both points and multiply that difference by itself (squaring the value). Then do the same thing with the y values (squaring that difference, as well). Finally, following the Pythagorean theorem, use the Math object to return the square root of that sum.
function getDistance(x1:Number, y1:Number, x2:Number, y2:Number):
Number {
var dx:Number = x1-x2;
var dy:Number = y1-y2;
return Math.sqrt(dx * dx + dy * dy);
}
Here is an example usage of our getDistance() function, seen in the accompanying distance2.fla source file. It compares the distance between ball0 and ball1 to the distance between ball0 and ball2:
var dist1 = getDistance(ball0.x, ball0.y, ball1.x, ball1.y);
var dist2 = getDistance(ball0.x, ball0.y, ball2.x, ball2.y);
if (dist1 < dist2) {
trace("ball1 is closest to ball0");
} else {
trace("ball2 is closest to ball0");
}
Earlier we discussed velocity as a vector quantity because it combined magnitude and direction. However, the direction in the previous example was determined by changing x and y coordinates. Unfortunately, such a direction is easily identifiable only when moving along simple paths, such as along the x or y axis. A much better way to indicate a direction is to specify an angle to follow.
Before we discuss angles and their different units of measure, it will help to understand how angles are indicated in the Flash coordinate system. As you might expect, angles are commonly referenced using degrees, but it's important to note that 0 degrees is along the x axis pointing to the right. The 360-degree circle then unfolds clockwise around the coordinate system. This means 90 degrees points down along the y axis, 180 degrees points left along the x axis, and so on. This is depicted in Figure 7-4.
Now that you have a correct point of reference, the next important concept to understand is that most of ActionScript, like most computer languages and mathematicians, does not use degrees as its preferred unit of measurement for angles. This is true for just about all common uses of angles, except for the rotation property of display objects and one or two somewhat more obscure items (such as a method of the MatrixTransformer class also used to rotate display objects). These entities use degrees as measure angles and to remain comfortable and familiar to users. The remainder of ActionScript uses radians: A radian is the angle of a circle defined by moving along the outside of the circle only for a distance as long as its radius, as seen in 7-4. One radian is 180/PI degrees, which is approximately 57 degrees.
While some of that may prove helpful, or even interesting, for our purposes we don't need to memorize this information. Instead, all we need to do is remember that there is a formula handy for our conversion needs. Converting degrees to radians is accomplished by multiplying the original angle in degrees by (Math.PI/180). Conversely, radians can be converted to degrees by multiplying the original angle in radians by (180/Math.PI). In the upcoming example, we'll write a utility function for this purpose that we can use throughout the rest of our examples.