Ant
Ant

Reputation: 77

Unloading external SWF files

I'm loading multiple swf files from the main menu which is never unloaded. I've done this with the following code... Only issue is that instead of unloading to the main menu I just see a white screen as if nothing is loaded.

function BackToMenu(i:MouseEvent):void
{
    var BaseMovie:MovieClip = parent.parent as MovieClip;
    BaseMovie.parent.removeChild(BaseMovie);
}

EDIT: I'll explain from the start I have a MainMenu.swf. The games are loaded from MainMenu.swf when the button relating to the game is clicked. When a game button is clicked on MainMenu.swf the game loads. When the player completes a game they are presented with the exit button which unloads the current game and shows the MainMenu.swf without having to re-load it.

Upvotes: 0

Views: 1481

Answers (1)

weltraumpirat
weltraumpirat

Reputation: 22604

First, you should remove one parent to make sure you are actually removing only the game:

function BackToMenu(i:MouseEvent):void
{
    var BaseMovie:MovieClip = parent as MovieClip;
    BaseMovie.parent.removeChild(BaseMovie);
}

This should take care of your most pressing problem, and allow you to return to the menu. You have, however, not really unloaded the game, but only removed it from the display list. This often means, that there are still sounds running, active key and/or mouse listeners, etc. - these must all be taken care of!

And, like I said, this will only fix your immediate problem. It is, however, neither a permanent solution, nor a good one: Since the main SWF is responsible for loading the games, it should also be responsible for disposing of them. You should put cleanup code into your game, but it should only be concerned with stopping any running scripts, sounds, etc. - simple rule: anything that is started within the game, should be stopped within the game. But it should not try to access objects further up in the display hierarchy, or try to unload itself.

The much better way to do this is by replacing all the above code, and letting the main SWF take care of removing the game, as well as unloading it from memory. For this, you have to do three things:

  1. Instead of writing actual removeChild calls, etc., let your button dispatch a custom event to notify the main SWF that it should now be removed:

    function onBackButtonClicked( event:MouseEvent ):void {
        destroyGame(); // this would be the function that stops all the scripts
        dispatchEvent( new Event( "FINISH_GAME", true ) ); 
    }
    

    Note that "FINISH_GAME" is now a "bubbling" event, i.e. it travels downward in the display hierarchy. We can now listen for this event in any ancestor display object containing the game.

  2. In your main SWF, add an event listener to the Loader when the game was successfully loaded. This is done in the event listener that is called when the load process completes:

    function onLoadComplete( event:Event ):void {
        var loader:Loader = event.target.loader;
        loader.addEventListener( "FINISH_GAME", onFinishGame, true );
    }
    
  3. Use the corresponding event handler to remove the game clip:

    function onFinishGame( event:Event ):void {
        var loader:loader = event.currentTarget;
        loader.parent.removeChild( loader );
        loader.unloadAndStop();
    }
    

A few more things to consider:

  • The naming conventions in ActionScript advise us to use lower case names for methods and variables, and upper case only for types.

  • The same naming conventions suggest we use either "on" or "handle" as a prefix for event listeners, along with the name of the event. Thus, it should be onBackToMenu or rather, onBackButtonClicked, etc.

  • Since I don't know anything about the code you use for loading, I just assumed you have a complete listener, and you don't keep references to the loader. If you use a member variable, you can use that instead of event.target, resp. event.currentTarget.

Upvotes: 1

Related Questions