- Because timeline and clip-event loops iterate once per-frame, their execution frequency is tied to the frame rate of a movie.
- Our code examples so far say, "With each frame that passes, move ball 10 pixels to the right":
ball._x += 10;
- Hence, an increase in frame rate would mean an increase in the speed of our animation.
- The more frames that are rendered per second, the more often ball is repositioned, and the faster it appears to move.
- It may be tempting to calculate the distance to move in relation to the movie's frame rate.
- For example, suppose:
- We want an object to move at 100 pixels per second
- Our movie's frame rate is 20 fps
- We set the amount to move the object to 5 pixels per frame:
100 pixels per second / 20 frames per second = 5 pixels per frame
- This approach has two serious flaws:
- If we change the frame rate, we have to recalculate our speed and edit our code accordingly.
- If the computer running the movie can not render frames fast enough to keep up with the designated frame rate, the movie slows down, meaning the object would no longer move at 100 pixels per second.
- To ensure that programmatically animated objects move at the same speed on any system, we calculate the distance to move relative to time, not frame rate.
- Let's take a look at a finished system (
timeScaledMotion.fla) that scales motion to time.
- Our program is broken into two functions,
init() and moveClip():
function init () {
attachMovie("processMoveBall", "processMoveBall", 5000);
distancePerSecond = 100;
now = getTimer();
}
function moveClip (theClip) {
then = now;
now = getTimer();
elapsed = now - then;
numSeconds = elapsed / 1000;
moveAmount = distancePerSecond * numSeconds;
theClip._x += moveAmount;
}
- The
init() function starts our clip moving.
- It attaches the
processMoveBall clip which calls the moveClip() function every frame.
init() also establishes two variables:
distancePerSecond (the number of pixels our object should move per second)
now (the current time)
- We call
init() from our start button:
on(release) {
init();
}
- The
moveClip() function moves our ball.
- Each time
moveClip() is called, it:
- Determines how much time has passed.
- Calculates how far to move the object based on the elapsed time.
- Moves the object.
- The
moveClip() function takes one parameter: a reference to the clip to move:
function moveClip (theClip) {
- Inside
moveClip, we record the last time a frame was rendered:
then = now;
- Next we assign the current time to the variable
now:
now = getTimer();
- Then we calculate the amount of time that passed between the last frame rendered and this frame:
elapsed = now - then;
- So far,
elapsed is measured in milliseconds. We now convert it to seconds:
numSeconds = elapsed / 1000;
- Now that we know how much time has passed, in seconds, since the last frame was rendered, we calculate how far to move.
- We multiply the amount to move per second by the number of seconds that have passed:
moveAmount = distancePerSecond * numSeconds;
- For example, if we're moving our object at 100 pixels per second, and it's been .14 seconds since the last frame was rendered, then:
moveAmount = 100 * .14;
moveAmount = 14;
So we move the object 14 pixels this frame.
- Finally, we move the object:
theClip._x += moveAmount;
- The
moveClip() function is called by the enterFrame handler of the eventLoop clip:
onClipEvent (enterFrame) {
_root.moveClip(_root.ball);
}
- Why scale motion to time?
- We can set the frame rate to anything we like without affecting the behaviour of the system.
- By setting the frame rate to, say, 100, we produce a silky smooth animation effect on fast computers.
- On slower computers the animation will be choppier, but objects will still move at the correct speed (very important for games).