Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Не работает прослушиватель KeyboardEvent, а использование stage выдает ошибку (http://www.flasher.ru/forum/showthread.php?t=199016)

Jim 11.05.2013 14:01

Не работает прослушиватель KeyboardEvent, а использование stage выдает ошибку
 
Вложений: 2
Добрый день! Сказали, что вопрос довольно простой для вас, опытных.
Скачал шаблон игрового меню, поковырял, разобрался что к чему. И столкнулся с проблемой, которую не могу локализовать.

Шаблон в скомпилированном виде:
anatomy.swf   (17.9 Кб)


Пытаясь добавить прослушиватель клавиатуры в класс отвечающий за отображение игры, не получаю никакой отдачи, хотя прослушиватель мыши работает как надо. Если приписываю к прослушивателю stage (ровно, как и к любой другой команде), при запуске уровня (уточняю: при запуске уровня, не при компиляции; меню запускается нормально) получаю ошибку следующего содержания:
Цитата:

TypeError: Error #1009: Не удается вызвать свойство или метод со ссылкой на объект "null".
at the_game_itself()
at the_game/play_the_game()
at level_thumbnail/on_level_clicked()
??? :o Не приложу ума, в чем тут может быть загвоздка? Пробовал создать прослушиватель отдельным классом, вызвать addChild'ом - реакции те же.
Если это не напряжно, помогите, пожалуйста, понять как эту неприятность поправить.

Набор классов шаблона содержит 3 класса, которые описывает ошибка (написано много, но код довольно простой и повторяется):

the_game.as
Код AS3:

package {
        import flash.display.Sprite;
        public class the_game extends Sprite {
                public var splash_screen:splash; //создаем переменную MovieClip'а экрана меню из fla-библиотеки, содержащую необходимый текст и кнопки. Переменные ниже - то же самое
                public var play_screen:the_game_itself;
                public var game_over_screen:game_over;
                public var level_select_screen:level_selection;
                public var how_to_play_screen:how_to_play;
                public var congratz_screen:game_won;
                public function the_game() {
                        show_splash();
                }
                public function show_splash() {
                        splash_screen = new splash(this);
                        how_to_play_screen=remove_movie_clip(how_to_play_screen);
                        level_select_screen=remove_movie_clip(level_select_screen);
                        game_over_screen=remove_movie_clip(game_over_screen);
                        congratz_screen=remove_movie_clip(congratz_screen);
                        addChild(splash_screen);
                }
                public function show_how_to_play() {
                        how_to_play_screen = new how_to_play(this);
                        splash_screen=remove_movie_clip(splash_screen);
                        addChild(how_to_play_screen);
                }
                public function show_game_over(level) {
                        game_over_screen = new game_over(this,level);
                        play_screen=remove_movie_clip(play_screen);
                        addChild(game_over_screen);
                }
                public function show_congratz(level) {
                        congratz_screen = new game_won(this,level);
                        play_screen=remove_movie_clip(play_screen);
                        addChild(congratz_screen);
                }
                public function select_the_level() {
                        level_select_screen = new level_selection(this);
                        splash_screen=remove_movie_clip(splash_screen);
                        how_to_play_screen=remove_movie_clip(how_to_play_screen);
                        game_over_screen=remove_movie_clip(game_over_screen);
                        congratz_screen=remove_movie_clip(congratz_screen);
                        addChild(level_select_screen);
                }
                public function play_the_game(level) {
                        play_screen = new the_game_itself(this,level);
                        level_select_screen=remove_movie_clip(level_select_screen);
                        game_over_screen=remove_movie_clip(game_over_screen);
                        congratz_screen=remove_movie_clip(congratz_screen);
                        addChild(play_screen);
                }
                private function remove_movie_clip(clip:*) {
                        if (clip) {
                                removeChild(clip);
                        }
                        return null;
                }
        }
}

level_thumbnail.as
Код AS3:

package {
        import flash.display.Sprite;
        import flash.events.MouseEvent;
        import flash.text.*;
        import flash.net.SharedObject;
        public class level_thumbnail extends Sprite {
                public var main_class:the_game;
                public var level_number:int;
                public var shared:SharedObject;
                public function level_thumbnail(i:int,passed_class:the_game) {
                        shared = SharedObject.getLocal("savegame");
                        if (shared.data.level_passed==undefined) {
                                shared.data.level_passed=1;
                        }
                        if (shared.data.level_passed<i) {
                                alpha = 0.5;
                        }
                        else {
                                this.buttonMode = true;
                                this.mouseChildren = false;
                                addEventListener(MouseEvent.CLICK, on_level_clicked);
                        }
                        main_class = passed_class;
                        level_number = i;
                        y = i*60-10;
                        leveltext.text = "Level "+i;
                        shared.close();
                }
                public function on_level_clicked(event:MouseEvent) {
                        main_class.play_the_game(level_number);
                }
        }
}

the_game_itself.as
Код AS3:

package {
        import flash.display.Sprite;
        import flash.display.SimpleButton;
        import flash.events.MouseEvent;
        import flash.events.KeyboardEvent;
        import flash.text.*;
        public class the_game_itself extends Sprite {
                public var main_class:the_game;
                public var current_level:int;
                public function the_game_itself(passed_class:the_game,level:int) {
                        current_level = level;
                        gametext.text = "Playing level "+level;
                        main_class = passed_class;
                        die_button.addEventListener(MouseEvent.CLICK, on_die_button_clicked);
                        win_button.addEventListener(MouseEvent.CLICK, on_win_button_clicked);
                        //stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); // Вызывает ошибку 1009
                        addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); // Ошибок не вызывает, но не работает
                }
 
                public function keyPressed(event:KeyboardEvent) {
            trace("Contact");
        }
 
                public function on_die_button_clicked(event:MouseEvent) {
                        main_class.show_game_over(current_level);
                }
                public function on_win_button_clicked(event:MouseEvent) {
                        main_class.show_congratz(current_level);
                }
        }
}

Во вложениях залил архив с исходником, если описанных классов не хватит.
Понимаю, что просьба - просмотреть относительно большой объем кода, но уже не знаю, к кому или куда обратиться.

TWETTI 11.05.2013 14:08

Чтобы прослушивать события клавиатуры в визуальном классе, нужен доступ к stage. Изначально, при создании экземпляра класса доступа к stage нет. Когда экземпляр добавляется на сцену вызывается событие Event.ADDED_TO_STAGE и ему становится доступен stage.
Напишите в контрукторе класса:
Код AS3:

if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);

Затем напишите код функции init:
Код AS3:

private function init(event:Event = null):void
{
    stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}


Jim 11.05.2013 14:23

Спасибо за быстрый ответ!
Попробовал внести Ваши правки в код - ошибок нет, но программа все еще не реагирует на клавиатуру.

Сейчас класс выглядит так:
Код AS3:

package {
        import flash.display.Sprite;
        import flash.display.SimpleButton;
        import flash.events.MouseEvent;
        import flash.events.KeyboardEvent;
        import flash.events.Event;
        import flash.display.Stage;
        import flash.text.*;
        public class the_game_itself extends Sprite {
                public var main_class:the_game;
                public var current_level:int;
                public function the_game_itself(passed_class:the_game,level:int) {
                        current_level = level;
                        gametext.text = "Playing level "+level;
                        main_class = passed_class;
                        die_button.addEventListener(MouseEvent.CLICK, on_die_button_clicked);
                        win_button.addEventListener(MouseEvent.CLICK, on_win_button_clicked);
                        //stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); // Вызывает ошибку 1009
                        //addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); // Ошибок не вызывает, но не работает
 
 
                        if (stage) { init(); }
                        else { addEventListener(Event.ADDED_TO_STAGE, init); }
 
                }
 
                private function init(event:Event = null):void
                {
                        stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
                }
 
                public function keyPressed(event:KeyboardEvent) {
            trace("Contact");
        }
 
                public function on_die_button_clicked(event:MouseEvent) {
                        main_class.show_game_over(current_level);
                }
                public function on_win_button_clicked(event:MouseEvent) {
                        main_class.show_congratz(current_level);
                }
        }
}


caseyryan 11.05.2013 14:56

Кэп мне подсказывает, что нужно создать экземпляр этого класса и добавить его в список отображения.

А вообще, слушатель конечно лучше вешать на stage, Но это не является обязательным условием. На клавиатуру будет реагировать любой объект, унаследованный от DisplayObject находящийся в фокусе.

Jim 11.05.2013 15:31

Все заработало! Да, была проблема с фокусом.
Программу привела в работу комманда
Код AS3:

this.stage.focus = this.stage;

Спасибо большое! :)

caseyryan 11.05.2013 17:15

А вообще, настоятельно рекомендую изучить конвенции написания кода на ас3 чтобы не писать такой нечитаемый код в будущем.

Jim 11.05.2013 17:50

Изучу, спасибо.


Часовой пояс GMT +4, время: 08:24.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.