简体   繁体   中英

Why should I use preloader in Flash

I do not have quite knowledge about preloaders but I have read couple of articles and Adobe instructions. So I am confused about preloaders using in Flash applications.

I am planning to call all MovieClips, sounds, and etc. from library and nothing will be on the stage. For this situation, is it logical to apply preloader, if so which approach will be the most suitable one (even with smaller swf sizes)?

It's impossible to tell you which approach is the best when you're not telling the context of your application.

For banners and smaller swf ( <100k) etc I shouldn't use any sort of a preloader. Flash will handle the loading itself (only without showing a visual loader)

For bigger swf games I normally let one small swf loads the main swf.

    package
{

    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;

    [SWF(width="992", height="768", frameRate="30", backgroundColor="0x000000")]
    public class Preloader extends Sprite
    {
        private var percent:Number;
        private var loader:Loader;

        public function Preloader()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            var movieurl:String = loaderInfo.parameters.movieurl;

            loader = new Loader();
            loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
            var loaderContext : LoaderContext = new LoaderContext(false,new ApplicationDomain(null));

            loader.load( new URLRequest("main.swf" + version),loaderContext);

        }


        private function progressHandler(event:ProgressEvent):void
        {
            percent = ((event.bytesLoaded / event.bytesTotal)*100);
            trace ("laoded": percent)

        }


        private function completeHandler(event:Event):void{
            //removeChild(progressBar);

            addChild(loader);
        }
    }
}

If your application must exist of 1 swf. You could use a Preloader class

main swf class

[Frame(factoryClass="Preloader")]
[SWF(width = "950", height = "600")]
public class Main extends Sprite 
{
  // do your coding
}

preloader swf class

package {
    import erasmus.simulation.LoaderFC;

    import flash.display.DisplayObject;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.events.UncaughtErrorEvent;
    import flash.utils.getDefinitionByName;


    public class Preloader extends MovieClip {

        public function Preloader(){
            if (stage){
                stage.scaleMode = StageScaleMode.NO_SCALE;
                stage.align = StageAlign.TOP_LEFT;
            }
            addEventListener(Event.ENTER_FRAME, checkFrame);
            loaderInfo.addEventListener(ProgressEvent.PROGRESS, progress);
            loaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioError);
        }



        private function progress(e:ProgressEvent):void {

            var progress : Number = e.bytesLoaded / e.bytesTotal;
            trace ("loader progress")
        }

        private function checkFrame(e:Event):void {
            if (currentFrame == totalFrames){
                stop();
                loadingFinished();
            }
        }

        private function loadingFinished():void {
            removeEventListener(Event.ENTER_FRAME, checkFrame);
            loaderInfo.removeEventListener(ProgressEvent.PROGRESS, progress);
            loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioError);

            var mainClass:Class = getDefinitionByName('Main') as Class; // class must be a string reference
            this.stage.addChild(new mainClass(this) as DisplayObject);
        }
    }
}

Nothing will be on stage - by that I assume you're using Flash IDE with timeline?

In this case (as well as other cases, in fact) you must use the preloader. There is a possibility (even when running locally) that when you try to access something from the library, it will not be fully loaded yet.

In Flash IDE a preloader can be first two frames in the timeline: some progress sprite or just a TextField that spans two frames, first frame does nothing, second frame checks bytesLoaded vs. bytesTotal and goes to first frame if the movie is not fully loaded yet. The third frame is where all main code starts.

Note that all your library assets must be set for 'export in Frame 3', ie not in any of frames where loader is active.

Alternately, you can use single frame with event-based loader.

When using FlashDevelop, there is a ready-made template for a project with a preloader.

There is a common mistake when people use some of their library classes or assets in the preloader to show a nice progress indicator. In that case, all that data has to be loaded first, and preloader cannot work immediately. It looks like empty screen with long pause and no preloader, and then the application is 100% loaded at once. So the preloader becomes pointless, it can't show any progress to the user.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM