AS3 stage = null?

会有一股神秘感。 提交于 2019-12-02 01:59:48

问题


I've just tried to implement a menu system I saw a tutorial onto a game that I'm working on and it was all smooth sailing until I've now encountered a problem with the stage being set to null and I don't know how to stop it. The line that keeps breaking it is in the AvoiderGame.as file and is the stage.addEventListener(Event.ADDED_TO_STAGE, init); it keeps returning the following error

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at AvoiderGame()[M:\Users\Andy\Documents\Programming For Fun\Flash\Tutorial - Avoider Game\Classes\AvoiderGame.as:29]

at States/changeState()[M:\Users\Andy\Documents\Programming For Fun\Flash\Tutorial - Avoider Game\States.as:26]

at mainMenu/brnP_Button()[M:\Users\Andy\Documents\Programming For Fun\Flash\Tutorial - Avoider Game\Classes\mainMenu.as:34]

Currently the way I've programmed my game is so that it starts in States.as which contains the following code.

package
{
import flash.display.*;
import flash.system.fscommand;

public class States extends MovieClip
{
    public function States()
    {
        changeState(null, "menu");
    }
    public function changeState (currentState, nextState)
    {
        if (currentState != null)
        {
            removeChild(currentState);
        }
        switch(nextState)
        {
            case "menu": var mm:mainMenu = new mainMenu(changeState); 
                         addChild(mm);
            break;
            case "game": var g:AvoiderGame = new AvoiderGame(changeState);
                         addChild(g);
            break;
            case "exit": fscommand("quit");
            break;
        }
    }

}

}

From there it will go into mainMenu.as until the user clicks play - inside mainMenu.as is the following code

package
{
import flash.display.*;
import flash.events.*;

public class mainMenu extends MovieClip
{
var theCallBackFunction:Function;

public function mainMenu(callBack)
{
    var Background:gameBackground;
    Background = new gameBackground();
    addChild(Background);

    var btnPlay:mmPlay = new mmPlay();
    btnPlay.addEventListener(MouseEvent.MOUSE_DOWN, brnP_Button);
    btnPlay.x = width/2;
    btnPlay.y = height/2 - btnPlay.height/2;
    addChild(btnPlay);

    var btnExit:mmExit = new mmExit();
    btnExit.addEventListener(MouseEvent.MOUSE_DOWN, brnE_Button);
    btnExit.x = width/2;
    btnExit.y = height/2 - btnExit.height/2;
    btnExit.y += btnExit.height + 4;
    addChild(btnExit);

    theCallBackFunction = callBack;
}
public function brnP_Button(e:MouseEvent)
{
    theCallBackFunction(this, "game");
    return;
}

public function brnE_Button(e:MouseEvent)
{
    theCallBackFunction(this, "exit");
    return;
}

}
}

Now this is where it goes wrong - it goes into AvoiderGame.as and it then kicks me back with an error which I don't know how to fix - Could anyone advise me on how to fix it?

package
{
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.Event;
import flash.events.TimerEvent;
import com.freeactionscript.CollisionTest;
import flash.display.Stage;

public class AvoiderGame extends MovieClip
{
    var theCallBackFunction:Function;

    public static var enemyArray:Array;
    public var enemy:Enemy
    public var Background:gameBackground;

    public var avatar:Avatar;
    public var gameTimer:Timer;

    private var _collisionTest:CollisionTest;
    private var numStars:int = 80;

    private var fireTimer:Timer; //causes delay between fires
    private var canFire:Boolean = true; //can you fire a laser

    public function AvoiderGame(callBack)
    {
        stage.addEventListener(Event.ADDED_TO_STAGE, init);
        theCallBackFunction = callBack;
    }

    private function init(e:Event):void
    {
        Background = new gameBackground();
        addChild(Background);

        enemyArray = new Array();
        var enemy = new Enemy(Math.round(1 + (500 - 1) * Math.random()), - 2, stage);
        enemyArray.push(enemy);
        addChild(enemy);

        avatar = new Avatar(stage);
        addChild(avatar);

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

        for (var i:int = 0; i < numStars; i++)
        {
            stage.addChildAt(new Star(stage), 1);
        }

        _collisionTest = new CollisionTest();

        gameTimer = new Timer(25);
        gameTimer.addEventListener(TimerEvent.TIMER, onTick);
        gameTimer.start();

        fireTimer = new Timer(300, 1);
        fireTimer.addEventListener(TimerEvent.TIMER, fireTimerHandler, false, 0, true);
        fireTimer.start();
    }

    public function onTick(timerEvent:TimerEvent):void 
    {
        if (Math.random() < 0.1)
        {
            trace('array length: ', AvoiderGame.enemyArray.length);
            enemy = new Enemy(Math.round(1 + (500 - 1) * Math.random()), - 28, stage);
            enemyArray.push(enemy);
            addChild(enemy);
        }

        avatar.UpdateAvatar(canFire);
        if (canFire == true)
        {
            canFire = false;
            fireTimer.start();
        }
        avatar.StayOnScreen();

        for each (var enemy:Enemy in enemyArray)
        {
            enemy.moveDown();
            enemy.StayOnScreen();
            if (_collisionTest.complex(enemy, avatar)) 
            {
                gameTimer.stop();
            }
        }
    }
    private function fireTimerHandler(e:TimerEvent) : void
    {
        //timer ran, we can fire again.
        canFire = true;
    }
}
}

回答1:


public function AvoiderGame(callBack)
{
    stage.addEventListener(Event.ADDED_TO_STAGE, init);
    theCallBackFunction = callBack;
}

Should be something like

public function AvoiderGame(callBack)
{
    this.addEventListener(Event.ADDED_TO_STAGE, init);
    theCallBackFunction = callBack;
}

Don't forget to remove the event listener when the init function is called.




回答2:


When a display object is not added to the stage or an other display object already in the display list, stage is null. Event.ADDED_TO_STAGE will be dispatched, when stage is set and available.




回答3:


When you create the AvoiderGame object, it wil fire the constructor. at this time, the object is not added to the stage or any object in the display list, so it will not have any reference to the stage.

You can add a listener to the ADDED_TO_STAGE event or call a custom init method before adding it to the stage manually.



来源:https://stackoverflow.com/questions/13444408/as3-stage-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!