Search code examples
actionscript-3flashactionscriptfla

linking fla files together in actionscript using document classes


I am working in actionscript3, and since I'm self-taught, I think I've developed some bad habits, including coding on the timeline and using multiple scenes.

I am hoping to rectify this now that I'm working on a larger project.

Based on what I've read, linking multiple .fla files together is a better practice, each with their own document class. Is that correct?

If so, how do I load one .fla with its document class and then link that into the subsequent .fla file (instead of using scenes)? Or am I misinterpreting what was recommended?

Thanks!


Solution

  • There's no point to split your application in several loadable modules unless you have any of the following preconditions:

    • you have smart resource management to load and unload content
    • if you put everything into one file it gets just too big and hard to work with in design time or it takes far too long to compile

    Regular AS3 alternative to working with scenes is creating/destroying content instances and using the main document class as their manager. You design content in the library and create behavior AS3 classes for them. Lets say, you have two content classes A and B. At the start the manager should show one of them and wait for the signal to show next one:

    private var APage:A;
    private var BPage:B;
    
    gotoA();
    
    function gotoA():void
    {
        if (BPage)
        {
            BPage.destroy();
            removeChild(BPage);
            BPage.removeEventListener(Event.CLOSE, gotoA);
        }
    
        APage = new A;
        APage.addEventListener(Event.CLOSE, gotoB);
        addChild(APage);
    }
    
    function gotoB():void
    {
        if (APage)
        {
            APage.destroy();
            removeChild(APage);
            APage.removeEventListener(Event.CLOSE, gotoB);
        }
    
        BPage = new B;
        BPage.addEventListener(Event.CLOSE, gotoA);
        addChild(BPage);
    }
    

    So, both A and B should have respective methods .destroy() that release used resources, unsubscribes methods from events, remove display objects, and so on, and they both should fire Event.CLOSE when they're done.

    If you have many pages like that, you need to go for more algorithmic approach. For example, to create class BasicPage which will interact with manager and have the methods needed in all pages already declared:

    package
    {
        import flash.display.Sprite;
    
        class BasicPage extends Sprite
        {
            // A reference to the page manager instance.
            public var Manager:PageManager;
    
            public function destroy():void
            {
                while (numChildren > 0) removeChildAt(0);
    
                Manager = null;
            }
    
            // Subclasses will have an access to this method to tell manager to show another page.
            protected function showOtherPage(pageClass:Class):void
            {
                Manager.showPage(pageClass);
            }
    
            // A method that is called by manager when everything is ready.
            // If page should take any actions on start it is a good idea to override this method.
            public function startEngine():void
            {
            }
        }
    }
    

    Then, example page A:

    package
    {
        import flash.events.MouseEvent;
    
        public class A extends BasicPage
        {
            // Lets say, class A in library have a designed button named Click.
            public var Click:SimpleButton;
    
            // We have things to undo here.
            override public function destroy():void
            {
                Click.removeEventListener(MouseEvent.CLICK, onClick);
                Click = null;
    
                // Pass the destruction to superclass so it wraps its existence either.
                super.destroy();
            }
    
            override public function startEngine():void
            {
                Click.addEventListener(MouseEvent.CLICK, onClick);
            }
    
            private function onClick(e:MouseEvent):void
            {
                // Lets use inherited method to show other page.
                showOtherPage(B);
            }
        }
    }
    

    So, PageManager will be like:

    package
    {
        public class PageManager extends Sprite
        {
            private var Page:BasicPage;
    
            // constructor
            function PageManager()
            {
                super();
                showPage(A);
            }
    
            function showPage(pageClass:Class):void
            {
                if (Page)
                {
                    Page.destroy();
                    removeChild(Page);
                    Page = null;
                }
    
                Page = new pageClass;
                Page.Manager = this;
    
                addChild(Page);
                Page.startEngine();
            }
        }
    }
    

    This all could look scary at first, but it really isn't. PageManager will always have a current page, once there's a need to show another page, the current will be destroyed on a regular basis. Each page class will tend to its own content, which makes coding simpler, for you don't need to see the whole picture. If you need any persistent data, keep it in the PageManager so each page will have access to the data with no need for the pages to communicate with each other.