5
votes

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!

5
If you want to fine tune your loading experience, dont rely on Flash's automatic loading mechanisms. And dont use frames. Use something like Bulkloader to load your assets. Your .swf file should only contain assets, that are needed to be displayed on the first frame, and all the code. - sydd

5 Answers

3
votes

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.

1
votes

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
0
votes

In your case you have to define the progressive loading method for your project.

First of all develop external assets, initially load only one and display it. Just start second one loading and manage display with your loaded UI only. So you can avoid the preloader. When you will get loaded item list just perform one by one displaying in progressive manner.

first display only one. After second loading first & second one.. then so on you have to manage

Other wise you have to wait on first display upto next display assets loading will be over. And don't show pre-loader this time.

0
votes

I've made some test using Adobe Flash Professional in order to find the answer for my question. Everyone who's interested can reproduce the test by doing the following steps in Adobe Flash:

  1. Create a movie with some frame, each frame contains one image and some actionscript code, for example.
  2. Select menu Control -> Test Movie -> in Flash Professional: The debug player will be displayed
  3. In the debug player, select menu View -> Download Settings then choose your desired download speed
  4. Also in the debug player, make sure Bandwidth Profiler and Simulate Download under View menu are checked.

If the script doesn't change the playhead, Flash player will:

  1. Load frame 1 and wait until it's loaded completely
  2. Go to frame 1
  3. Execute script on frame 1
  4. Display frame 1
  5. Doing above steps for frame 2, and so on... (Stay at frame 1 until frame 2 is loaded completely, then go to frame 2, execute script, display...)

If the script change the playhead, e.g. jump from frame 1 to frame 20, Flash player will:

  1. Continue to execute all script statements in frame 1 (even though these statements follow the jumping statement) and display frame 1.
  2. If frame 20 is loaded, jump to frame 20, execute script on it & display it. If it isn't loaded, jump to nearest loaded frame (in my example in the question is frame 10) but do not execute script on that frame.
0
votes

in AS2, try this code. Loading progress show at first frame, and main content show at 3rd frame. This code is in ActionScript 2.0 reference(getBytesLoaded). http://help.adobe.com/ko_KR/AS2LCR/Flash_10.0/00001304.html#1333866

if (this._framesloaded<this._totalframes) {
    this.gotoAndPlay(1);
} else {
    this.gotoAndStop(3);
}

in AS3, use This.

this.loaderInfo.addEventListener(Event.COMPLETE, completeHandler);