views:

307

answers:

2

Hi,

I'm trying to start off a as3.0 project with nothing in the maintimline, I want my default actionscript class to start things off. Like a main in C, so is there a main like function in AS3.0 ?

+3  A: 

The Document class is the closest to what you want. Document class info. I tend to keep the document class to a bare minimum.

package 
{   
    import flash.display.MovieClip; 
    import flash.events.Event;  



    public class Document extends MovieClip
    {

        public var _main:Main; 


        public function Document()
        {
            addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
        }

        //all initialization goes in here!
        private function init(e:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            initMain();     
        }

        private function initMain():void
        {
            _main = new Main();
        }


    }
}

Note that calling another Main class is just a personal preference thing. Also the event listener is quite important if you are trying to reference items on the stage.

Allan
Yes, basically I'm used to timelines and coding a lot on the first frame. Now I need to change that practice to a more OO approach. So yes I would need to have a lot of listeners and the main ofcourse.Btw why keep the document class to a bare minimum? Last but not least what about EnterFrame can I have it in a class?
Fahim Akhter
Keeping the document class to a minimum is just something I do. Since my work involves lots of animations by artists on the stage I link them up with the help of a static class and a lot of the linking is done in the Document class and gets visually messy. So I like my logic code to be in a class I call Main. You can put all your code in the document class if you want :). Yes you can listen for ENTER_FRAME, the document class wont limit you in anyway. The listener must just be attached to the stage object.
Allan
@Fahim Akhter: "why keep the document class to a bare minimum?" http://en.wikipedia.org/wiki/Single_responsibility_principle
back2dos
+1  A: 

I have a few modifications to the answer above which might be useful.

The listener is important for referencing things on stage only if the SWF could potentially be loaded in as a module into another application. If this document class is guaranteed to be the root document class, then adding an event is essentially pointless. I've modified the answer above so that it take the faster route if it is the root SWF, without braking the potential for modularity.

I'd recommend looking into a framework like RobotLegs to organise your code. Most people who move into a more interactive scenario think that they don't need them to start with, and end up realising that they exist for very good reasons - namely that dependencies tend to get messy fast in this line of work. If you chose RobotLegs, your 'Main' class would be the framework Context.

In any event, to be useful your Main class will need access to the display list, so you'll need to pass in a reference to the Document class. Pass it in cast to DisplayObjecContainer though, to avoid dependencies on Document in Main.

You also don't need to extend MovieClip since there's no timeline here; Sprite will serve just as well, and the class will be fractionally lighter. There's no good reason for exposing the main variable either - if you're going to use the SWF modularly and expose an API in the document class, you don't want to expose the Main class anyway, you want to expose an interface. (Unfortunately, you can't usefully interface Document and load it in as a modular SWF - or you couldn't at least for Flash Player 9 - as there is a bug related to this process: blog post on problems interfacing a SWF

With these modifications then, the above answer becomes:

package 
{   
    import flash.display.Sprite; 
    import flash.events.Event;  

    public class Document extends Sprite
    {
        private var main:Main; 

        public function Document()
        {
            if (stage)
                init();
            else
                addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true);
        }

        private function onAddedToStage(event:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
            init();     
        }

        private function init():void
        {
            main = new Main(this);
        }
    }
}

But your main class wouldn't know the Document type, so:

package 
{   
    import flash.display.DisplayObjectContainer;

    public class Main
    {
        private var viewComponent:DisplayObjectContainer;

        public function Main(viewComponent:DisplayObjectContainer)
        {
            this.viewComponent = viewComponent;
            ...
        }
    }
}
alecmce
alecmce, could you elaborate a little more about the last part "But your main class wouldn't know the Document type" ? I can't understand what you mean by that.nice idea with the if (stage)
dome
I just mean you pass in the Document instance to the Main class, but the Main class would treat it as a DisplayObjectContainer because you want to use it as a container into which you will put your other content. Building it this way makes the format of what you created more reusable, and your code more robust. The less each part knows about each other part increases the likelihood that your code will work as you intend.
alecmce
@Allan - I voted up your answer, this is not intended as a criticism (at least not in a harsh sense), but it was a bit too big for a comment.
alecmce
@alecmce thats cool. They are all valid criticisms and I agree with them +1 :) Was a touch lazy when I wrote this. The only thing I generally differ from is passing in the reference to stage. I normally link it up to a static field in another class (as well as all the other image resourcs on stage) so that I can refer to it from anywhere (I have far too many bits of animations to keep passing things by parameter).
Allan
@Allan, glad you took my intention as I had hoped :) I use robotlegs so I don't have to worry about static fields or reference issues, but the idea's pretty much the same.
alecmce