Using a Preloader for External Assets


In this section, you will learn how to add a preloader that monitors the download progress of any external asset, whether the file format is SWF, JPEG, PNG, GIF, FLV, or MP3. This preloader combines the same methodology employed by the original preloader_f5_100.fla document you built earlier in this chapter. We've already taken the same loader Movie Clip symbol from that exercise and added ActionScript to its timeline. Let's take a quick look at what we've done.

Note 

Later in this chapter, you learn how to use the Preloader component included with Flash 8. In this section, you learn the fundamental building blocks of an asset preloader, from the ground up.

Open the loader_100.fla file located in the ch28 folder of this book's CD-ROM. Open the Library panel and double-click the loaderClip symbol. Inside of this symbol, select frame 1 of the actions layer. Open the Actions panel and you will see the Listing 28-9 code in the Script pane. Note that the image from book character indicates a continuation of the same line of code.

Listing 28-9: The loaderClip Symbol Code

image from book
 var mcBar:MovieClip; var tLabel:TextField; var nCount:Number; var nCheckID:Number; function checkLoad(oTarget:Object, oListener:Object):Void {    var nLB:Number = oTarget instanceof NetStream ? oTarget.bytesLoaded       : oTarget.getBytesLoaded();    var nTB:Number = oTarget instanceof NetStream ? oTarget.bytesLoaded       :oTarget.getBytesTotal();    var nPL:Number = isNaN(nLB) || isNaN(nTB) ? 0 : (nLB/nTB)*100; (nLB/nTB)*100;    mcBar._xscale = nPL;    tLabel.text = Math.floor(nPL)+"% of "+Math.floor(nTB/1024)+" KB loaded.";    if (nLB >= nTB && nTB > 0) {       if (nCount >= 12) {          clearInterval(nCheckID);          oListener.onLoadFinished({target: this});       } else {          nCount++;       }    }    updateAfterEvent(); } nCount = 0; nCheckID = setInterval(this, "checkLoad", 30, target, listener); stop(); 
image from book

Tip 

You can add a check to the value of nTB to prevent a -1 value from being displayed in the tLabel field. For example, the following if() statement makes sure that nTB is greater than -1:

 if(nTB > -1){    tLabel.text = Math.floor(nPL)+"% of   image from book       "+Math.floor(nTB/1024)+" KB loaded."; } 

While this may seem a bit overwhelming, it's nearly identical to the code you built on the Main Timeline of the preloader_100.fla document. The primary differences are as follows:

  • The code is contained within a function named checkLoad().

  • Instead of a frame loop, the new setInterval() function is used to repeatedly execute the checkLoad() function. When the loading is finished, the clearInterval() function is called to stop the looping.

    Note 

    This script uses a specific implementation of the setInterval() function. The function has two syntax formats: setInterval(functionName:Function, interval:Number, optionalArgs); or setInterval(object:Object, objectMethod:String, interval:Number, optionalArgs);. In this example, we use the latter syntax, because there are this references in the checkLoad() function. If you have this references within the checkLoad() function, using the latter syntax helps work out scoping issues with objects within the function.

  • The checkLoad() function accepts two arguments: oTarget and oListener. The function checks the load status of a specified object, oTarget, instead of checking the loaded bytes and total bytes of the current timeline (this or _root) as our earlier example in the chapter used. As such, this clip needs to be passed a target value, as expressed in the setInterval() function. The oListener object works similarly to listener objects of Flash 8 components. When the loading of the oTarget object is finished, the checkLoad() function will invoke the onLoadFinished() method of the oListener object. Like oTarget, oListener must be passed into the loaderClip instance, as expressed in the setInterval() function.

  • The checkLoad() function can also detect the data type of the target (oTarget) it is monitoring. Using the instanceof operator (discussed in Chapter 26, "Using Functions and Arrays") and the ?: conditional operator, the nLB and nTB variables check different properties of the target. NetStream objects have bytesLoaded and bytesTotal properties, while MovieClip and Sound objects have getBytesLoaded() and getBytesTotal() methods.

  • The loaderClip instance is dynamically placed in the movie to monitor the download progress of a specific asset — it does not monitor the load progress of the main movie .swf file.

Tip 

The setInterval() and clearInterval() functions were introduced in Flash Player 6. These actions work only in Flash Player 6 or higher movies.

Note 

The loaderClip symbol is only a few steps away from being a full-fledged ActionScript 2.0 (AS2) component. However, in order to keep the loaderClip symbol flexible enough to monitor everything from individual asset downloads to the main movie's download progress, the symbol must not use any ActionScript 2.0 classes. Why? If the main movie has other AS2 components, you need to defer the classes from loading on frame 1. If the loaderClip symbol became a component, then it wouldn't be available for use on frame 1 of the main movie.

But that's not all of the code you'll need to get an asset preloader working. Even though there is code with a loaderClip symbol that continually checks the loading progress of an asset, you need some code that provides some input for the loaderClip symbol, such as the object (target, as specified in the setInterval() function) in which the file is loading (a MovieClip object, a Sound object, or a NetStream object).

Let's take a look at one more chunk of code. Open the loadFile.as file located in the ch28 folder of this book's CD-ROM. You can use Macromedia Dreamweaver, Flash Professional 8, or any other text editor to view the code. Listing 28-10 displays the code contents of this file. Note that the image from book character indicates a continuation of the same line of code.

Listing 28-10: The loadFile.as Script

image from book
 import mx.utils.Delegate; var snd:Sound; var mcHolder:MovieClip; var mcl:MovieClipLoader; var ns:NetStream; var vWin:Video; var nc:NetConnection = new NetConnection(); nc.connect(null); function loadFile(sUrl:String, sType:String, oProp:Object,image from book    oListener:Object):Void {    if(sType == null || sType == undefined)        var sType:String = sUrl.substr(-3).toLowerCase();    else   sType = sType.toLowerCase();    var mc:MovieClip = mcHolder = createEmptyMovieClip("mcHolder", 1);    if(oProp != null || oProp != undefined){       mc._x = oPosition.x;       mc._y = oPosition.y;       mc._xscale = mc._yscale = oPosition.scale;    }    var oTarget:Object;    switch(sType){       case "swf" :       case "jpg" :       case "gif" :       case "png":       default:          mcl = new MovieClipLoader();          if(oListener != undefined) mcl.addListener(oListener);          mcl.loadClip(sUrl, mc);          oTarget = mc;          break;       case "mp3" :          snd = new Sound(mc);          snd.loadSound(sUrl, true);          oTarget = snd;          break;       case "flv" :          var mcVid:MovieClip = mc.attachMovie("videoClip", "mcVid", 1);          vWin = mcVid.vWin;          ns = new NetStream(nc);          ns.onMetaData = Delegate.create(this, this.onVideoMetaData);          ns.play(sUrl);          mcVid.vWin.attachVideo(ns);          oTarget = ns;          break;    }    var oInit:Object = {_x: 25, _y: Stage.height - 30, target: oTarget. image from book       listener: oListener};    var mcLoader:MovieClip = attachMovie("loaderClip", "mcLoader", 2, oInit);    mcLoader.onResize = function():Void {       this._y = Stage.height - 30;    };    Stage.addListener(mcLoader); } function unloadFile():Void {    if(mcHolder instanceof MovieClip) mcHolder.removeMovieClip();    if(snd instanceof Sound) {       snd.stop();       delete snd;    }    if(ns instanceof NetStream) ns.close(); } function onVideoMetaData(oData:Object):Void {    var nWidth:Number = oData.width;    var nHeight:Number = oData.height;    if(nWidth == 0 || nWidth == undefined ||  isNaN(nWidth)){       vWin._width = vWin.width;       vWin._height = vWin.height;    } else {       vWin._width = nWidth;       vWin._height = nHeight;    }    vWin._visible = true; } 
image from book

The loadFile() function takes a URL specified in the sUrl parameter and loads it into a proper container based on the sType value passed to the function. The sType argument can be any of the following types: swf, jpg, gif, png, mp3, or flv. If the sType parameter is not passed to the function, the loadFile() function checks the last three characters of the sUrl value. The switch() statement loads the URL into an appropriate holder object. If the sType value is "swf", "jpg", "gif", or "png", the function will load the URL into a new Movie Clip instance named mcHolder. If the sType value is "mp3", the function loads the URL into a new Sound object. If the sType value is "flv", the URL is loaded into a NetStream object. The oInit object contains the information that the loaderClip symbol needs to work. The Y position of the mcLoader instance is based on the Stage.height value. The target variable (which is also specified in the checkLoad() function you saw earlier within the loaderClip symbol) is set to either mcHolder, snd, or ns, depending on what type of media file is being loaded. Finally, the attachMovie() method attaches the loaderClip symbol from the movie's library to the Main Timeline (_root), passing it the properties of the oInit object.

The loadFile() function can also use optional arguments, such as oProp and oListener. If oProp is passed to the loadFile() function, the mcHolder instance will be positioned according to the oProp.x and oProp.y property values. You can also specify a scale property on the oProp object. The oListener object is passed to the loaderClip symbol. The oListener object should have an onLoadFinished() method defined, as you'll see later in this section.

Tip 

The ability to pass an oInit object to the attachMovie() method is a feature of Flash Player 6 and higher movies.

Cross-Reference 

The loadFile() function also uses the Delegate class to define the onMetaData() handler of the NetStream instance, ns. The Delegate class enables you to remap the scope of a handler to another object and function. The onVideoMetaData() function uses essentially the same code you used earlier in this chapter to resize a Video object. You learn more about the Delegate class in Chapter 33, "Using Components."

The unloadFile() function deletes the objects created by the loadFile() function. If a mcHolder, snd, or ns instance exists, it will be deleted or removed from the movie.

In the following steps, you combine the loaderClip symbol from the loader_100.fla file with the loadFile.as file that you just examined. You integrate these elements into a new version of the loadSound_100.fla file that you created earlier in this section.

On the CD ROM 

Make a copy of the loader_100.fla, loadFile.as, and loadSound_100.fla files, located in the ch28 folder of this book's CD-ROM.

  1. Open the loadSound_100.fla document. Save this document as preloader_fp8_100.fla.

  2. Choose File ð Import ð Open External Library, and choose the loader_100.fla document.

  3. Drag the loaderClip symbol from the loader_100.fla Library panel to the Stage of the preloader_fp8_100.fla document. All of the symbols associated with the loaderClip symbol will be transferred to the preloader_fp8_100.fla document. Close the loader_100.fla Library panel.

    Note 

    For ease of use, the videoClip symbol that's used by the loadFile.as code is embedded on frame 2 of the loaderClip symbol.

  4. Delete the instance of the loaderClip symbol from the Stage of the preloader_fp8_100.fla document. This symbol is linked in the Library of this document and will be attached to the movie's Stage via ActionScript.

  5. Delete the mcHolder layer in the Main Timeline. You will not need a physical Movie Clip instance on the Stage in which to load assets. The code within the loadFile() function creates a mcHolder instance on the fly.

  6. Select the cbtLoad component instance on the Stage. In the Property inspector's Parameters tab, change the label value to Load Asset.

  7. Select the cbtUnload component instance on the Stage. In the Property inspector's Parameters tab, change the label value to Unload Asset.

  8. Select the Input text field on the Stage and open the Property inspector. Change the instance name of the field to tUrl. At run time, the text that you type into this field will be used by the loadFile() function, which will be executed by the listener of the cbtLoad instance when the button is clicked.

  9. Select frame 1 of the actions layer. Open the Actions panel (F9, or Option+F9 on Mac), and replace the existing code in the Script pane with the following code:

     var cbtLoad:mx.controls.Button; var cbtUnload:mx.controls.Button; var tFile:TextField; #include "loadFile.as" var oLoader:Object = new Object(); oLoader.click = function(oEvent:Object):Void {    var sLabel:String = oEvent.target.label.toLowerCase();    if(sLabel == "load asset"){       loadFile(tFile.text);    } else if (sLabel == "unload asset"){       unloadFile();    } }; cbtLoad.addEventListener("click", oLoader); cbtUnload.addEventListener("click", oLoader); 

    The #include directive fetches the contents of the loadFile.as file when you publish or test the movie (at compile time), and inserts the code into the Flash movie on this keyframe. As with previous examples in this chapter, the label of the clicked button is checked to determine which if/else statement is invoked. If the cbtLoad instance is clicked, the loadFile() function is invoked, passing the text value of the tFile field. If the cbtUnload instance is clicked, the unloadFile() function is invoked.

  10. Save the Flash document, and test it (Ctrl+Enter or z+Return). Type a URL into the Input text field. You can use the following test URL:

    • http://www.flashsupport.com/images/waterfall.png

    Alternatively, you can type the name of a file in the same location as the tested movie on your hard drive. Click the Load Asset button, and the loader instance will appear above the Input Text field, indicating the progress of the file's download. If you received an error while Flash 8 was creating the test .swf file, go back and double-check your code on frame 1 of the actions layer.

  11. If you loaded the .png file listed in the previous step, then you noticed that the image was overlapping the controls of the movie. The loadFile() function can also accept an object that describes where and at what size the loaded asset should appear. Select frame 1 of the actions layer, and open the Actions panel. Change the oLoader.click() handler code to the following code shown in bold. Note that the null value is passed as the sType value, so that you have flexibility with the URL you type into the text field.

     oLoader.click = function(oEvent:Object):Void {    var sLabel:String = oEvent.target.label.toLowerCase();    if(sLabel == "load asset"){       loadFile(tFile.text, null, { x: 10, y: 10, scale: 50});    } else if (sLabel == "unload asset"){       unloadFile();    } }; 

  12. Save the Flash document, and test it. Type the following location into the text field:

    • http://www.flashsupport.com/images/waterfall.png

    and click the Load Asset button. The image should load into the movie, and the loaderClip symbol should appear on the Stage. More importantly, the image is scaled at 50 percent so that it's smaller on the Stage, as shown in Figure 28-23. If you click the Unload Asset button, the image should disappear.

  13. There's one more issue to address with this example: The loaderClip symbol does not remove itself from the movie when the asset has finished loading. In order to remove the loaderClip symbol, you need to set up a listener object with an onLoadFinished() method defined. Since you already have an oLoader listener object, you can define the onLoadFinished() method on the oLoader object. You then need to pass a reference to oLoader to the loadFile() function. Select frame 1 of the actions layer, and open the Actions panel. Modify the oLoader object code with the following bold code. Do not type the image from book character, which indicates the continuation of the same line of code.

    Note 

    If you remember from the code breakdown earlier in this section, when the checkLoad() function within the loaderClip symbol determines that the asset has fully loaded, the onLoadFinished() handler of the listener object is passed an object containing a target property pointing to the loaderClip instance itself.

     var oLoader:Object = new Object(); oLoader.onLoadFinished = function(oEvent:Object):Void {    oEvent.target.removeMovieClip(); }; oLoader.click = function(oEvent:Object):Void {    var sLabel:String = oEvent.target.label.toLowerCase();    if(sLabel == "load asset"){       loadFile(tFile.text, null, { x: 10, y: 10, scale: 50}.image from book         oLoader);    } else if (sLabel == "unload asset"){       unloadFile();    } }; 

  14. Save the document, and test it (Ctrl+Enter or z+Enter). Type the URL listed in Step 12, and click the Load Asset button. If you have a fast Internet connection, the mcLoader instance appears and disappears. If you use a local asset, such as beach.jpg in the text field and click the Load Asset button, the mcLoader instance appears for just an instant. To see the download progress in simulation, choose View ð Simulate Download while you're testing the movie.

image from book
Figure 28-23: The mcLoader instance appears when you click the Load Asset button.

Try a URL for each of the media formats that Flash Player 8 can load dynamically. If a file fails to load, check the same URL in a Web browser.

You now have a complete loading script and loaderClip symbol that you can reuse on your own progress. These custom preloaders add very little weight to your file size — just over 1 KB!

On the CD-ROM 

You can find the completed document, preloader_fp8_100.fla, in the ch28 folder of this book's CD-ROM.




Macromedia Flash 8 Bible
Macromedia Flash8 Bible
ISBN: 0471746762
EAN: 2147483647
Year: 2006
Pages: 395

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