A Flash Developer Resource Site

Page 1 of 2 12 LastLast
Results 1 to 20 of 25

Thread: How to access a function from another AS file?

  1. #1
    Member
    Join Date
    Jan 2010
    Posts
    40

    How to access a function from another AS file?

    I need a bit of assistance in a game I’m making.
    Basically I’ve got the ‘mysteryNumber’ inside the ‘init’ function working but I need functions in the other ActionScript files to access the ‘mysteryNumber’.

    So basically I have a:

    Main.as (with the mysteryNumber function)
    function init():void

    {
    startMessage = "???";
    mysteryNumber = Math.ceil(Math.random() * 1);
    libPage.output_txt.text = startMessage;
    }


    LibPage.as (function that calls the mysteryNumber using an if/else statement)
    public function get mysteryNumber()

    {
    if (1 == mysteryNumber)
    {
    libPage.output_txt.text = "Number 1";
    }

    This if statement will work if I put it inside the Main.as file but I will be needing it in several .as files.

    I’m not sure whether I should be using getters/setters or an event dispatcher but I also don’t know much about how to use them.

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Make mysteryNumber a public property of Main. Then when you need it elsewhere, get it from the instance of Main that you have (should be your document class).

    Your getter function there doesn't make sense. A getter should return a value. And it is invoked when accessing that value as a property. So if you put in a property reference to the same thing as the getter, you'll get an infinite recursion.

  3. #3
    Member
    Join Date
    Jan 2010
    Posts
    40
    I think I may have put some irrelevant code in there so it might make the problem a bit confusing.

    But I've amended mysteryNumber and it now looks like this.

    Main.as file
    public function init():void

    {
    mysteryNumber = Math.ceil(Math.random() * 1);
    }

    but I don't know how to use a getter and I just put it there to show what I was trying to do. Could you help?

  4. #4
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Apparently not. I'll try re-phrasing.

    In order for other instances to have access to the mysteryNumber property of your Main instance, it must be a public property. That means that it is declared in Main.as like this:

    Code:
    public class Main extends MovieClip{
    
      public var mysteryNumber:Number;
      //more Main code...
    
    }
    Now, any other instance which has a reference to your Main instance can access mysteryNumber. Let's say that that instance has a reference called mainInstance.

    Code:
    trace(mainInstance.mysteryNumber);
    To get a reference to your instance of Main, you will either need to create main from another class (unlikely, or it wouldn't be very main), or pass an existing instance to it. If main is your document class, then any DisplayObject on the display list will have a reference to it in the root property. But to use stuff declared in Main, you must cast root to Main so the compiler knows that those properties are there.

    Some moveclip on the stage:
    Code:
    trace(Main(root).mysteryNumber);
    If you're a little more advanced than I've given you credit for and you actually have other classes that you are using, you can give them a reference when you create them, or later.

    Code:
    var myInstance:AnArbitraryClass = new AnArbitraryClass();
    myInstance.mainRef = Main(root);
    Code:
    public class AnArbitraryClass {
      public var mainRef:Main;
      //...
    
      private function useMysteryNumber():void{
       trace(mainRef.mysteryNumber);
      }
    }
    None of these names are important, only the relationships between classes and instances.

    Now, I do not recommend this in this case, but you could make mysteryNumber a static property of Main and then you could reference it from anywhere with Main.mysteryNumber.

  5. #5
    Member
    Join Date
    Jan 2010
    Posts
    40
    Hey, sorry for the late response. I've been trying to implement the code you gave, modifying the names to better suit the program but I havn't been successful in any way.
    I thought it might be easier if you could look at the code. I've highlighted the code you've advised me to use.

    Main.as Code:
    Actionscript Code:
    package
    {
        import flash.display.MovieClip;
        import flash.events.MouseEvent;
       
        public class Main extends MovieClip
        {
            var mapPage:MapPage;
            var essenPage:EssenPage;
            var libPage:LibPage;
            var mungosPage:MungosPage;
            var startMessage:String;
            [COLOR="Red"]public var theNumber:Number;[/COLOR]
           
            public function Main()
            {
                mapPage = new MapPage;
                essenPage = new EssenPage;
                libPage = new LibPage;
                mungosPage = new MungosPage;
                [COLOR="Blue"]addChild(mapPage); //The game is not based on timeline [/COLOR]

                mysteryNumber();
               
                mapPage.essenButton.addEventListener(MouseEvent.CLICK,
                    onEssenButtonClick);
                mapPage.libButton.addEventListener(MouseEvent.CLICK,
                    onLibButtonClick);
                mapPage.mungosButton.addEventListener(MouseEvent.CLICK,
                    onMungosButtonClick);      
                libPage.mapButton.addEventListener(MouseEvent.CLICK,
                    onMapButtonClick);
               
                [COLOR="red"]mapPage.mysteryNumber = Main(root);[/COLOR]
            }
           
            private function mysteryNumber():void
            {
                //Initialize vars
                startMessage = "???";
                theNumber = Math.ceil(Math.random() * 6);
                libPage.output_txt.text = startMessage;        
                //trace(theNumber) 
            }

           
            function onEssenButtonClick(event:MouseEvent):void
            {
                addChild(essenPage);
                removeChild(mapPage);
            }
            function onLibButtonClick(event:MouseEvent):void
            {
                addChild(libPage);
                removeChild(mapPage);
            }
            function onMungosButtonClick(event:MouseEvent):void
            {
                addChild(mungosPage);
                removeChild(mapPage);
            }
            function onMapButtonClick(event:MouseEvent):void
            {
                addChild(mapPage);
                removeChild(libPage);
            }
        }
    }

    LibPage.as Code:
    Actionscript Code:
    package
    {
        import flash.display.MovieClip;
        import flash.events.MouseEvent;
       
    [COLOR="red"]   public class LibPage extends MovieClip
        {
            public var mysteryNumber:Main;
           
            private function useMysteryNumber():void
            {
                trace(mysteryNumber.theNumber);
            }
        }[/COLOR]
    }

    Apologies for the mess, as you found out before, I'm a rookie at as3
    I really appreciate your time.
    Last edited by eightballmark; 02-16-2010 at 10:17 AM.

  6. #6
    Member
    Join Date
    Jan 2010
    Posts
    40
    I'm obviously also a newbie at forums :-/

  7. #7
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    You've got the key and you've got the lock, you just need to put them together. After you create your LibPage instance, set its mysteryNumber property to the instance of Main.
    Code:
    libPage = new LibPage();
    libPage.mysteryNumber = this;

  8. #8
    Member
    Join Date
    Jan 2010
    Posts
    40
    Ok so my Main.as file now has

    Actionscript Code:
    public function Main()
            {
                mapPage = new MapPage;
                essenPage = new EssenPage;
                libPage = new LibPage;             <<<<
                libPage.mysteryNumber = this;   <<<<
                mungosPage = new MungosPage;
                addChild(mapPage);
                mysteryNumber();

    And the LibPage.as looks like this

    Actionscript Code:
    public class LibPage extends MovieClip
        {
            public var mysteryNumber:Main;
           
            private function useMysteryNumber():void
            {
                if (1 == mysteryNumber.theNumber)
                {
                trace(mysteryNumber.theNumber);
                }
            }
        }

    But LibPage "useMysteryNumber" still won't call the function

  9. #9
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    What function? theNumber is a property. If you wanted other classes to call Main's mysteryNumber function, you'd have to make that function public in Main and actually call it.

  10. #10
    Member
    Join Date
    Jan 2010
    Posts
    40
    sorry I meant property. It still won't call the mysteryNumber.theNumber property

  11. #11
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    What are you getting? I would expect that about 1 in 6 times, you get a trace of "1", and mostly you get no trace at all. You could trace mysteryNumber.theNumber outside the if, just to see if you are getting it at all.

    If you are getting some error, post what it is.

  12. #12
    Member
    Join Date
    Jan 2010
    Posts
    40
    I just want the LibPage to perform
    Actionscript Code:
    trace(mysteryNumber.theNumber);
    so it shows in output.

    I tried doing it without the if statement and set it so it would only produce "1" but output shows nothing.
    There's no errors in whichever way I do it.

  13. #13
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Are you ever calling useMysteryNumber? I don't see it in any of the code above.

  14. #14
    Member
    Join Date
    Jan 2010
    Posts
    40
    Ohhhhhh, I think I get it. I thought "trace" would automatically work as soon as you test the swf file. Could you possibly give me a code example so that I can call useMysteryNumber?

  15. #15
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Within LibPage, you call it just by
    Code:
    useMysteryNumber();
    Outside of LibPage, it is currently not available, since the function is private. If you make it public, you could do the following. I don't know if this is where you want to use it, but this should call useMysteryNumber after Main has initialized itself.
    Code:
    public function Main(){
       mapPage = new MapPage();
       essenPage = new EssenPage();
       libPage = new LibPage();
       libPage.mysteryNumber = this;
       mungosPage = new MungosPage();
       addChild(mapPage);
       mysteryNumber(); 
       libPage.useMysteryNumber();
       //...

  16. #16
    Member
    Join Date
    Jan 2010
    Posts
    40
    I've used that and here's what it looks like in LibPage.as

    Actionscript Code:
    public class LibPage extends MovieClip
        {
            public var mysteryNumber:Main;
           
            public function LibraryPage()
            {
                useMysteryNumber();
            }
           
            private function useMysteryNumber():void
            {
                trace(mysteryNumber.theNumber);
            }
        }

    But get the error code:
    1195: Attempted access of inaccessible method useMysteryNumber through a reference with static type LibPage.

  17. #17
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    That doesn't make sense. You'd get that error if you were calling useMysteryNumber from outside LibPage because that function is not public.

    It kinda looks like you were trying to make a constructor for LibPage, and call useMysteryNumber there. If that's the case, you need to make the function name exactly match the class name. That would compile, but still not work. You can't use the mystery number until the reference to main is set, and that doesn't happen until after the constructor finishes.

    Where are you calling LibraryPage?

  18. #18
    Member
    Join Date
    Jan 2010
    Posts
    40
    I think it might be better if I explain what I'm trying to do as I might be programming this the completely wrong way.

    I'm making a murder mystery game.

    The Main.as file will have all of the game logic, such as the mysteryNumber.

    The other actionScript files represent rooms that the user may click.

    So for example, if a user clicks the Library page, the LibPage.as will call the 'mysteryNumber' and depending on what the number is, it will execute the 1 of the 6 scenarios and display it on the Library page.

    It will be the same for the other 4 rooms.

    Hopefully I'm not doing this wrong but if I am please point me in the right direction.

  19. #19
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    What I do not see that is pretty important to that scenario is any sort of MouseEvent.CLICK listener. You will want to set up such a listener on the LibPage instance, which will then use the mysteryNumber to determine what to do.

    So, a very bare sketch. Main:
    Code:
    var libPage:LibPage = new LibPage();
    libPage.mainRef = this;
    addChild(libPage);
    //stuff to set up theNumber...
    LibPage:
    Code:
    public class LibPage extends Sprite{
      public var mainRef:Main;
    
      public function LibPage(){
         addEventListener(MouseEvent.CLICK, useMysteryNumber);
      }
    
      private function useMysteryNumber(e:MouseEvent):void{
         trace(mainRef.theNumber);
      }
    }

  20. #20
    Member
    Join Date
    Jan 2010
    Posts
    40
    I get the errors:

    1017: The definition of base class Sprite was not found.

    5000: The class 'LibPage' must subclass 'flash.display.MovieClip' since it is linked to a library symbol of that type.

    5000: The class 'Main' must subclass 'flash.display.MovieClip' since it is linked to a library symbol of that type.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center