AS3.0 Smooth Loader Class

Just in case anyone else is dabbling with AS3.0 i created a smooth loader class with a preloader yesterday, for loading swf, jpg, gif and png files. To use it all you need to do is create an instance of the class and call it’s loadClip or loadClips method.

loadClip as the name suggests loads a single file (a string of the URL) into a single target clip

and loadClips loads an array of files into an array of targets.

Jimmy

p.s. it’s obviously fairly new and untested so if there are any problems let me know and i’ll sort em.


////////////////////////////////////////////////////
// AS3.0 SmoothLoader v1.0
//
// by James Hay @ [www.vectorjunkie.co.uk](http://www.vectorjunkie.co.uk)
//
// Uasge:
//
// public function loadClip(string, targetSprite) - accepts a single url string and a 
// single target for the clip to load to.
//
// public function loadClips(arrayString, arrayTargetSprite) - accepts and array of strings
// and an array of targets for them to be loaded into. Both arrays must be of the same length;
//
//
////////////////////////////////////////////////////////


package 
{
    import flash.display.Sprite;    
    import flash.display.TextField;
    import flash.display.InteractiveObject;
    import flash.display.Loader;
    import flash.net.URLRequest;
    import flash.events.*
    import flash.util.trace;
    import mx.effects.Tween;

    public class SmoothLoader extends Sprite
    {
        private var _loaderDisplay:LoaderDisplay
        
        private var _loadIndex:uint;
        
        private var _files_array:Array;
        private var _targets_array:Array;
        
        private var _loaderComplete:Boolean;
        private var _loaded:Boolean;
        
        private var _dispatcher:IEventDispatcher
        
        public function SmoothLoader()
        {
            super();
            this.smoothLoaderInit();
        }
        
        private function smoothLoaderInit():Void
        {
            this._files_array = new Array();
            this._targets_array = new Array();
        }
        
        /////////////////////////////////////////////////////
        // Initialises Loader Display
        /////////////////////////////////////////////////////
        private function displayProgress():Void
        {
            this._loaderDisplay = new LoaderDisplay();
            this._loaderDisplay.addEventListener("onLoaderDisplayComplete", onLoaderDisplayCompleteListner);
            this.addChild(this._loaderDisplay);
        }

        /////////////////////////////////////////////////////
        // onLoaderDisplayComplete callback for LoaderDisplay
        /////////////////////////////////////////////////////

        private function onLoaderDisplayCompleteListner(event:Event):Void
        {
            this._loaderComplete = true;
            this.checkComplete();
        }
        
        ///////////////////////////////////////
        // Configure dispacthers for Loader obj
        ///////////////////////////////////////
        
        private function congureListeners():Void
        {
            this._dispatcher.addEventListener(EventType.INIT, onSmoothLoaderInitListner);
            this._dispatcher.addEventListener(ProgressEventType.PROGRESS, onSmoothLoaderProgressListner)
            this._dispatcher.addEventListener(IOErrorEventType.IO_ERROR, onIOErrorListner);
        }
        
        /////////////////////////////////////////
        // Deconfigure dispacthers for Loader obj
        /////////////////////////////////////////
        
        private function deConfigureListeners():Void
        {
            this._dispatcher.removeEventListener(EventType.INIT, onSmoothLoaderInitListner);
            this._dispatcher.removeEventListener(ProgressEventType.PROGRESS, onSmoothLoaderProgressListner)
            this._dispatcher.removeEventListener(IOErrorEventType.IO_ERROR, onIOErrorListner);    
        }
        
        //////////////////////////////////////
        // IO_ERROR callback for Loader
        /////////////////////////////////////
        
        private function onIOErrorListner(event:Event):Void
        {
            trace("An error type " + event.type + " has occured");
        }
        
        //////////////////////////////////////
        // INIT callback for Loader
        /////////////////////////////////////
        
        private function onSmoothLoaderInitListner(event:Event):Void
        {
            this.deConfigureListeners();
            
            if (this._loadIndex == (this._files_array.length-1))
            {
                this._loaded = true;
                this.checkComplete();
            } else {
                this._loadIndex++;
                this.loadNext();
            }
            
        }
        
        //////////////////////////////////////
        // PROGRESS callback for Loader
        /////////////////////////////////////
        
        private function onSmoothLoaderProgressListner(event:ProgressEvent):Void
        {
            var progressPercentComplete:Number = event.bytesLoaded / event.bytesTotal;
            var totalProgressPercentComplete:Number = ((1/this._files_array.length)*this._loadIndex) + (progressPercentComplete/this._files_array.length);
            this._loaderDisplay.update(totalProgressPercentComplete)
        }
        
        ///////////////////////////////////////////////////////////////
        // Checks both loader is complete and total clips have loaded
        //////////////////////////////////////////////////////////////
        private function checkComplete():Void
        {
            if (this._loaderComplete && this._loaded)
            {
                this._loaderDisplay.kill();
                this.removeChild(this._loaderDisplay);
                delete this._loaderDisplay
                this.dispatchEvent(new Event("onLoadComplete", false, false));
            }    
        }
        
        
        //////////////////////////////////////
        // Load next file
        /////////////////////////////////////
        private function loadNext()
        {
            var request:URLRequest = new URLRequest(this._files_array[this._loadIndex]);
            var newLoad:Loader = new Loader
            
            this._dispatcher = newLoad;
            this.congureListeners()
            
            newLoad.load(request);
            
            this._targets_array[this._loadIndex].addChild(newLoad);
        }
        
        //////////////////////////////////////
        // Reset
        /////////////////////////////////////
        private function reset():Void
        {
            this._files_array = [];
            this._targets_array = [];
            this._loaderComplete = false;
            this._loaded = false;
            this._loadIndex = 0;
            
            this.displayProgress();
        }
        
        //////////////////////////////////////
        // Load single clip
        /////////////////////////////////////
        public function loadClip(file:String, target:Sprite):Void
        {
            this.reset();
            
            this._loadIndex = 0;
            
            this._files_array[0] = file;
            this._targets_array[0] = target;
            
            this.loadNext();
        }
        
        //////////////////////////////////////
        // Load multiple clips
        /////////////////////////////////////
        public function loadClips(files:Array, targets:Array):Void
        {
            this.reset();
            
            if (files.length == targets.length)
            {
                this._loadIndex = 0;
                
                this._files_array = files;
                this._targets_array = targets;
                
                this.loadNext();
            } else {
                trace("Number of clips to load must be equal to the number of target clips");    
            }    
        }
        

    }
    
    private class LoaderDisplay extends Sprite
    {
        private var _bar:LoadBar;
        private var _progress:TextField;
        
        private static var BAR_WIDTH:Number = 100;
        private static var BAR_HEIGHT:Number = 5;
        
        public function LoaderDisplay()
        {
            super()
            this.loaderDisplayInit();
        }
        
        private function loaderDisplayInit():Void
        {
            this._bar = new LoadBar(LoaderDisplay.BAR_WIDTH,LoaderDisplay.BAR_HEIGHT);
            this._bar.addEventListener("onTweenBarComplete", onTweenBarComplete);
            this._progress = new TextField();
            this._progress.x = -10;
            
            this.addChild(this._progress);
            this.addChild(this._bar);
        }
        
        //////////////////////////////////////
        // onTweenComplete callback for LoadBar
        /////////////////////////////////////
        private function onTweenBarComplete(event:Event):Void
        {
            this._progress.text = "100 %";
            this.dispatchEvent(new Event("onLoaderDisplayComplete", false, false));
        }
        
        //////////////////////////////////////
        // Update the loader display
        /////////////////////////////////////
        public function update(percentComplete:Number):Void
        {
            this._bar.tweenBar(percentComplete);
            
            var roundedPercent:Number = Math.round(percentComplete * 100);
            this._progress.text = roundedPercent.toString() + " %";
        }
        
        //////////////////////////////////////////
        // Clean internal workings before deletion
        //////////////////////////////////////////
        public function kill():Void
        {
            this._bar.removeEventListener("onTweenBarComplete", onTweenBarComplete);
            this.removeChild(this._bar)
            this.removeChild(this._progress)
            delete this._bar;
            delete this._progress;
        }
    }
    
    private class LoadBar extends Sprite
    {
        private var _width:Number;
        private var _height:Number;
        
        public function LoadBar(initWidth:Number, initHeight:Number)
        {
            super();
            this.loadBarInit(initWidth, initHeight);    
        }
        
        private function loadBarInit(initWidth:Number, initHeight:Number):Void
        {
            this._width = initWidth;
            this._height = initHeight;
            this.scaleX = 0;
            this.draw();
        }
        
        //////////////////////////////////////////
        // Draw bar
        //////////////////////////////////////////
        private function draw():Void
        {
            this.graphics.beginFill(0x000000, 1);
            this.graphics.drawRect(-(this._width/2),20,this._width, this._height);
        }
        
        //////////////////////////////////////////
        // onTweenChanged callback for Tween
        //////////////////////////////////////////
        
        private function onScaleXTweenUpdate(val:Object):Void
        {
            this.scaleX = val;    
        }
        
        //////////////////////////////////////////
        // onTweenFinnished callback for Tween
        //////////////////////////////////////////
        
        private function onScaleXTweenEnd(val:Object):Void
        {
            this.scaleX = val;
            if (this.scaleX == 1)
            {
                this.dispatchEvent(new Event("onTweenBarComplete", false, false));
            }    
        }
        
        //////////////////////////////////////////
        // tween the bar
        //////////////////////////////////////////
        public function tweenBar(percent:Number)
        {
            var tweenBar:Tween = new Tween(this, this.scaleX, percent, 100, 31);
            tweenBar.setTweenHandlers(this.onScaleXTweenUpdate, this.onScaleXTweenEnd)
        }    
        

    }
}