0
votes


I started working on a flash shoot em-up game tutorial and i finished it Asgamer Shoot em upp Game
Now i started creating a new .fla that is the Main Menu and i have a play button so when i press it it will load the .swf(Game swf) but when i press the button i get the following error.

TypeError: Error #1009: Cannot access a property or method of a null object reference.
 -at com.senocular.utils::KeyObject/construct()
 -at com.senocular.utils::KeyObject()
 -at com.actionscript.Ergasia::Ship()
 -at com.actionscript.Ergasia::Engine()





public function Engine() : void {
    if(stage) {
        initialize();
    } else {
        addEventListener(Event.ADDED_TO_STAGE,initialize);
    }
} 

    private function initialize(e:Event = null):void {
        removeEventListener(Event.ADDED_TO_STAGE,initialize);
        //  here goes the code that's currently in Engine constructor
    }

EDIT: Thanks to Viper for solving this!

1
Most likely your game SWF was created with stage already assigned, while in this content its stage property is yet null, as it's loaded but not added anywhere. So, wherever you address stage in your game SWF, make an Event.ADDED_TO_STAGE listener, and put all code that accesses stage in there, also don't allow proceeding while stage is null. Also, it's not enough to initiate loading the SWF, you ave to wait until it'll complete loading. - Vesper
First of all thanks for your quick answer, because i m beginner in as3 where do i put Event.ADDED_TO_STAGE? - Tony Zach
That depends on what parts of code, and what classes refer to stage from within their constructor. At the very least it's Ship class. Do revise your entire codebase for constructors that call for stage.something inside them, these will net you a 1009 error if you let them. Instead, slap a if (stage) init(null); else addEventListener(Event.ADDED_TO_STAGE,init); line at the end of each of these, and implement a function init(e:Event):void { removeEventListener(Event.ADDED_TO_STAGE,init); ...} that will process whatever your class needs from stage. - Vesper
Sorry again i edited my question so you can see the code from my Engine() class and the code you gave me so i can understand how can i change it - Tony Zach
So, your Engine class has a pre-placed instance on the stage at design time. Right, this is a common issue of addressing stage in constructors. Yes, you need to do exactly this, except for making Engine() return void - it's still a constructor. So, public function Engine() { instead of : void. - Vesper

1 Answers

0
votes

Change the Engine constructor to the following:

public function Engine() {
    if(stage) {
        initialize();
        } else  addEventListener(Event.ADDED_TO_STAGE,initialize);
    } 

private function initialize(e:Event = null):void {
    removeEventListener(Event.ADDED_TO_STAGE,initialize);
    //  here goes the code that was in Engine constructor
    trace(stage);
        ourShip = new Ship(stage);
        stage.addChild(ourShip);
        ourShip.x = stage.stageWidth / 2;
        ourShip.y = stage.stageHeight / 2;
        ourShip.addEventListener("hit", shipHit, false, 0, true);
        stage.addChild(ourShip);
        scoreHUD = new ScoreHUD(stage);
        stage.addChild(scoreHUD);

        for (var i:int = 0; i < numCloud; i++)
        {
            stage.addChildAt(new Cloud(stage), stage.getChildIndex(ourShip));

        }
        for (var b:int = 0; b < numStar; b++)
        {
            stage.addChildAt(new Star(stage), stage.getChildIndex(ourShip));
        }

        addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}

The main problem is that your Engine class is written in presumption that stage is already accessible, but when you load the SWF, its stage is null while that SWF is not added to the stage. To circumvent this, the common practice is using the Event.ADDED_TO_STAGE listener, and start placing your code in there instead of the constructor.