Using getBytesLoaded() and getBytesTotal()


With the introduction of the Movie Clip object in Flash 5 came some new methods , notably getBytesLoaded() and getBytesTotal(). For the first time, you can accurately determine how much of your movie has downloaded. If you're going to be building preloaders in Flash, you want to get to know these methods well:

  • getBytesLoaded(). The total number of bytes that have currently loaded. The syntax is movieclip.getBytesLoaded().

  • getBytesTotal(). The total number of bytes for the entire movie, including all movie clips. The syntax is movieclip.getBytesTotal().

The formula you need to determine the number of bytes that have loaded is very similar to what you looked at for _framesloaded and _totalframes. However, because you know how many bytes of information you're dealing with, you can actually take it a step further and calculate the percentage of bytes loaded:

 movieclip.getBytesLoaded()/movieclip.getBytesTotal() * 100 

As in the _framesloaded example, when you divide getBytesLoaded() by getBytesTotal(), you get a number between 0 and 1. By multiplying this number by 100, you get the total percent loaded.

In it's simplest form, using these methods can involve nothing more than attaching a couple actions to a basic movie clip. You know that you're going to need to continually check the status of the download. The most efficient way to do that is to use the onClipEvent() method with an enterFrame argument. You can set up a conditional statement inside the onClipEvent() to test for the value in which you're interested. When the condition is satisfied, you just tell the main timeline to jump to the appropriate frame. That's the approach you'll take for the first exercise.

Exercise 16.1 Using getBytesLoaded() and getBytesTotal() to Create a Simple Preload Sequence

The file for this exercise has already been started for you. This file consists of three layers , each with two frames :

  • Actions. Frame 1 contains a stop() action.

  • Preload. Contains the movie clip in frame 1 that will be used as a preloader. Frame 2 is a blank keyframe.

  • FigIntro. Contains a blank keyframe in frame 1. Frame 2 contains a movie clip of the Fig Leaf Web site introductory movie.

    All your actions are going to be attached to the movie clip in frame 1 of the Preload layer. You want this movie to continue to play until all the bytes for the entire movie are loaded; then, the movie should advance to the next frame.

  1. Open bytes_preload_1.fla from the Chapter_16/Assets folder on the CD. Save it to your hard drive.

  2. Select the FigIntro movie clip in the Preload layer and launch the Actions panel.

  3. All you need to get this to work is one clip event and an if statement. Start by setting up the shell for the clip event. Enter the following code:

     onClipEvent(enterFrame) { } 
  4. On the blank line between the curly braces, you need a simple if statement. If getBytesLoaded() divided by getBytesTotal() is equivalent to 1, tell the main timeline to go to the next frame and stop. The code you need is this:

     if (_root.getBytesLoaded()/_root.getBytesTotal() == 1) {     _root.gotoAndStop(2);  } 

    It almost seems silly to show the complete code for this, because it's so simple, but as a precaution, Listing 16.1 shows the completed code.

  5. Save and test your movie. Make sure the Bandwidth Profiler is turned on (View > Bandwidth Profiler). Set the modem speed at which you want to test (Debug > 56 K) and set the View to Show Streaming (see Figure 16.1). A completed version of this file is available in the Chapter_16/Assets folder as bytes_preload_1_final.fla.

    Figure 16.1. When you test your movie, you can display the Bandwidth Profiler and show the movie as it would stream over a particular connection. In this case, only 36 percent of the movie has loaded, so the loading sequence is still displaying.

    graphics/16fig01.gif

Listing 16.1 The Completed Code Attached to the Preload Movie Clip
 onClipEvent(enterFrame) {     if (_root.getBytesLoaded()/_root.getBytesTotal() == 1) {         _root.gotoAndStop(2);      }  } 

I don't know about you, but I don't like loading pages that don't give me any idea of how long I'm going to have to wait. I mean really, with some sites you have enough time to go out and wash the car before they complete their loading sequence. Wouldn't it be nice to know that upfront so that you could do something worthwhile while you wait, instead of staring at the monitor and growing frustrated? Let your users know whether they have time to make a quick phone call or time to wash the car. You know you can get at the total percent loaded. Why not show that to your user ? A classic way to do this is to use a loading bar that scales according to the percentage of bytes loaded.

Adding a Percent Loading Bar

Taking your preloader to the next level is not very difficult at all. You already know how to set up the calculation to determine the percent loaded:

 getBytesLoaded()/getBytesTotal() * 100 

You can save that value to a variable and use the variable to dynamically scale a preload bar. The trickiest part of this whole exercise is setting up the preload bar.

So what do you need to get going here?

  • A horizontal bar that you can scale

  • A border around the bar that is constant so that you can see the load progress

Because you're going to be scaling the horizontal bar and not the border, the horizontal bar needs to be a separate movie clip. The way you set up the bar is important. You'll want the bar to load with the _xscale property set to 0. For that to work properly, without a lot of unnecessary code, you need to make sure that the Registration point for the bar is on the left side of the bar. For neatness sake, use the upper-left corner for the Registration point. If you decide to align the movie clips with the Registration points at the center, the loading bar still scales; however, it scales from the center outward.

You'll give this a try in the next two exercises.

Exercise 16.2 Creating a Dynamically Scaling Loading Bar

As in the previous exercise, this file has already been started for you. You actually build the preloader for this one.

  1. Open bytes_preload_2.fla from the Chapter_16/Assets folder on the CD. Save it to your hard drive.

    This file has a very similar setup to the file used in the last exercise. The only difference is that there is no preload movie in the Preload layer. You're going to have to build that.

  2. You already know that your preloader is going to be a movie clip, so you might as well start building it that way. Choose Insert > New Symbol. Name your symbol loading bar.

  3. Give layer 1 a name of bar.

  4. Drag a copy of the bar movie clip from the Library onto frame 1 of the bar layer and give it an instance name (Window > Panels > Instance) of bar so that you'll be able to address it using dot syntax.

  5. Position the movie clip so that the Registration point on the Stage lines up with the upper-left corner of the movie clip.

  6. You need an outline so that you can gauge the bar's progress. However, the bar needs to scale independently of the outline, so add a new layer to the top of the stack and name it border.

  7. To create the border, select the Rectangle tool. Set Fill to No Fill and set Stroke to be a black hairline . Draw a rectangle on the Stage and use the Info panel to set the Width to 200 and the Height to 10.

  8. Position the border over the bar movie clip. (See Figure 16.2.)

    Figure 16.2. Position the loading bar movie clip and the border so that their upper-left corners align with the Registration point on the Stage.

    graphics/16fig02.gif

  9. Return to the main timeline and drag a copy of the loading bar movie clip from the Library onto the first frame of the Preload layer.

  10. Assign the loading bar an instance name (Panels > Instance) of loadingBar.

That was a fair amount of work, and you haven't even started coding yet.

Exercise 16.3 Adding ActionScript to Your Loading Bar

Fortunately, the coding is a piece of cake. This time you need to attach code in two placesto the loading bar movie clip and to the instance of the bar movie clip inside the loading bar movie clip. When your movie first loads, the _xscale for the bar movie clip should be set to 0 because nothing has loaded yet.

  1. You still should be working in bytes_preload_2.fla. Double-click the loading bar movie clip to open it in Symbol-Editing mode. Select the bar movie clip, launch the Actions panel, and add the following code:

     onClipEvent(load){     this._xscale = 0;  } 

    The rest of the code is attached to the loading bar movie clip. Just as in the previous exercise, all the activity will take place inside an onClipEvent().

  2. On the main timeline, select the loading bar movie clip and launch the Actions panel. Set up the shell for your onClipEvent() with this code:

     onClipEvent(enterFrame){ } 
  3. This time, instead of just checking whether getBytesLoaded/getBytesTotal is equivalent to 1, you want to capture the current value in a variable named percent. Between the curly braces, add the following code:

     percent = _root.getBytesLoaded() / _root.getBytesTotal(); 
  4. Based on the value of the variable percent (which will be between 0 and 1), you set the _xscale property for the bar movie clip. Add a new blank line after the line you just added and enter the following code:

     _root.loadingBar.bar._xscale = percent*100; 
  5. All you need to do now is add a conditional statement to check whether percent is equivalent to 1. If it is, you want to make the loading bar invisible and you want the main timeline to advance to frame 2. After the last line you entered (but still inside the curly braces), add the following code:

     if (percent == 1){     _root.loadingBar._visible = false;      _root.gotoAndStop(2);  } 
  6. Save and test your movie. Make sure you choose Show Streaming from View so that you can watch the preloading sequence. If you're having any problems, check the code in Listing .

Listing 16.2 The Final Code That Is Attached to the loadingBar Movie Clip
 onClipEvent(enterFrame){     percent = _root.getBytesLoaded() / _root.getBytesTotal();      _root.loadingBar.bar._xscale = percent*100;      if (percent == 1){         _root.loadingBar._visible = false;          _root.gotoAndStop(2);      }  } 

Now that your percent preloader is working, you can take this concept a step further. Why not show your user how much time is left until the file finishes downloading?

Showing Remaining Download Time

You can use what you already know and throw in a couple of Flash's built-in functions to give your user even more information about the file download. How about showing the percent loaded as a number, the rate at which the file is downloading (in bytes per second), and an estimate of how much time is left before the download is complete?

Before you try to code this, you need to think through the necessary calculations. You'll output the values in dynamic text boxes. That means you're going to need three variables to hold the output of your calculations:

  • percent_loaded. You already know how to do this; it's just getBytesLoaded()/getBytesTotal() * 100.

  • bytes_per_second. This calculation introduces another of Flash's built-in functionsgetTimer(). This function returns the time, in milliseconds , that has elapsed since the movie started. To convert the time to seconds, you just need to divide by 1000. To determine the file's download rate in bits per second, divide the number of bytes that have loaded by the value (which, in turn , is divided by 1000) returned from the getTimer() function. In other words, use this formula: getBytesLoaded()/(getTimer()/1000).

  • time_left. For this simple calculation, subtract the bytes that have currently loaded (getBytesLoaded) from the total number of bytes (getBytesTotal). Divide that number by the previous variable (bytes_per_second) to determine the time left in seconds. You'll get a little creative and use the Math object to help you format the output in minutes and seconds.

Now that you know what calculations you need to set up a timer, it's time to give it a try. The next exercise walks you through the process. You'll start by setting up text fields to display your variables on the Stage; then, you'll add Actions to the loading bar movie clip to perform the calculations.

Exercise 16.4 Setting Up the Display for Your Timer

Creating a timer with your preloader just builds on what you already know how to do. The only major difference is that this time you'll place some dynamic text fields inside the loading bar movie clip to display the values of your variables.

  1. Open the bytes_preload_3.fla file in the Chapter_16/Assets folder and save it to your hard drive.

    This file is currently the same as the final product of your last exercise, but the actions attached to the loading bar movie clip have been removed. The Actions for the bar movie clip still are in place.

  2. Double-click the loading bar movie clip to open it in Symbol-Editing mode.

  3. You'll be adding three lines of static text along with three dynamic text fields just beneath the bar movie clip. Select the Text tool, open the Character panel, and change the following settings:

    Font: Arial or Helvetica

    Size : 12

    Color: Black

    Make sure that the Text type on the Text Options panel is set to Static.

  4. Add the following three lines of text to the Stage (see Figure 16.3 for positioning):

    Percent Loaded:

    Bytes per Second:

    Remaining Time:

  5. Select the Text Options panel and change the following settings:

    Text Type: Dynamic Text

    Line Type: Single Line

    HTML, Border/Bg, Selectable: not selected

    Draw three text boxes next to the static text on the Stage.

  6. Each text box needs a unique variable name. From top to bottom, use the Text Options panel to assign the following three variable names :

    percent_loaded

    bytes_per_second

    time_left

  7. Return to the main timeline and save your movie.

Next you'll start adding code to the loading bar movie clip.

Figure 16.3. The static text fields and dynamic text boxes should be aligned below the bar movie clip. Each dynamic text box is assigned its own variable name.

graphics/16fig03.gif

Exercise 16.5 Setting Up the Preloader Calculations

It's always more efficient to use local variables than to make multiple function calls; it also saves on final file size. So the next thing you need to do is set up some local variables to hold the values of the different functions you'll need to call. As in the previous exercises, the code for the timer is wrapped inside an onClipEvent(). You already know that you'll be making calls to getBytesLoaded(), getBytesTotal(), and getTimer() functions. You'll begin this exercise by setting up the onClipEvent() shell and the local variables to hold the values returned by the functions.

  1. Select the loading bar movie clip on the Stage, launch the Actions panel, and enter the following code:

     onClipEvent(enterFrame){ //load function values to local variables      bytesLoaded = _root.getBytesLoaded();      bytesTotal = _root.getBytesTotal();      timer = getTimer();  } 

    This should be a familiar process for you; the only thing that is different is passing the values returned by the functions into local variables.

  2. Take care of the easy part first. You already know how to set up the calculation for figuring out the percent loaded. You also already know how to scale the bar movie clip. This time, however, you use variables instead of functions. To return an even number, you use the rounding function of the Math object. Add a new line between the last line of code and the curly brace , and enter the following code:

     //      percent = bytesLoaded/bytesTotal;      _root.loadingBar.bar._xscale = percent*100;  //calculate and format percent loaded      percent_loaded = Math.round(percent*100) 
  3. Save and test your movie.

    So far, the only text box with a value should be the one next to Percent Loaded.

  4. Next you want to calculate the approximate download rate. The getTimer() function that you used to get the value for the timer variable returns milliseconds. To change that value to seconds, you need to divide it by 1000. Add the following code before the last curly brace:

     //calculate and format download rate      bytes_per_second = Math.round(bytesLoaded/(timer/1000)); 
  5. Save and test your movie.

    Now the top two text boxes should display values. The last set of calculations is significantly more complex than the previous two. The calculation to get the number seconds left to download isn't that bad. It's converting the value into a more readable minutes and seconds format that's a bit of a stretch.

  6. Start with the easy part. Enter the code to calculate the number of seconds left before the last curly brace:

     //calculate and format remaining time to download      seconds_left = (bytesTotal - bytesLoaded)/bytes_per_second; 
  7. Now for the slightly tricky part. Getting at the number of minutes isn't too bad; you just need to divide the number of seconds left by 60. You want to eliminate the leftover fraction. You want only the number of minutes, and you don't want to round the number. To do this, you use the Math.floor() function. This function returns the floor, or closest integer less than or equal to the returned value. Add the following to your code:

     //format time in mm:ss      minutes = math.floor(seconds_left/60); 
  8. Because you're going to be displaying the minutes and seconds in MM:SS format, you need to check whether the number of minutes is less than 10. If so, you need to add a leading 0. Enter the following code:

     if (number(minutes) < 10) {     minutes = "0" + minutes;  } 
  9. Now you need to perform a similar set of calculations to get the number of seconds left minus the number of minutes:

     seconds = Math.round(seconds_left - (minutes*60));  if (number(seconds) < 10) {     seconds = "0" + seconds;  } 
  10. To output the formatted minutes and seconds, you just need to add the following line of code:

     time_left = minutes + ":" + seconds; 
  11. Save and test your movie. Remember to set the View to Show Streaming.

    Your numbers should be whizzing by madly. There's only one thing left to do now: Tell your movie what to do after the file is preloaded. In the next step, you'll do exactly what you've done in the previous exercises.

  12. Enter the following code before the last curly brace (Listing 16.3 shows the completed code):

     //Play movie      if (percent == 1){             _root.loadingBar._visible = false;              _root.gotoAndStop(2);      } 
Listing 16.3 The Completed Code That Is Attached to the Loading Bar Movie Clip
 onClipEvent(enterFrame){ //load function values to local variables      bytesLoaded = _root.getBytesLoaded();      bytesTotal = _root.getBytesTotal();      timer = getTimer();  //      percent = bytesLoaded/bytesTotal;      _root.loadingBar.bar._xscale = percent*100;  //calculate and format percent loaded      percent_loaded = Math.round(percent*100)  //calculate and format download rate      bytes_per_second = Math.round(bytesLoaded/(timer/1000));  //calculate and format remaining time to download      seconds_left = (bytesTotal - bytesLoaded)/bytes_per_second;  //format time in mm:ss      minutes = math.floor(seconds_left/60);      if (number(minutes) < 10) {         minutes = "0" + minutes;      }      seconds = Math.round(seconds_left - (minutes*60));      if (number(seconds) < 10) {         seconds = "0" + seconds;      }      time_left = minutes + ":" + seconds;  //Play movie      if (percent == 1){             _root.loadingBar._visible = false;              _root.gotoAndStop(2);      }  } 

So far you've been working with self-contained movies. What happens if you've split a large movie into several smaller movies? Chances are that you're still going to want to make sure that the smaller movies have at least partially loaded before playing. But how can you use the getBytesLoaded() and getBytesTotal() methods with external movies?

Determining the Percent Loaded for External Movies

Figuring out the percent loaded for an external movie isn't difficult; the procedure just isn't intuitively obvious. To get the bytes loaded for an external movie, you actually need to load the movie into an existing movie clipan empty clip that acts as a container.

Before any of this will work, however, you need to create a new blank movie clip and assign it an instance name. After you've done that, you'll have someplace to load your movie. Before you begin to load your movie, you need to check the size of the container movie clip; even if it is empty, it still takes up a few bytes of space. After you've done that, you can go ahead and load your movie and begin testing.

Exercise 16.6 Preloading an External File

This time, you need to move two files to your hard drive: the Flash movie you're building and the existing external file you'll be loading.

  1. Copy external_preload.fla and music.swf from the Chapter_16/Assets folder and save them to the same directory on your hard drive.

  2. Open external_preload.fla. Create a new movie clip named container.

  3. Select frame 1 of the loader layer and drag a copy of the container movie clip from the Library onto the Stage. Give it an instance name (Window > Panels > Instance) of container. (See Figure 16.4.)

    Figure 16.4. The preloader and the container movie clip on the Stage.

    graphics/16fig04.gif

  4. Select frame 1 of the actions layer, add the code to check the base size of the container movie clip, and then load the external movie:

     baseSize = container.getBytesTotal();  container.loadMovie("music.swf"); 
  5. Select the container movie clip on the Stage and launch the Actions panel.

    The code this time is going to be a little different, but not much, from what you entered earlier. Notice that this movie is only one frame long. In all the previous movies, there were at least two frames, and there was always a blank keyframe right after the frame with the preloader. There actually was a good reason for that. You've been using onClipEvent(enterFrame) to continuously monitor the status of your files. That event continues to fire until it's removed from the time-line. That's effectively what you were doing with the blank keyframe. When the movie advanced to frame 2, you removed the preloader from your active time-line. With a one-frame movie, that has to be handled a little differently. When you initially load your container movie clip, you'll create a variable called loading and set it to true. Then, whenever you enter the onClipEvent(enterFrame), you'll check whether that value is true. It's true only as long as the value in the variable percent is less than 100. If it is still true, you'll process the rest of the code. If the value of percent evaluates to 100, loading is set to false and you'll immediately drop out of the loop. That's going to save you a lot of processing time.

  6. Except for handling the loading variable, the rest of the code should be old news to you. Instead of doing this step-by-step, you'll enter all the code at one time:

     onClipEvent(load){     loading = true;  }  onClipEvent(enterFrame){     if (loading){         if (this.getBytesTotal() > _root.baseSize){             percent = this.getBytesLoaded()/this.getBytesTotal() *              100;              trace(percent);              _root.loadingBar.bar._xscale = percent;              if (percent == 100){                 loading = false;                  _root.loadingBar._visible = false;                  this.nextFrame();              }          }      }  } 
  7. Save and test your movie.

You can see that except for the if (loading) conditional and except for setting loading to false after the movie is completely loaded, this is exactly what you've done before.

Alternately, you could load the external movie into a level rather than into a container movie clip. To do so, you change the loadMovie in the first frame to the following:

 loadMovieNum("music.swf", 1); 

Then, you change the code on the loading bar to the following:

 onClipEvent(load){     loading = true;  }  onClipEvent(enterFrame){     if (loading){         if (_level1.getBytesTotal() > _root.baseSize){             percent = _level1.getBytesLoaded()/_level1.getBytesTotal() *              100;              trace(percent);              _root.loadingBar.bar._xscale = percent;              if (percent == 100){                 loading = false;                  _root.loadingBar._visible = false;                  _level1.nextFrame();              }          }      }  } 

In the next section, you'll look at an entirely different approach to using preloaders. In this case, you'll use a game to distract the user while your main movie downloads. Pretty sneaky, huh? Just don't make the game too much fun; they might never get to your movie!



Inside Flash
Inside Flash MX (2nd Edition) (Inside (New Riders))
ISBN: 0735712549
EAN: 2147483647
Year: 2005
Pages: 257
Authors: Jody Keating

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net