Search code examples
actionscript-3flashflash-cs5

How can I call timeline-specific methods from an external file in AS3?


I'm creating a game is Flash CS5 with ActionScript 3. To simplify things, I've created a file (Game.as) in the top layer of my source folder. My Game.as file looks as follows:

package {
    public class Game {
        public static function fail():void {
            stop();

            var restart:RestartButton = new RestartButton();
            addChild(restart);

            restart.x = stage.stageWidth/2;
            restart.y = stage.stageHeight/2;

            Game.createButton(restart, function(e:MouseEvent):void { gotoAndPlay (1, "Title Sequence") });
        }
    }
}

I would supposedly call Game.fail () from a frame on a timeline a scene, but I get these compiler errors:

Line 11 1180: Call to a possibly undefined method stop. Line 19 1180: Call to a possibly undefined method gotoAndPlay. Line 17 1120: Access of undefined property stage. Line 16 1120: Access of undefined property stage. Line 14 1180: Call to a possibly undefined method addChild.

Why are these errors happening? What can I do to fix them?

Thanks for your help in advance.


Solution

  • The problem is that none of those methods exist on your Game class.

    There's at least two good reasons for this:

    1. Your Game class needs to extend MovieClip to have the methods stop(), gotoAndPlay(), addChild(), and the stage property. For example class Game extends MovieClip would give you those methods.
    2. Even if your Game extends MovieClip you can't access methods like stop() from static scope, only from instance scope (ie this). This is because static scope is essentially a global code space so none of those methods make any sense: when you say stop() you have to say what instance will stop, ex this.stop() or thatThing.stop(). The static code has no awareness of what instances of the class there may even be, so there's no way an instance function can work. You need an instance of the Game class, not just a static function.

    What I think you are trying to do is essentially use Game as a singleton for your main timeline. You can do that like this:

    package {
        public class Game extends MovieClip {
    
            // global reference to a single instance of the Game
            public static game:Game;
    
            public function Game() {
                // store a global reference to this instance
                // NOTE: bad things will happen if you create more than one Game instance
                game = this;
            }
    
            // do NOT use static for your methods
            public function fail():void {
                stop();
    
                var restart:RestartButton = new RestartButton();
                addChild(restart);
    
                restart.x = stage.stageWidth/2;
                restart.y = stage.stageHeight/2;
    
                createButton(restart, function(e:MouseEvent):void { gotoAndPlay (1, "Title Sequence") });
            }
        }
    }
    

    Now you need to set this class as your document class. There is only ever one instance of the document class, so this works well for you. However, you could link this class to a symbol in your library and instantiate it by code (new Game()) or by placing a timeline instance on a keyframe.

    Finally, to call Game methods from anywhere you can use the Game.game instance:

    Game.game.fail();