Learning ActionScript 3.0: Chapter 7, Motion
Pages: 1, 2, 3, 4, 5, 6, 7, 8
Now we're prepared to address the task at hand. We must send a movie clip off in a direction specified by an angle (direction) at a specific speed (magnitude). This will be the resulting velocity. This script starts by creating a movie clip and positioning it on stage at point (100, 100). It then specifies the speed and angle at which the movie clip will travel, and converts commonly used degrees to ActionScript-preferred radians using the utility function at the end of the script.
1 var ball:MovieClip = new Ball(); 2 ball.x = ball.y = 100; 3 addChild(ball); 4 5 var speed:Number = 12; 6 var angle:Number = 45; 7 var radians:Number = deg2rad(angle);

With both a direction (angle) and magnitude (speed), the required velocities relative to the x and y axes can be determined. We accomplish this by using the sine() and cosine() methods of the Math class. Think of a triangle with one point at the origin of the x/y axes, as seen in Figure 7-5.
The sine of an angle is the length of the opposite side of the triangle divided by the length of the triangle's hypotenuse (which is the side opposite the triangle's right angle). The cosine of an angle is the length of the adjacent side of the triangle divided by the length of the triangle's hypotenuse. Therefore, the x component of the direction is determined by calculating the cosine of a specified angle, and the y component of the direction is determined by calculating the sine of the same angle. Multiply each value by the speed of the movement and you have a velocity vector.
8 var xVel:Number = Math.cos(radians) * speed; 9 var yVel:Number = Math.sin(radians) * speed;
All that remains is to add that change in velocity to the x and y coordinates of the ball and it's on the move.
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
16 function deg2rad(deg:Number):Number {
17 return deg * (Math.PI/180);
18 }
Now that you know how to determine x and y coordinates from an angle, circular movement is a snap. For example, it will now be relatively trivial for you to move an object in a circle, the way a moon revolves around a planet. With circular movement, we are not interested in the velocity derived from direction and magnitude, because the ball in this example will not be traveling along that vector. Instead, we want to calculate the x and y coordinates of many consecutive angles. By plotting the sine and cosine of many angles, you can move the ball in a circle.
If you think of the sine and cosine values of various angles, this technique is easy to understand. (For simplicity, all angles will be discussed in degrees, but assume the calculations are performed with radians.) The values of both cosine and sine are always between −1 and 1. The x component, or cosine, of angle 0 is 1, and the y component, or sine, of angle 0 is 0. That describes point (1, 0), or straight out to the right. The cosine of 90 degrees is 0 and the sine of 90 is 1. That describes point (0, 1), or straight down.
This continues around the axes in a recognizable pattern. Remembering that we're discussing degrees but calculating in radians, the cosine and sine of 180 degrees are −1 and 0, respectively (point(−1, 0), straight to the left), and the cosine and sine of 270 degrees are 0 and 1, respectively (point(0, 1), straight up).
You have only two things you must still do to plot your movie clip along a circular path. Because all the values you're getting from your math functions are between −1 and 1, you must multiply these values by the desired radius of your circle. A calculated value of 1 times a radius of 150 equals 150, and multiplying −1 times 150 gives you −150. This describes a circle around the origin point of the axes, which spans from −150 to 150 in both horizontal and vertical directions.
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.
Figure 7-6 illustrates these concepts in one graphic. Each color represents a different angle shown in degrees, with the x and y values expressed in both standard cosine and sine units (−1 to 1) and the result of multiplying that value by a desired radius of 150.

Finally, you must position the circle wherever you want it on the stage. If you take no action, the object will rotate around the upper-left corner of the stage, or point(0, 0). This script centers the circle.
The first nine lines of the script initialize the important variables. Specified are a starting angle of 0, a circle radius of 150, an angle increment of 10, and a circle center that matches the center of the stage (its width and height divided by 2, respectively). Also created is the satellite that will be orbiting the center of the stage, derived from the Asteroid class. This uses the same technique you used to create the balls in the previous files, making a new display object from the linkage class of a library symbol, but you might need a little spice now, so an asteroid it is. To prevent a quick blink of the satellite at point(0,0), it is initially placed offstage in line 8 before becoming a part of the display list in line 9.
1 var angle:Number = 0; 2 var radius:Number = 150; 3 var angleChange:Number = 10; 4 var centerX:Number = stage.stageWidth/2; 5 var centerY:Number = stage.stageHeight/2; 6 7 var satellite:MovieClip = new Asteroid(); 8 satellite.x = satellite.y = −200; 9 addChild(satellite);
The last part of the script is the frame loop and handy degree-to-radian conversion utility discussed earlier. The function begins by translating the specified angle from degrees to radians and determining the x (cosine) and y (sine) values that correspond to each angle. The function then multiplies each value by the desired radius and adds it to the origin point of the circle (in this case, center stage). After each plot, the angle is incremented (line 15) and then reset to an equivalent near-zero angle once it reaches or exceeds 360.
The angle value reset (line 16) is accomplished using the modulus operator, which simply determines the remainder after a division. For example, using the 10-degree increment in this example, 360 goes into 350 zero times, leaving a remainder of 340. However, 360 goes into 360 one time, leaving a remainder of 0. As a result, the angle is reset to 0, and you don't have to deal with angles like 370 or 380 degrees.
10 addEventListener(Event.ENTER_FRAME, onLoop, false, 0, true);
11 function onLoop(evt:Event):void {
12 var radian:Number = deg2rad(angle);
13 satellite.x = centerX + radius * Math.cos(radian);
14 satellite.y = centerY + radius * Math.sin(radian);
15 angle += angleChange;
16 angle %= 360;
17 }
18
19 function deg2rad(deg:Number):Number {
20 return deg * (Math.PI/180);
21 }
Note: The last step of the circular rotation script, resetting the angle on line 16, isn't wholly necessary because Flash will adjust angle values automatically. However, it's not a bad idea to understand what's going on in your scripts, in case you have to use a value for another purpose. Obviously, the fewer surprises you must face, the better.

Determining points on a circle when you start with an angle requires sine and cosine, as seen in the previous example. However, the opposite of that task requires a different trigonometric method. Determining an angle when starting with point data requires atan2(). This method of the Math class determines the angle between two points, based on two assumptions. The first is that the zero angle is on the right half of the x axis, and the second is that the angles increase moving counterclockwise from this zero point.
The atan2() method is especially useful when you want to use rotation to point something at another point. For instance, the next code example uses a frame event to continuously point a movie clip at the mouse location, no matter where the mouse is on the stage, as simulated in Figure 7-7.
There are two important issues to be aware of when using atan2(). The method always takes y point data as its first parameter (instead of x, which is more commonly placed in the first position), and the method returns its angle in radians, not degrees.