Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Flash Player load the main SWF file?

UPDATE:

It seems that everyone didn't read my question thoroughly, all answers suggest me preloading or using external assets. So anyone willing to answer, please take notice to bold questions in this post. Thanks!


I'm developing a simple Flash application which has only one SWF file. I want the SWF movie to start playing asap so I don't build a preloader for it. What happen if my actionscript code refers to resources which haven't been loaded yet?

For example, the code cause the playhead to jump from frame 1 to frame 20 when the movie has just been loaded up to frame 10. In that case, flash player will?

  • Block the script execution, stop playing, continue loading from frame 11 to 20 (without executing script), jump to frame 20 and invoke script at that frame when it's loaded?
  • Block the script execution, stop playing, ignore loading frame 11 to 19, load frame 20, jump to frame 20 and invoke script at that frame?
  • Ignore jumping to frame 20, continue executing next statements after the go to frame 20 statement?
  • Or anything else?

If flash player doesn't ignore jumping to frame 20, any event is triggered when frame 20 is loaded completely?

Note: Answers for the first question should focus on my example, cover all circumstances (such as attach movie from library...) is better, but not necessary.

Thanks!

like image 298
ExpExc Avatar asked Oct 09 '22 09:10

ExpExc


2 Answers

Flash will always load all the frames before running the application. However, the frame contents might not be fully loaded. So if you have some images on frame 20, they might not appear.

But basically you shouldn't rely on Flash to load things for you - it might do it in the order you want, but maybe it won't. If you have many assets and you are jumping from frame to frame, you should handle the loading yourself using the Loader class.

like image 77
laurent Avatar answered Oct 11 '22 21:10

laurent


Flash player will try to jump to frame 20. But it will only go as far as the frames that are loaded. So if you tell it to go to 20, and only 10 are loaded, you will go to 10.

Calling resources in code not yest loaded will either throw an error, or define that object as null. Needless to say, this needs to be avoided. Load those resources first.

A good solution is to use the -frame compiler argument to create a 2-frame flash movie. the first contains your preloader, and the second frame contains the complete app. that way you can preload what you need before the full functionality is called for.

Here is an example fo how to do that.

package 
{
    import flash.display.DisplayObject;
    import flash.display.MovieClip;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.utils.getDefinitionByName;

    /**
     * ...
     * @author Zachary Foley
     */
    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);

            // TODO show loader
        }

        private function ioError(e:IOErrorEvent):void 
        {
            trace(e.text);
        }

        private function progress(e:ProgressEvent):void 
        {
            // TODO update loader
        }

        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);

            // TODO hide loader

            startup();
        }

        private function startup():void 
        {
            var mainClass:Class = getDefinitionByName("Main") as Class;
            addChild(new mainClass() as DisplayObject);
        }

    }

}

To use this you need to add the frame argument to your build. For this example the frame argument would be:

-frame start Main
like image 34
Plastic Sturgeon Avatar answered Oct 11 '22 21:10

Plastic Sturgeon