Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I've got a somewhat large SWF which I'd like to deliver through a pre-loader so the user doesn't have to appear to wait as long. With Actionscript it's pretty easy to create an external pre-loader but doing so makes it harder to distribute my game. What methods are available for including the pre-loader in a single SWF?

share|improve this question
add comment

4 Answers 4

up vote 3 down vote accepted

If you're using Flex in your project, i.e. you created a Flex project, including a preloader in your Application is very easy: set a class name in you Application declaration:

<mx:Application usePreloader="true" preloader="com.example.Preloader">

Now, create a class called com.example.Preloader which extends Sprite, and implements mx.preloaders.IPreloaderDisplay.

Basically, any Sprite can be a preloader display, provided that implements the functions written in the IPreloaderDisplay interface. These functions are properties that the application pass to the class so it can know something about the application: height, width, background color, and two important functions: a "preloader" property setter, and a initialize function.

The preloader property setter accepts a Sprite, and you usually add listeners to the parameter given to you, to the PROGRESS, and COMPLETE events that the sprite dispatches to let the preloader know how is the loading going. This is an example of the property setter:

public function set preloader(value:Sprite):void
{
    _preloader = value;

    value.addEventListener(ProgressEvent.PROGRESS, progressHandler);    
    value.addEventListener(Event.COMPLETE, completeHandler);

    value.addEventListener(RSLEvent.RSL_PROGRESS, rslProgressHandler);
    value.addEventListener(RSLEvent.RSL_COMPLETE, rslCompleteHandler);
    value.addEventListener(RSLEvent.RSL_ERROR, rslErrorHandler);

    value.addEventListener(FlexEvent.INIT_PROGRESS, initProgressHandler);
    value.addEventListener(FlexEvent.INIT_COMPLETE, initCompleteHandler);
}

The initialize function is called by the application when it starts loading the real data. The default preloader uses this function to start a timer, which after some time has passed and the application is still loading, it actually displays the preloader (this is to prevent the preloader to appear immediately, until the user has waited too much time for the app to load)

    public function initialize():void
{
    _startTime = getTimer(); //from flash.utils.getTimer()
}

You might want to download some real source code, though, so I recommend this article which answers some other preloader details on how to draw things inside it: http://iamjosh.wordpress.com/2007/12/18/flex-custom-preloader/

I said at the beginning that this was very easy, but if you're a newcomer you might find this rather daunting. But once you learn how to do it, you'll find that all preloaders in Flex work the same.

share|improve this answer
add comment

You already accepted an answer, which is fine. I'm just going to add the way you would do this in an ActionScript only Project (which is preferable for games IMHO, since it doesn't add the bloat of the flex classes).

package 
{
    // Use the "Frame" metatag to add a preloader class at the first frame
    // of your compiled SWF. You have to enter the fully qualified class
    // name here, if your Preloader is located in a package other than the
    // default package.
    [Frame(factoryClass="Preloader")]
    public class Game extends Sprite
    {
        public function Game(){
            // game init...
        }
    }
}

Your preloader should extend MovieClip. Something along these lines:

public class Preloader extends MovieClip
{
    // Class name of your Game as String. Same rules as with the Preloader, if 
    // the Game is in a package, use fully qualified classname (eg. your.cool.Game).
    // You can't include the class directly, otherwise the preloader would
    // already include the full game.
    protected static const app:String = "Game";

    public function Preloader(){
        this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
    }

    private function onEnterFrame(event:Event):void {
        // do something meaningful here, eg. update loading bar using
        // bytesLoaded and bytesTotal...
        if(framesLoaded == totalFrames){
            loadComplete();
        }
    }

    private function loadComplete():void {
        this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
        // get the class definition of the game
        var clazz:Class = getDefinitionByName(app) as Class;
        if(clazz){
            // create an instance of it and attach it
            var app:DisplayObject = new clazz;
            addChild(app);
        }
    }
}
share|improve this answer
    
Thanks this is useful, but are there any gotchas with exporting symbols on frame 1? –  Alex Schearer Jul 31 '10 at 9:01
    
Not sure what you mean by that. This is the common way preloaders are done in ActionScript-only projects. You have to be careful about what classes you include/use in the Preloader, since that code will be loaded with the first frame. You can use [Embed] metatags to embed preloader assets too. Other than that it's much the same as creating a 2-frame SWF using the Flash IDE where you export some stuff to the first frame and the rest to the second frame. –  bummzack Jul 31 '10 at 9:22
add comment

Okay, this might sound like a cop-out, but I'd download Flixel and see how they do it. Modify it to your hearts content of course, but why not just learn from a working example?

share|improve this answer
    
I'll take a look a that if no one has a better answer. The reason I hesitate is because their pre-loader might be heavily integrated into the rest of the framework making it hard to transfer to another project. –  Alex Schearer Jul 27 '10 at 7:49
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.