swastik's
life is work
Search This Blog
4/17/10
Velocity explained
This tutorial gets you started with basic motion: velocity, vectors, and acceleration. These concepts will be used for almost every bit of ActionScripted animation you do from here on out.
The speed part of it is usually defined in terms of pixels per frame (ppf). In other words, if a movie clip is at a certain point as it enters a frame, it’s going to be so many pixels away from that point at the end of the frame.In most cases, using pixels per frame works fine, and it is definitely the simplest to program. However, due to the unstable nature of frame rates in Flash, using pixels per frame may make your animation slow down at certain points when too much is happening, there is too much to compute, or the CPU is busy doing something else. If you are programming some kind of game or simulation in which it is crucial that the animation proceeds at a very uniform rate, you might want to use an interval-based animation instead.
Before getting into coding velocity, I want to talk a little bit about vectors, as that’s how velocity is generally depicted.
Vectors and velocity
A
vector
is something that has magnitude and direction. In the case of velocity, the magnitude is the speed. Vectors are drawn as arrows. The length of the arrow is its magnitude, and the direction the arrow is pointing in is, naturally, the direction of the vector. The following figure 1 shows some vectors.
One thing to note is that the magnitude is always positive. A vector with a negative magnitude would simply be a vector going in the opposite direction, as illustrated in figure 2.
Another thing to note is that vectors don’t really have any set position. Even in the case of velocity, the vector doesn’t state where something is starting or where it ends up; it just indicates how fast and in which direction the object is moving. Thus, two vectors can be equal if they have the same direction and magnitude, even if they are describing two different objects in two different locations, as shown in Figure 3
If vectors have the same magnitude and direction, they are the same. Position doesn’t matter.
Velocity on one axis
I’m going to simplify things at first, by limiting velocity to a single axis: the x axis, or horizontal motion. This is basically saying that the direction is zero degrees, due east, or from the left side of the screen to the right side of the screen—however you want to look at it. The speed is just how many pixels it moves in that direction each frame. Thus, if I say that the velocity on the x axis is 5, I mean that the object will move 5 pixels each frame from left to right. This also means that if I say the velocity is
−
5 on the x axis, it will move right to left, 5 pixels each frame.
Throughout , I will use
vx
to stand for velocity on the x axis
, and
vy
to mean velocity on the y axis
.
Positive
vx
means to the right
, and
negative
vx
means to the left
.
Positive
vy
means down
, and
negative
vy
means up
.
For velocity on one axis, you simply add the velocity to the object’s position on that axis. Whatever your
vx
is, you add it to the object’s
_x
property on each frame.
Let’s see it in action. The first few examples in this tutorial will use a similar setup . You’ll use an FLA file with a single movie clip symbol in the library, named
ball
and exported with the same linkage name. For each example, I’ll give you code to put on frame 1 of the main timeline. Here’s the first example,
init();
function init():Void
{
vx = 5;
ball = attachMovie("ball", "ball", 0);
ball._x = 0;
ball._y = Stage.height / 2;
}
function onEnterFrame():Void
{
ball._x += vx;
}
In this example, first you set an x velocity (
vx
) of 5. Remember that is 5 pixels per frame, so on each frame, the
vx
is added to the
_x
property. Then it goes through the business of getting the ball out of the library and onto the stage, and setting up the event handler for the
enterFrame
event. On each frame, the ball will be placed 5 pixels to the right of where it was on the last frame. Try it out. Pretty good illusion of motion, eh?
Play around with it. Give it higher values or lower values for
vx
. Try some negative values and watch it move in the other direction.
See if you can make it move on the y axis instead.
Here is what u will get....
Velocity on two axes
Moving along two axes is pretty simple. You just define a
vx
and a
vy
, and then add the
vx
to the
_x
property and the
vy
to the
_y
property on each frame. So, what you are saying is that for each frame, the object is going to move so many pixels on the x axis and so many pixels on the y axis.
The next example demonstrates this, and here it is:
init();
function init():Void {
vx = 5;
vy = 5;
ball = attachMovie("ball", "ball", 0);
ball._x = 0;
ball._y = Stage.height/2;
}
function onEnterFrame():Void {
ball._x += vx;
ball._y += vy;
}
Again, play around with the velocity variables until you get a good feel for them. Don’t forget to try out some negative values.
Here is the animation for you...
and here is the code with the loop...
init();
function init():Void {
vx = 5;
vy = 5;
ball = attachMovie("ball", "ball", 0);
ball._x = Stage.width/2;
ball._y = Stage.height/2;
}
function onEnterFrame():Void {
ball._x += vx;
ball._y += vy;
if (ball._y>Stage.height) {
ball._x = Stage.width/2;
ball._y = Stage.height/2;
}
}
Angular velocity
OK, so far, so good. You have some real animation going on, using velocity on two axes. But in many cases—maybe most cases—x and y velocity won’t be the initial data you have.
The fact is I’m kind of cheating with the definition of velocity here. I said it’s speed in a direction, but now I’ve given you two different speeds in two different directions. The reason I did that is because, in Flash, you position objects by placing them on x, y coordinates. So you need to end up with a velocity and position on both axes, but that’s not necessarily what you start out with.
What if you just have a value for speed and an angle for direction, per the definition. Say you want something to move at an angle of 45 degrees and a speed of 3 pixels per frame. I don’t see any
vx
or
vy
, or anything even similar in that description.
Fortunately, we’ve already been introduced to the tools we need to derive
vx
and
vy
from that description. Think back to the discussion of trigonometry in . Now, look at the following Figure , which shows what you want the ball to do on each frame: move 3 pixels at an angle of 45 degrees.
A magnitude and a direction
Does this diagram look familiar? How about if I add another line? What do you know? You have a right triangle, with one angle and the hypotenuse defined!
Magnitude and direction mapping becomes a right triangle
Notice that the two legs of that triangle lie on the x and y axes. In fact, the leg that lies on the x axis is equal to the distance the ball is going to move on the x axis. The same goes for the leg on the y axis. Remember that in a right triangle, if you have one side and one angle, you can find all the rest. So, given the 45 degrees and the hypotenuse of 3 pixels, you should be able to use
Math.cos
and
Math.sin
to find the lengths of
vx
and
vy
.
The side adjacent to the angle is
vx
. The cosine of an angle is the adjacent/hypotenuse. Or, stated another way, the adjacent side is the cosine of the angle times the hypotenuse. Similarly, the opposite side is
vy
. Sine is opposite/hypotenuse, or the opposite is the sine times hypotenuse.
Here’s the exact code you would use:
vx = Math.cos(angle) * speed;
vy = Math.sin(angle) * speed;
Now don’t you dare forget to convert the 45 degrees to radians before passing it into the
Math
functions! Once you have the
vx
and the
vy
, you can easily add these to the x, y position of the object you are animating.
The next example has the following code on frame 1:
init();
function init():Void {
angle = 45;
speed = 3;
ball = attachMovie("ball", "ball", 0);
ball._x = Stage.width/2;
ball._y = Stage.height/2;
}
function onEnterFrame():Void {
var radians:Number = angle*Math.PI/180;
var vx:Number = Math.cos(angle)*speed;
var vy:Number = Math.sin(angle)*speed;
ball._x += vx;
ball._y += vy;
}
The main difference here is that you’re starting off with
angle
and
speed
rather than
vx
and
vy
. The velocities are calculated as local variables, used, and discarded. Of course, in a simple case like this, where the angle and speed are never changing, it would make more sense to calculate the velocities
once and save them as timeline variables. But in most advanced motion, both the direction and speed of motion will be constantly changing, so the
vx
and
vy
will not remain static.
To experiment with this example, change the angle around. See for yourself that you can make the ball travel at any speed and any angle by simply changing those two numbers.
Here is the movie:
A mouse follower
Let’s use the velocity concepts to expand With what you just learned, you can now throw some speed into the mix and get a velocity based on the current angle. This example uses an arrow movie clip, rather than the ball. Here is the code for it :
init();
function init():Void
{
speed = 5;
arrow = attachMovie("arrow", "arrow", 0);
arrow._x = Stage.width / 2;
arrow._y = Stage.height / 2;
}
function onEnterFrame():Void
{
var dx:Number = _xmouse - arrow._x;
var dy:Number = _ymouse - arrow._y;
var angle:Number = Math.atan2(dy, dx);
arrow._rotation = angle * 180 / Math.PI;
var vx:Number = Math.cos(angle) * speed;
var vy:Number = Math.sin(angle) * speed;
arrow._x += vx;
arrow._y += vy;
}
While this is a pretty complex effect, there shouldn’t be anything in here that you don’t fully understand by now. You’re getting the x distance and y distance to the mouse, and from that using
Math.atan2
to get the angle that forms. You’re then using that angle to rotate the arrow, and using
Math.cos
and
Math.sin
along with the speed to find the x and y velocities. Finally, you’re adding the velocities to the position.
Here is the movie for u:
Velocity extended
I’m entering into dangerous territory here, but I’m going to start taking the definition of velocity into places it was never meant to go. While, in a strict sense, velocity refers to change of position and physical motion through space, there’s no need to limit the concepts you’ve just learned to just the
_x
and
_y
properties of movie clips.
A movie clip has a lot of properties you can tinker with, and almost all of them can accept a wide range of values that you can change over time to produce animation.
An example would be having a movie clip spin around. In this case, you are changing the object’s
_rotation
property on each frame by adding a value to it. You can make it spin quickly by adding a
high value to the
_rotation
property on each frame, or have it spin more slowly by adding a smaller value. Correct or not, I usually refer to the variable that holds the spinning speed as
vr
, for rotational velocity.
Using the familiar arrow movie clip, you can come up with something like this :
init();
function init():Void
{
vr = 5;
arrow = attachMovie("arrow", "arrow", 0);
arrow._x = Stage.width / 2;
arrow._y = Stage.height / 2;
}
function onEnterFrame():Void
{
arrow._rotation += vr;
}
In terms of velocity here, the speed is 5 and the direction is clockwise. I might even get away with that one, as there’s still some motion going on, but when I start using terms like “alpha velocity” (how fast something is fading in or out), I’m sure I’ll ruffle some feathers. Still, I find it useful to think of such properties in these same terms. I want to change the alpha at a certain rate by adding or subtracting to its value on each frame. As I often find myself changing several properties over time, each at certain rates, it’s nice to relate them all by calling them velocities. Thus, I might wind up with something like this:
function onEnterFrame():Void
{
arrow._x += vx;
arrow._y += vy;
arrow._alpha += vAlpha;
arrow._rotation += vr;
arrow._xscale = arrow._yscale += vScale;
// etc.
}
That about does it for velocity and its cousins.
No comments:
Post a Comment
Newer Post
Older Post
Home
No comments:
Post a Comment