Flash CS5 Отображение различных «экранов» на сцене в виде видеоклипов - PullRequest
1 голос
/ 03 августа 2011

Вывод этой темы на следующий уровень и создание класса Main.as для отображения различных "экранов" моей игры.На данный момент у меня есть только 1 экран с именем ControlPanel, но в конечном итоге он будет иметь несколько уровней (каждый уровень будет отдельным экраном), а также экран выбора уровня и т. Д.Так что в этот момент я теряю контроль над тем, как дать вещам доступ к сцене (другими словами ... это становится действительно густым с несколькими уровнями, и мозг этого нуба перегружен, смеется).

Для началаВыключив, я взял всю свою графику, которая была на сцене по умолчанию (кнопки, источники света, метры, текст партитуры и т. д.), и создал новый символ (MovieClip), который я назвал ControlPanel, и выбрал «Экспорт для ActionScript» симя класса ControlPanel.Так что теперь моя стадия игры черная, и я создал класс документов Main.as.что выглядит следующим образом:

public class Main extends MovieClip {

    public var controlPanel:ControlPanel;

    public function Main() {
        addEventListener(Event.ADDED_TO_STAGE, added);
    }

    private function added(evt:Event):void {
        removeEventListener(Event.ADDED_TO_STAGE, added);

        controlPanel = new ControlPanel(this);
        addChild(controlPanel);
    }
}

Запуск этого сработал отлично в том, что мой экран панели управления появился прямо на экране.Конечно, все кнопки еще не работали, но это следующий шаг.Поэтому я изменил свой старый Game.as так, чтобы он теперь назывался ControlPanel, и читал так:

public class ControlPanel extends MovieClip {
    private var docRef:Main;

    private var _player:Player;
    private var _controller:Controller;

    public function ControlPanel($docRef:Main):void {
        this.docRef = $docRef;

        addEventListener(Event.ADDED_TO_STAGE, added);
    }

    private function added(evt:Event):void {
        removeEventListener(Event.ADDED_TO_STAGE, added);

        _player = new Player(docRef);
        _controller = new Controller(_player, docRef);

        addChild(_player);
    }

Теперь это добавляет мой класс Player и мой класс Controller.Они в основном имеют похожую косметику, поэтому я просто собираюсь показать класс Player.as здесь:

public class Player extends MovieClip {
    private var docRef:Main;
    private var _lights:uint;

    public function Player($docRef:Main):void {
        this.docRef = $docRef;

        addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    }

    private function lightsOut():void {
        switch(_lights) {
        case 1:
        docRef.controlPanel.greenLight1.visible=false;
        break;
        case 2:
        docRef.controlPanel.greenLight2.visible=false;//works
        break;
        case 3:
        docRef.controlPanel.greenLight3.visible=false;//works
        break;
        }
    }

Проблема в том, что теперь, когда я пытаюсь его протестировать, у меня больше нет контроляГрафическое изображение, которое я видел раньше, но теперь я получаю сообщение об ошибке:

Ошибка типа: Ошибка # 1009: Не удается получить доступ к свойству или методу ссылки на пустой объект.в ControlPanel () в Main / Added ()

Также я закомментировал строки controlPanel в Main и просто сделал трассировку (это);и он вернул

[объект Main]

Разве это не должен быть объект Stage или что-то в этом роде?Никогда раньше не пробовал, поэтому я не знаю, что это было раньше.Где я тут ошибся?

ОБНОВЛЕНИЕ: ОК, так что мой Контроллер не просто как класс Player, а нуждается в экземплярах как сцены, так и представления, возможно, переданного ему ???Итак, вот что у меня есть для контроллера и некоторых прослушивателей событий, которые необходимы:

public class Controller extends MovieClip {
    private var _model:Object;
    private var _dHandle:Object;
    private var panelView:ControlPanelView; //started playing with this idea but maybe that is the wrong way to go?? Stick with docRef here? or both?

    public function Controller(model:Object, dHandle:Object, $view:ControlPanelView):void {
        this._model = model;
        this._dHandle = dHandle;
        this.panelView = $view;

        docRef.stage.addEventListener(KeyboardEvent.KEY_DOWN, processKeyDown);
        docRef.stage.addEventListener(MouseEvent.MOUSE_DOWN, processMouseDown);
        docRef.ControlPanelView.fireButton.addEventListener(MouseEvent.CLICK, processFirePress);
        docRef.ControlPanelView.cWButton.addEventListener(MouseEvent.CLICK, processCWPress);
        docRef.ControlPanelView.cCWButton.addEventListener(MouseEvent.CLICK, processCCWPress);

Как вы можете видеть, это мешанина идей, разрывающихся между docRef и идеей View.Мне нужно иметь доступ к сцене для моих слушателей мыши и клавиатуры, но тогда мне также нужен доступ к кнопкам в символе ControlPanelView.Нужно ли передавать здесь и вид, и документ?Как сохранить доступ к сцене и графике ControlPanelView?

1 Ответ

1 голос
/ 03 августа 2011

Нельзя экспортировать что-либо из библиотеки и файл класса с тем же именем.Когда вы устанавливаете для элемента библиотеки значение «Экспорт для ActionScript», Flash создает класс с таким именем для представления этого объекта, и поэтому последующее создание класса с таким же именем приведет к конфликту.

У вас естьЕсть два варианта действий:

Наследование

Вы можете использовать класс, созданный для вашей ControlPanel, в качестве базы кода для символа в вашей библиотеке.Для этого сначала дайте ему другое имя, скажем ControlPanelBase.Затем вы можете назначить его базовым классом вашего символа.Это можно сделать в среде IDE, перейдя в свойства своего символа и изменив базовый класс с flash.display.MovieClip на ControlPanelBase (или любое другое имя, которое вы выберете).Нажмите на маленькую зеленую галочку, чтобы убедиться, что класс найден, затем нажмите OK.

Теперь, когда вы создаете новую ControlPanel с использованием нотации new ControlPanel(this), она создаст объект, который использует графику, но такжекод из базового класса.Поскольку вы наследуете, вам нужно будет изменить все вхождения слова private на protected, чтобы их могли видеть любые классы-потомки.

Разделите представление

Это мое предпочтение, потому что, когда вы прекращаете использовать IDE для чего-то большего, чем просто для генерации пакетов ресурсов, вам не нужно перекомпилировать свои активы при каждом изменении кода.

Измените имя символа вашей библиотеки на что-то большееописательный, как ControlPanelView.Теперь, когда вы создаете свою ControlPanel, используя new ControlPanel(this), она не будет прикреплять графику, поэтому вам нужно будет сделать это самостоятельно:

public class ControlPanel extends MovieClip {
    private var docRef:Main;

    private var _player:Player;
    private var _controller:Controller;

    public var view:ControlPanelView; //note that this is public

    public function ControlPanel($docRef:Main):void {
        this.docRef = $docRef;

        addEventListener(Event.ADDED_TO_STAGE, added);
    }

    private function added(evt:Event):void {
        removeEventListener(Event.ADDED_TO_STAGE, added);

        view = addChild(new ControlPanelView()) as ControlPanelView; //add the graphics

        _player = new Player(docRef);
        _controller = new Controller(_player, docRef);

        addChild(_player);
    }
}

Теперь, чтобы получить доступ к этим источникам света из Player, вы бы сказали

docRef.controlPanel.view.greenLight1.visible=false;

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

в ControlPanel:

_player = new Player(view);

новый Класс игрока:

public class Player extends MovieClip {
    private var panelView:ControlPanelView;
    private var _lights:uint;

    public function Player($view:ControlPanelView):void {
        this.panelView = $view;

        addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    }

    private function lightsOut():void {
        switch(_lights) {
        case 1:
        panelView.greenLight1.visible=false;
        break;
        case 2:
        panelView.greenLight2.visible=false;//works
        break;
        case 3:
        panelView.greenLight3.visible=false;//works
        break;
        }
    }
}

Относительно вашего обновленияпомните, что ваш основной класс и сцена не одно и то же.Каждый экранный объект имеет свойство stage, которое будет указывать на одно и то же.Это означает, что для добавления слушателей на сцену нет никакой разницы между Main.stage, view.stage и this.stage (при условии, что контроллер находится на сцене).Таким образом, ваш контроллер может выглядеть следующим образом:

public class Controller extends EventDispatcher {
    private var _model:Player;
    private var panelView:ControlPanelView;

    public function Controller($model:Player, $view:ControlPanelView):void {
        this._model = $model;
        this.panelView = $view;

        panelView.stage.addEventListener(KeyboardEvent.KEY_DOWN, processKeyDown);
        panelView.stage.addEventListener(MouseEvent.MOUSE_DOWN, processMouseDown);
        panelView.fireButton.addEventListener(MouseEvent.CLICK, processFirePress);
        panelView.cWButton.addEventListener(MouseEvent.CLICK, processCWPress);
        panelView.cCWButton.addEventListener(MouseEvent.CLICK, processCCWPress);
    }
}

, а в ControlPanel вы можете создать его следующим образом:

_controller = new Controller(_player, view);

Обратите внимание, что я также заставил ваш контроллер расширяться EventDispatcher , а не MovieClip.Хорошей практикой является расширение от необходимого минимального класса, который вам нужен, поэтому, если этого никогда не будет на сцене, но он будет генерировать события, EventDispatcher является минимальным.Если ему никогда не понадобится отправлять события, только добавлять слушателей к другим, тогда ему не нужно ничего расширять.

По сути, расширяйте MovieClip только в том случае, если вам нужна функциональность временной шкалы или ваш класс будет базовым классом для чего-либов библиотеке.Для любого другого стандартного экранного объекта вы должны расширить либо Sprite или Shape , первый, если вы собираетесь добавить потомков, второй, если вы только собираетесь рисовать векторную графику.Если ваш объект никогда не попадает в дерево отображения, чаще всего вам потребуется расширить либо EventDispatcher, либо вообще ничего.

...