My favorites | Sign in
Project Home Downloads Wiki Issues Source
Project Information
Members
Links

AssetLoader v 2.8

Russell Lowke, June 26th 2011.
for use with ActionScript 3



The AssetLoader is designed to allow you to easily bulk load assets from external files. In particular, it easily and conveniently supplies you with a single reference to your external asset. Clearing that reference generally will release the asset from memory (see note below). This tidies up the mess of event listeners and object references usually associated with the Flash Loader that makes bulk loading of external assets, and clearing of those assets, tedious.

AssetLoader simplifies the loading process, allowing you to load multiple types of files using one interface. AssetLoader will load the following file types, .xml, .swf, .aif, .mp3, .wav, .bmp, .png, .jpg, .html, .txt, .bin, and .zip. AssetLoader will also load a class or class definition out of a specific .swf file.
Note: Flash DisplayObject assets can be unusually stubborn to unload, particularly if the asset is a MovieClip that has children that are playing or if there is a hard EventListener attached to it. You should stop all MovieClips and remove all EventListeners on an asset before clearing the reference. As of Flash Player 10 you can dispose of stubborn DisplayObject assets using the Flash Player 10 unloadAndStop() method on the asset's Flash Loader, which can be accessed through loaderInfo.loader, like so,

    displayObjectAsset.loaderInfo.loader.unloadAndStop();


Zip file functionality utilizes FZip package by Claus Wahlers and Max Herkender, see assetLoader/deng/fzip. Zip files to be read might first need be prepared using assetLoader/deng/tools/python/fzip-prepare.py. Uncompressed .zip files, such as those containing .png files (which are already compressed), do not need to be prepared using fzip-prepare.py.


Note: You might need to set permissions for local file access from the Flash Global Security Settings panel, see,
http://www.macromedia.com/support/documentation/en/flashplayer/help/ and select "Global Security Settings Panel"


Usage,

AssetLoader is a singleton, a reference to it is obtained through AssetLoader.instance. See the AssetLoaderExample project for an example of how to use AssetLoader.

As AssetLoader is a singleton it should never be instantiated directly. Use AssetLoader.instance to obtain a reference to the AssetLoader,

    var ldr:AssetLoader = AssetLoader.instance;




1) LOADING AN EXTERNAL FILE

The most common usage is to load a specific file, such as a .jpg, .snd, .swf, or .xml. Use the loadFile() method to do this, for example,

    AssetLoader.instance.loadFile("config.xml", gotXML);

Where the 1st parameter is the path to the file asset, and the second parameter is a Function that will receive the asset once loaded. In this example we are loading an external config.xml file, once loaded, the XML data is passed as the 1st argument to a custom function gotXML().
Your gotXML() function might look something like this,

    private function gotXML(cfg:XML):void {
        trace("XML CONFIG:" + cfg);
    }

Notice that the 1st parameter of gotXML() receives class type XML. If you are loading a '.mp3' the class type would be Sound,

    private function gotSound(snd:Sound):void { ...

If you are loading a '.jpg' the class type would be Bitmap,

    private function gotBitmap(bmp:Bitmap):void { ...

The AssetLoader loadFile() method uses the file type suffix (such as ".mp3") to identify the type of file being loaded. It recognises the following file types:

/*
    SUFFIX              CLASS               FILE TYPE
    ".xml"              XML                 Extensible Markup Language
    ".swf"              Sprite/MovieClip*   Shockwave Flash     
    ".zip"              Object**            Data compression and archive format
    ".bmp"              Bitmap              Bitmap image file format            
    ".png"              Bitmap              Portable Network Graphics       
    ".jpg", or ".jpeg"  Bitmap              Joint Photographic Experts Group
    ".aif", or ".aiff"  Sound               Audio Interchange File Format   
    ".mp3"              Sound               MPEG-1 Audio Layer 3
    ".wav"              Sound               Waveform Audio Format               
    ".bin"              ByteArray           Binary data
    ".txt"              String              Text
    ".html"             String              Hypertext Markup Language
    ".var" or ".vars"   URLVariables        Url variables

* .swf files should be typecast as Sprite, if a single frame, or as MovieClip,
if multiple frames.

** .zip files will return a library Object with the contents of the zip keyed to file names in the zip.
Zipped files may contain ".bmp", ".png", ".jpg", ".jpeg", ".gif", ".swf" and ".xml" content.

*/



2) FAILED ASSETS

If an asset fails to load the callback function will still be called, only the asset being passed to it will be returned as null. The gotXML() example from above would look like the following if also checking for a failed load,

      private function gotXML(cfg:XML):void {
          if (! cfg) {
              trace("XML failed to load");
          } else {
              trace("XML CONFIG:" + cfg);
          }
      }

The AssetLoader will log a "WARNING" message informing you that the file didn't load, this warning message would look like so,

    WARNING #1002: AssetLoader IOError, usually caused by file not found.
    Error #2035: URL Not Found. URL: file:///Users/russ/Workspace/AssetLoaderExample/bin-debug/config.xml




3) BULK LOADING ASSETS

You may bulk load a series of assets, listening for the AssetLoader to finish loading them by listening for the BatchCompleteEvent.BATCH_COMPLETE event,

    public function BulkLoadingExample() {
        var ldr:AssetLoader = AssetLoader.instance;
        ldr.addEventListener(BatchCompleteEvent.BATCH_COMPLETE, ready);
        ldr.loadFile("config.xml", gotAsset);
        ldr.loadFile("myGraphic.jpg", gotAsset);
        ldr.loadFile("mySound.mp3", gotAsset);
    }
    
    private function gotAsset(asset:*):void {
        trace("Asset arrived:" + asset);
    }

    private function ready(evt:Event = null):void {
        AssetLoader.instance.removeEventListener(BatchCompleteEvent.BATCH_COMPLETE, ready);
        trace("Your assets have all loaded.");
    }

Don't forget to remove your BatchCompleteEvent.BATCH_COMPLETE listener once your assets have arrived.

ALTERNATIVELY (and perhaps preferably), you may use the whenDone() method instead of listening for the BatchCompleteEvent.BATCH_COMPLETE event, in which case the above example would look like so,

    public function BulkLoadingExample() {
        var ldr:AssetLoader = AssetLoader.instance;
        ldr.loadFile("config.xml", gotAsset);
        ldr.loadFile("myGraphic.jpg", gotAsset);
        ldr.loadFile("mySound.mp3", gotAsset);
        ldr.whenDone(ready);
    }
    
    private function gotAsset(asset:*):void {
        trace("Asset arrived:" + asset);
    }

    private function ready():void {
        trace("Your assets have all loaded.");
    }

whenDone() listens for the BatchCompleteEvent.BATCH_COMPLETE event for you, triggering your callback function when the event fires. It's not necessary to remove any listeners, and whenDone() also accepts additional arguments to be passed to your callback function. Multiple consecutive whenDone() callbacks may be set.

If the AssetLoader is idle with no loads running when whenDone() is called then the whenDone() function callback will be called on the next frame, when Flash sends a general Event.ENTER_FRAME.

See 10) EXAMPLE: USING A GENERIC ASSIGN FUNCTION, for ways of assigning assets as they bulk load.


4) LOADING AN EXTERNAL CLASS

You may load a Class asset out of a specific .swf file and send it to a function once it has loaded using loadClass().

This is achieved like so,

    AssetLoader.instance.loadClass("assest.swf", "ClassName", gotAsset);

    private function gotAsset(asset:*):void {
        trace("Asset arrived:" + asset);
    }

Where the 1st parameter is the path to the .swf file, the 2nd parameter is the name of the class being loaded from the .swf, and the 3rd parameter is the function that will receive the class instance once loaded. With loadClass() a new instance of the class is given.


5) LOADING AN EXTERNAL CLASS DEFINITION

If you want the class definition you should use loadClassDefinition(), where the parameters are the same as for loadClass(), except the actual class definition is returned to the function and you will need to make your own instance from it using new, for example,

    AssetLoader.instance.loadClassDefinition("assest.swf", "ClassName", gotClass);

    private function gotClass(myClass:Class):void {
        // your Class has loaded
        var asset:* = new myClass();
        trace("Asset arrived:" + asset);
    }




6) STOPPING AN ASSET FROM LOADING

To stop an asset from loading simply call close(), passing it the path to the asset being loaded.

    AssetLoader.instance.close("asset.swf");




7) GETTING LOAD PROGRESS

To get the progress of the AssetLoader while loading assets use,

    import com.lowke.assetLoader.events.ProgressEvent;
    AssetLoader.instance.addEventListener(ProgressEvent.PROGRESS, printProgress);

    public function printProgress(evt:ProgressEvent):void {
        trace("Percent loaded:" + Math.round(evt.percentDone*100) + "%");
    }

Load progress can also be found by querying the AssetLoader directly,

    var percentDone:Number = AssetLoader.instance.percentDone;




8) SUPPRESSING LOAD PROGRESS

You can suppress progress information given by a particular load by setting the showProgress parameter on that load's loader instance to false,

    AssetLoader.instance.loadFile("myGraphic.jpg", gotGraphic).showProgress = false;

This can be useful if you're displaying a progress bar that listens to the load progress, and don't want the progress bar to appear for a particular load.




9) PASSING ADDITIONAL ARGUMENTS

You may pass additional arguments into loadFile(), loadClass(), loadClassDefinition(), and addSwf(). These additional arguments are duly passed to any receiving function once the asset is loaded, e.g.

    AssetLoader.instance.loadFile("config.xml", gotXML, "A", 1);

    private function gotXML(cfg:XML, arg0:String, arg1:Number):void {
        trace("print XML CONFIG:" + cfg);
        trace("print arg0:" + arg0);    "print arg0: A"
        trace("print arg1:" + arg1);    "print arg1: 1"
    }

The usefulness of additional arguments becomes more apparent in section 10) EXAMPLE: USING A GENERIC ASSIGN FUNCTION


10) EXAMPLE: USING A GENERIC ASSIGN FUNCTION

The additional arguments in methods such as loadFile() and loadClass() may be used to pass a variable name to assign the asset to when it arrives. The asset can be assigned using a generic assign() function which uses associative syntax to assign the assets on arrival, such as,

      private var _config:XML;                // XML
      private var _click:Sound;               // Sound

      AssetLoader.instance.loadFile("config.xml", assign, "_config");
      AssetLoader.instance.loadFile("click.mp3", assign, "_click");

      // generic assign()
      private function assign(asset:*, variableName:String):void {
          
          if (! asset) {
              // asset failed to load!
              throw new Error("Asset for " + variableName + " failed to load.");
          }
          
          // use associative syntax to assign asset to member variable
          this[variableName] = asset;
      }

Where the assign() function will set the variable config to the config.xml data when it arrives, and click to the click.mp3 sound when it arrives. This is an unconventional but simple and powerful way of assigning assets as they arrive.

Here is an example Flex ActionScript project called AssetLoaderExample that uses a generic assign() function to bulk load multiple files and classes.

//
//  Note: You might need to set permissions for local file access from the 
//  Flash Global Security Settings panel, see,
//      http://www.macromedia.com/support/documentation/en/flashplayer/help/
//      and select "Global Security Settings Panel"
//

package {
	
	import com.lowke.alert.Alert;
	import com.lowke.assetLoader.AssetLoader;
	import com.lowke.assetLoader.events.ProgressEvent;
	import com.lowke.logAs.LogAs;
	import com.lowke.logAs.events.LogAsEvent;
	
	import flash.display.Bitmap;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.media.Sound;
	
	[SWF(width="640", height="480", backgroundColor="#000000", frameRate="30")]
	public class AssetLoaderExample extends Sprite {
		
		private var _config:XML;				// XML
		private var _background:Bitmap;		// background Bitmap
		private var _sprite:Sprite;				// Sprite from .swf
		private var _ship:MovieClip;			// MovieClip from .swf
		private var _ufoClass:Class;			// Class definition from .swf
		private var _click:Sound;				// sounds
		private var _whistle:Sound;
		
		public function AssetLoaderExample() {
			
			LogAs.addEventListener(LogAsEvent.LOG_AS_EVENT, handleLogs);

			var ldr:AssetLoader = AssetLoader.instance;
			ldr.addEventListener(ProgressEvent.PROGRESS, printProgress);
			ldr.loadFile("config.xml", assign, "_config");
			ldr.loadFile("assets/Blue-Planet-Earth.jpg", assign, "_background");
			ldr.loadClass("assets/text.swf", "PlanetEarth", assign, "_sprite");
			ldr.loadClass("assets/ship.swf", "Ship", assign, "_ship");
			ldr.loadFile("assets/click.mp3", assign, "_click");
			ldr.loadFile("assets/whistle.mp3", assign, "_whistle");
			ldr.loadClassDefinition("assets/ufo.swf", "UFO", assign, "_ufoClass");
			ldr.whenDone(ready);
		}
		
		// generic assign()
		private function assign(asset:*, variableName:String):void {
			
			if (! asset) {
				// asset failed to load!
				throw new Error("Asset for " + variableName + " failed to load.");
			}
			
			// use associative syntax to assign asset to member variable
			this[variableName] = asset;
		}
		
		private function printProgress(evt:ProgressEvent):void {
			if (evt.percentDone > 0) {
				trace("Percent loaded:" + Math.round(evt.percentDone*100) + "%");	
			}
		}
		
		private function handleLogs(evt:LogAsEvent):void {
			Alert.defaultParent = stage;
			var msg:String = evt.toString();
			switch(evt.level) {
				case LogAsEvent.SEVERE:
					// show severe log as error alert
					Alert.error(msg);
					break;
				case LogAsEvent.WARNING:
					// show warning log as warning alert
					Alert.warning(msg);
					break;
				case LogAsEvent.INFO:
					// show info log as info alert
					Alert.info(msg);
					break;
				case LogAsEvent.DEBUG:
					// trace debug logs
					trace(msg);
					break;
			}
		}
		
		private function ready(evt:Event = null):void {

			// rememeber to remove event listeners
			AssetLoader.instance.removeEventListener(ProgressEvent.PROGRESS, printProgress);

			//
			// your assets are loaded and ready
			
			// print the XML
			trace("config XML:" + _config);			
			
			// display the background
			this.addChild(_background);
			
			// center and show "Planet Earth" sprite
			_sprite.x = (this.stage.width - _sprite.width)/2;	
			_sprite.y = 26;
			this.addChild(_sprite);							
			
			// show "Ship" MovieClip
			_ship.x = 100; _ship.y = 100;
			this.addChild(_ship);
			
			// add four to eight UFOs
			var nUFOs:uint = randomInt(4, 8);				
			for (var i:uint = 0; i < nUFOs; ++i) {
				
				// create an asteroid MovieClip from Class definition
				var ufo:MovieClip = new _ufoClass();
				
				// randomly place UFO
				ufo.x = randomInt(ufo.width, this.stage.width - ufo.width);
				ufo.y = randomInt(100, this.stage.height - ufo.height);
				this.addChild(ufo);
			}
			
			// play whistle sound
			_whistle.play();
		}
		
		//
		// generate a random integer from low value to high value
		public static function randomInt(low:int, high:int):int {
			var range:int = (high + 1) - low;
			var rtn:int = Math.floor(Math.random() * range) + low;
		
			return rtn;
		}
	}
}
Powered by Google Project Hosting