Learning ActionScript 3.0: Chapter 7, Motion
Pages: 1, 2, 3, 4, 5, 6, 7, 8
With that in mind, let's take a look at the script. It begins by creating a new instance of the Hand movie clip class from the library, placing it in the center of the stage, and adding it to the display list. The listener that follows in lines 6 through 9 then sets the rotation property of the resulting hand movie clip every time the playhead enters the frame. The angle is computed by the getAngle() function, after passing the location of the hand and mouse to the function.
1 var hand:MovieClip = new Hand();
2 hand.x = stage.stageWidth/2;
3 hand.y = stage.stageHeight/2;
4 addChild(hand);
5
6 addEventListener(Event.ENTER_FRAME, onLoop, false, 0, true);
7 function onLoop(evt:Event):void {
8 hand.rotation = getAngle(hand.x, hand.y, mouseX, mouseY);
9 }
The atan2() method in line 11 then subtracts the second location (in this case, think of the mouse as a point on a circle) from the first location (the hand movie clip, which serves as the center of the circle), to get its angle. However, remember that atan2() returns its angle value in radians, and you want to set the rotation of a movie clip, so degrees are required. Therefore, you must convert from radians to degrees using the rad2deg() function.
10 function getAngle(x1:Number, y1:Number, x2:Number, y2:Number):
Number {
11 var radians:Number = Math.atan2(y1-y2, x1-x2);
12 return rad2deg(radians);
13 }
14
15 function rad2deg(rad:Number):Number
16 return rad * (180 / Math.PI);
17 }
This example points one movie clip at the mouse, but the effect can be adapted in many ways. One obvious variant is to point a movie clip at another movie clip. Another visually interesting adjustment is to point many instances of a movie clip at the same object. A grid of such pointers, for example, looks interesting because each pointer rotates independently based on its location. Finally, the ultimate effect need not be visual. You can use this technique simply to track things, such as planning the trajectory of a projectile toward a target.
Adding physics to animations, games, and similar projects can really elevate them to another level of user enjoyment. The visual appearance and, in interactive scenarios, even the user experience, of a project are sometimes dramatically enhanced by surprisingly small code additions.
Although we're going to be discussing some basic physics principles in this section, it is initially more important to understand their effects than to focus minutely on the math and science behind them. For the scientifically minded, this should be viewed more as a matter of practicality than heresy. The formulas offered here are sometimes simplified, or even adapted, from their real-world counterparts for practical use or familiarity. Once you are comfortable with their uses, you can then refine their formulas, account for additional variables, and so on, to improve their realism. In short, it is often helpful to first simulate the simple orbit of a planet before considering the orbit's decay, the gravitational attraction of other bodies, and so on.
Let's start off with a simple implementation of pseudo-physics that is based on an example used previously in this chapter. If you think about it, a basic Flash simulation of gravity requires little more than acceleration in the y direction, and requires only two small changes to the previous acceleration code. What do you think would happen if you added only 1 to the y velocity (meaning no change to the x velocity), and started out with a negative y value, as seen in the following code?
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 = −10;
7 var yAcc:Number = 1;
8
9 addEventListener(Event.ENTER_FRAME, onLoop, false, 0, true);
10 function onLoop(evt:Event):void {
11 ball.x += xVel;
12 ball.y += yVel;
13
14 yVel += yAcc;
15 }
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.
This code would effectively simulate tossing a ball into the air. The ball would appear to rise initially because the y velocity is negative (remember that negative y is up in the Flash coordinate system). However, by adding a positive 1 in line 14, each time the function executes, the velocity decreases from −10 to −9 to −8, and so on, slowing the ball's ascent, just as if gravity were counteracting the upward force of the toss. Eventually, the y velocity reaches zero at the height of the toss, where the upward force and gravity reach equilibrium. Then the velocity changes to positive, continuing to increase by 1 each time. The value becomes 1, then 2, then 3, and so on, as the ball begins to accelerate downward due to the effect of gravity. shows the effect of the simulated gravity by depicting several frames of the animation at once. When a ball is tossed in the air, gravity slows its rate of ascent and then increases the rate at which it falls.
To continue your exploration of gravity, velocity, and acceleration, visit the book's companion web site. A file called wall_bounce.fla demonstrates all these concepts and adds several additional features. Included are conditionals to change the ball's direction when hitting a stage boundary, bounce behavior, and even a texture to simulate rotation during bouncing.
Note: The role of the y acceleration in this discussion is important for future topics because it behaves as a coefficient of gravity. A coefficient is a modifier that alters a property of a system. It is often a multiplier, which we'll see in a little while, multiplying by a value less than 1 to reduce an effect, or by a value grater than 1 to exaggerate an effect. However, it can also add, subtract, or divide a value, as needed. If you altered the y acceleration value in the previous example to 2 or .5, it would be doubling or halving the amount of gravity applied, respectively.
All other things being equal, if you slide a hockey puck along three surfaces—a street, a marble floor, and an ice rink—the puck will travel three different distances due to friction. Friction will be highest on the street, building up resistance to motion between the puck and the street surface, limiting the progress of the puck. Friction will be reduced on the marble surface, and lowest on the ice, allowing the puck to travel the farthest.
A simple way to add friction to an animation is to create a friction coefficient that gradually reduces velocity over time. To demonstrate this, we'll start with the example from the section. You'll only need to do two things to add friction. First, create the coefficient variable, as seen in line 10, and then multiply the x and y velocities by this coefficient in lines 14 and 15. Remember that friction hinders movement, so you want to choose a friction value between 0 and 1. Depending on the application, you can vary the number. Perhaps you might use .97 for ice, .90 for marble, and .60 for asphalt.
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);
8 var xVel:Number = Math.cos(radians) * speed;
9 var yVel:Number = Math.sin(radians) * speed;
10 var frCooef:Number = .95;
11
12 addEventListener(Event.ENTER_FRAME, onLoop, false, 0, true);
13 function onLoop(evt:Event):void {
14 xVel *= frCoeff;
15 yVel *= frCoeff;
16 ball.x += xVel;
17 ball.y += yVel;
18 }
19
20 function deg2rad(deg:Number):Number {
21 return deg * (Math.PI / 180);
22 }
Note: The effect of friction may be familiar to you as one kind of easing. Easing is so named because when used, an object appears to "ease in" to an animation, accelerating as the animation progresses, or "ease out" of an animation, decelerating as the animation finishes. We'll discuss several more elaborate easing equations already built in to ActionScript later in this chapter.