TypeError: Ошибка # 1009 ActionScript 3 при загрузке внешнего SWF


Я начал работать над учебником по игре «Флэш-стрелялка» и закончил его Asgamer Shoot em upp Game
Теперь я начал создавать новый .fla, который является главным меню, и у меня есть кнопка воспроизведения, поэтому, когда я нажимаю на нее, она загрузите .swf (Game swf), но когда я нажимаю кнопку, я получаю следующую ошибку.

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
    }

РЕДАКТИРОВАТЬ: Спасибо Viper за решение этой проблемы!


person Tony Zach    schedule 26.04.2013    source источник
comment
Скорее всего, ваша игра SWF была создана с уже назначенным stage, в то время как в этом содержимом его свойство stage еще имеет значение null, поскольку оно загружено, но нигде не добавлено. Итак, где бы вы ни обратились к stage в SWF-файле игры, создайте Event.ADDED_TO_STAGE прослушиватель и поместите туда весь код, который обращается к stage, также не позволяйте продолжить, пока stage имеет значение null. Кроме того, недостаточно инициировать загрузку SWF, вы можете дождаться завершения загрузки.   -  person Vesper    schedule 26.04.2013
comment
Прежде всего, спасибо за быстрый ответ, потому что я новичок в as3, где мне разместить Event.ADDED_TO_STAGE?   -  person Tony Zach    schedule 26.04.2013
comment
Это зависит от того, какие части кода и какие классы относятся к stage из своего конструктора. По крайней мере, это Ship класс. Пересмотрите всю свою кодовую базу для конструкторов, которые вызывают stage.something внутри себя, это приведет к ошибке 1009, если вы им позволите. Вместо этого вставьте if (stage) init(null); else addEventListener(Event.ADDED_TO_STAGE,init); строку в конец каждого из них и реализуйте function init(e:Event):void { removeEventListener(Event.ADDED_TO_STAGE,init); ...}, который будет обрабатывать все, что нужно вашему классу на этапе.   -  person Vesper    schedule 26.04.2013
comment
Извините, я снова отредактировал свой вопрос, чтобы вы могли видеть код из моего класса Engine () и код, который вы мне дали, чтобы я мог понять, как я могу его изменить   -  person Tony Zach    schedule 26.04.2013
comment
Итак, ваш Engine класс имеет предварительно размещенный экземпляр на сцене во время разработки. Правильно, это обычная проблема решения stage в конструкторах. Да, вам нужно сделать именно это, за исключением того, что Engine() return void - это все еще конструктор. Итак, public function Engine() { вместо : void.   -  person Vesper    schedule 26.04.2013
comment
public function Engine() { я меняю это, но все равно получаю ошибку 1009   -  person Tony Zach    schedule 26.04.2013
comment
Контекст ошибки такой же, in Engine() in Ship() или где-то еще?   -  person Vesper    schedule 26.04.2013
comment
и на at com.senocular.utils::KeyObject/construct() at com.senocular.utils::KeyObject() я разместил два .as Engine и Ship, и я не могу понять, как вставить код, который вы мне дали.   -  person Tony Zach    schedule 26.04.2013
comment
Фактически, вы делаете именно это: заменяете заголовок конструктора на private function initialize(e:Event = null):void, добавляете оператор removeEventListener в качестве первой строки, затем добавляете новый конструктор, как вы его написали, и проверяете. Также обновите вопрос, если вы получите еще 1009.   -  person Vesper    schedule 26.04.2013
comment
Можно ли отредактировать мой код, потому что я не знаю, что изменить   -  person Tony Zach    schedule 26.04.2013


Ответы (1)


Измените конструктор Engine на следующий:

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);
}

Основная проблема заключается в том, что ваш класс Engine написан в предположении, что stage уже доступен, но когда вы загружаете SWF, его stage имеет значение null, а этот SWF не добавляется в сцену. Чтобы обойти это, обычно используют прослушиватель Event.ADDED_TO_STAGE и начинают размещать там свой код вместо конструктора.

person Vesper    schedule 26.04.2013
comment
Чтобы отметить вопрос как решенный, поставьте галочку под тем ответом, который помог вам больше всего. Это помогает улучшить StackOverflow как сообщество и увеличивает шансы, что кто-то ответит на ваши вопросы в будущем. - person Vesper; 26.04.2013