I worked out that I needed to control the rate of playback of the loader after I had built one. If the movie had already been loaded, the loader would give an annoying flash before the content appeared on slower machines (tip: always have some outdated boxes in your office for testing). Also, I wanted the loader to play through quickly every time, just for effect, even if the movie had already downloaded and was in the cache.
This requires two things: we need to know if the movie that we are loading has already been downloaded to the user's computer, and if that is the case we need to set a maximum frame rate for playing our loader before restarting the parent movie.
The first bit is easy. Just check to see if the bytes loaded equals the total bytes of the parent movie. If so, we set a flag (I've called it "quickPlay") to true so that we don't have to check every frame. Otherwise we are interested in finding out how much pre-load we need to do, as before. Here's the code for the load event that sits on our loader movie:
Now we need to tweak our enterFrame event handler to support this new condition. Given that we will somehow be playing our loader movie at a maximum speed, we will need a different test when we are playing the loader quickly because all of the bytes will already be loaded. We will do this be seeing if the playhead of our loader has reached the end of its animation. And here's the code for that:
onClipEvent (enterFrame) {
gotoAndStop(loadedIndicatorFrame());
if (quickPlay == true) { //quickly play the anim
if (_currentframe == _totalframes) {
_parent.play();
}
} else { //wait for the preload
if (_parent.getBytesLoaded() >= preLoad) {
_parent.play();
}
}
}
"Now hang on a minute!" I hear you say. "Why don't you set quickPlay to false if have to wait for the movie to load? That's a sloppy bit of coding there!" Well, if we don't set quickPlay to true, when we do the test if (quickPlay == true) quickPlay will evaluate to "undefined" which certainly is not equal to "true", so the code works fine. And we save ourselves some bytes by not writing quickPlay = false; in the else clause in the load event handler.
There's no real point in testing this code now because our loadedIndicatorFrame function will just jump straight to the end. But if you are really keen, you can remove the function entirely to see what happens.
Doing a plain vanilla preview (Ctrl+Enter) now will allow your loader animation to play through once before continuing on with the parent movie. When previewing like this it is just like having already downloaded the entire movie, so this is doing our quickPlay bits of code. When streaming the preview (Ctrl+Enter again), you should see your loader animation loop until you hit the required percentage, then it will continue on playing the parent movie to the end.
Setting a maximum load rate
The last bit of code will limit the number of frames that we can leap in a single bound. All we have to do is keep track of what frame we handed back on our last function call, compare it to where we want to go now, and if it is too much of an advance then we clamp it to a maximum jump.
To achieve this, we will need an extra variable named lastFrame to store the last frame we showed. This is initialised to 1 which is the frame just before our loader animation starts. Here is the final loader code:
Most of the code is the same, but I'll give it a quick run through anyway. Given that our frame rate for the Western Australian Museum project was set to 25 fps, we found that skipping 4 frames at a time gave us enough time to see the loader and still not be annoying if a movie was already downloaded. Just play with the values to get it right for your frame rate.
If we are skipping frames for a movie that has already been downloaded, then we want to fake our bytes loaded text so that it matches the current frame that we are showing. Our loadedText calculations are now based on lastFrame instead of getBytesLoaded.
Preview now (Ctrl+Enter) to see your loader animation play through once in a fast-forward style before continuing on with the parent movie. When streaming the preview, you should see your loader animation tick through according to your bandwidth settings until you hit the required percentage, then it will continue on playing the parent movie to the end.
If you find that you are creating large SWF files (such as for video) you might find that you need to update the Dynamic Text object more frequently than when you advance to the next frame of your loader. The code for this would be:
lastFrame = 1;
function loadedIndicatorFrame() {
var newFrame = int((_parent.getBytesLoaded() / _parent.getBytesTotal()) * 65) + 2;
if (newFrame - lastFrame > 4) { //too far
lastFrame += 4;
loadedText = int(_parent.getBytesTotal() / 1024 * (lastFrame - 2) / 65) + "kb of " + int(_parent.getBytesTotal() / 1024) + "kb";
} else if (newFrame - lastFrame > 0) { //normal move
lastFrame++;
loadedText = int(_parent.getBytesLoaded() / 1024) + "kb of " + int(_parent.getBytesTotal() / 1024) + "kb";
} else { //update the text only
loadedText = int(_parent.getBytesLoaded() / 1024) + "kb of " + int(_parent.getBytesTotal() / 1024) + "kb";
}
return lastFrame;
}
Now would be a good time to save this using Save As... so that you can give your loader a better name (choose "loader" again). It would also be good to get rid of any test images, sounds, and layers from your file. After tidying up the file, check the linkage on your loading movie in the Library for loader.fla by right-clicking on it and selecting the Linkage... option. It should look like this:
Save it, publish it, and were ready to rock and roll.