Как управлять символами библиотеки со связанными классами в Flash CS4 для компиляции / отладки в Flash Builder 4?

Я создаю видеоплеер, используя Flash CS4 (далее «Flash») для создания графических символов, компиляции и отладки с помощью Flash Builder 4 («FB4»). Вот шаги, которые я предпринимаю в своем текущем рабочем процессе:

- Создание графических символов во Flash. Я создал несколько разных символов для игрока, но здесь я остановлюсь только на кнопке воспроизведения / паузы («ppbutton»).

- На панели «Библиотека» я перехожу к свойствам Linkage символа ppbutton и связываюсь с классом с именем assets.PlayPauseButtonAsset, который расширяет MovieClip. На самом деле у меня нет пакета ресурсов и файла класса для PlayPauseButtonAsset, поскольку Flash создаст их для меня при публикации.

- В настройках публикации Flash я установил для проекта экспорт файла SWC, который будет использоваться в FB4, под названием VideoPlayerAssets.swc.

- После создания SWC я создаю свой проект FB4 под названием «VideoPlayer» и добавляю SWC в свой путь. FB4 автоматически создает класс VideoPlayer в пакете по умолчанию.

- В VideoPlayer.as я импортирую assets. *, Который импортирует все классы символов, которые я создал во Flash, и которые доступны через VideoPlayerAssets.swc. Теперь я могу создать экземпляр кнопки ppbutton и добавить его на сцену, например:

var ppbutton:PlayPauseButtonAsset = new PlayPauseButtonAsset();
addChild(ppbutton);

На данный момент ppbutton не имеет никаких функций, потому что я не создавал для него никакого кода. Поэтому я создаю новый класс с именем video.controls.PlayPauseButtonLogic, который расширяет assets.PlayPauseButtonAsset. Я добавляю логику, и теперь я могу использовать этот новый класс для размещения рабочей кнопки ppbutton на сцене:

var ppbutton:PlayPauseButtonLogic = new PlayPauseButtonLogic();
addChild(ppbutton);

Это нормально работает, но вы можете спросить, почему я просто не связал символ ppbutton во Flash с классом video.controls.PlayPauseButtonLogic в первую очередь. Причина в том, что у меня есть дизайнер, создающий пользовательский интерфейс во Flash, и я не хочу, чтобы мне приходилось повторно публиковать SWC из Flash каждый раз, когда я вношу изменения в логику. По сути, я хочу, чтобы мой дизайнер мог создать символ во Flash, связать этот символ с классом с логическим именем в свойствах Linkage и экспортировать SWC. Я не хочу снова прикасаться к этому файлу .fla, если дизайнер не внесет изменения в символы или макет. Я также использую систему управления версиями для проекта, и будет проще убедиться, что только дизайнер касается файла .fla.

Итак, наконец, вот проблема, с которой я сталкиваюсь:

- По мере усложнения дизайна дизайнер вкладывает символы, чтобы расположить элементы управления видео на панели управления. Он создает символ панели управления и связывает его с assets.ControlBarAsset. Символ панели управления содержит символ кнопки ppbutton.

- Дизайнер публикует SWC, и ControlBarAsset теперь доступен в FB4. Я создаю новый класс с именем video.controls.ControlBarLogic, который расширяет assets.ControlBarAsset, чтобы я мог добавить некоторую логику на панель управления, и добавляю панель управления на сцену:

var controlbar:ControlBarLogic = new ControlBarLogic();
addChild(controlbar);

--Это работает, но кнопка pp ничего не делает. Это потому, что ppbutton, находясь внутри панели управления, по-прежнему связан только с PlayPauseButtonAsset, что не имеет никакой логики. Я больше не создаю экземпляр объекта ppbutton, потому что он является частью панели управления.

Вот где я застрял сегодня. Кажется, я не могу просто повторно преобразовать ppbutton панели управления как PlayPauseButtonLogic, поскольку я получаю ошибку типа. И я не хочу создавать класс, который должен создавать экземпляры каждого из элементов управления видеопроигрывателем, размещать их на их значениях x и y на сцене в соответствии с тем, как их разместил дизайнер, поскольку для этого мне потребуется открыть .fla и проверьте различные свойства символа, затем добавьте эти значения в код. Если бы дизайнер внес изменения, мне пришлось бы каждый раз входить в код, чтобы каждый раз обновлять эти свойства. Фигово.

Как мне преобразовать вложенные символы, чтобы использовать созданные мной классы логики, расширяющие классы активов? Помните, что решение состоит не в том, чтобы связывать символы Flash с реальными классами, поэтому мне не нужно постоянно перекомпилировать SWC, если нет способа сделать это без повторной компиляции SWC. Я хочу, чтобы дизайнер сделал свое дело, опубликовал SWC и покончил с этим. Затем я могу взять его SWC, применить свою логику к его ресурсам и иметь возможность отлаживать и компилировать окончательный SWF.


person wpjmurray    schedule 02.04.2010    source источник


Ответы (3)


Вот решение, которое я иногда использую:

Вместо того, чтобы делать PlayPauseButtonLogic extends PlayPauseButtonAsset, используйте этот класс как преобразователь PalyPauseButtonAsset, используйте композицию вместо наследования! ; ).

Вы получите что-то вроде этого в своем классе ControlBarLogic:

//constructor exemple
public function ControlBarLogic(){
     //all logic of PPButton is inside PlayPauseButtonLogic
     //you just pass a reference to the PlayPauseButtonAsset button contained inside ControlBarAsset
     var ppButtonLogic: PlayPauseButtonLogic=new PlayPauseButtonLogic(refToButtonAsset)
     //the warper class can extends EventDispatcher so you will be able to listen to custom or redisatched events
     ppButtonLogic.addEventListener("ppPause",onPause)
}

надеюсь, это поможет тебе

person OXMO456    schedule 02.04.2010
comment
Согласитесь, вы можете быстро посмотреть, как работают компоненты / скины. - person Theo.T; 02.04.2010
comment
Должен ли я думать об этом с точки зрения графического актива, являющегося членом / свойством логического класса? Допустим, ControlBarLogic необходимо изменить положение ресурса ppbutton, изменив значение x. Поэтому вместо того, чтобы делать ppbutton.x = 100, мне действительно следовало бы вызвать для этого метод класса-оболочки, например ppbutton.setX (100), который затем обновил бы значение x внутреннего актива? - person wpjmurray; 03.04.2010
comment
Да, вы правы Это может показаться странным, но это единственный известный мне способ сохранить библиотеку FLA без кода и сохранить возможность создавать сложные экранные объекты непосредственно внутри Flash (экономия времени и возможность быстрого изменения вид приложения). Это хорошая тема, но, к сожалению, я недостаточно хорошо владею английским ... так что я не могу объяснить лучше, извините - person OXMO456; 03.04.2010
comment
Спасибо, OXM0456. На выходных я потратил немного времени на ваше решение, и, похоже, это хороший метод. Я столкнулся с несколькими проблемами, когда я должен помнить, что настройка событий немного отличается, поскольку теперь я применяю события мыши к активу, а не к самому классу, и я также не могу просто добавить прослушиватель событий к основному классу, который обычно получают всплывающее событие. В общем, это лучшее решение для моих нужд. Престижность. - person wpjmurray; 05.04.2010
comment
Я добавил награду за этот вопрос. если у вас есть что добавить - например, пример кода или какие-либо новые идеи - хотелось бы услышать это - person Simon_Weaver; 22.03.2011

У вас может быть два класса, один из которых содержит функциональные возможности, а другой обеспечивает его графическую реализацию (актив / скин).

Попросите PlayPauseButtonLogic расширить AssetWrapper.

Простой способ решить вашу проблему, касающуюся прослушивателей событий, вы можете сделать следующее:

package {

    import flash.display.DisplayObjectContainer;
    import flash.events.Event;
    import flash.events.IEventDispatcher;

    public class AssetWrapper implements IEventDispatcher {
        private var _skin:DisplayObjectContainer;

        public function AssetWrapper( skin:DisplayObjectContainer = null ) {
            if ( skin ) setSkin(skin);
        }

        public function setSkin(skin:DisplayObjectContainer):void{
            _skin = skin;           
        }


        public function dispatchEvent(event:Event):Boolean{
            _skin.dispatchEvent(event);
        }

        public function hasEventListener(type:String):Boolean{
            return _skin.hasEventListener(type);
        }

        public function willTrigger(type:String):Boolean{
            return _skin.willTrigger(type);
        }

        public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void{
            _skin.removeEventListener(type, listener, useCapture);
        }

        public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void{
            _skin.addEventListener(type, listener, useCapture, priority, useWeakReference);
        }


    }
}

РЕДАКТИРОВАТЬ: вы можете, конечно, просто добавить столько свойств / методов в AssetWrapper, которые делегируют DisplayObject (скин), сколько вам нужно. Это также дает вам больше контроля над этими свойствами / методами. то есть:

public function get x( ):Number {
    return _skin.x;
}

public function set x( v:Number ):void {
    if ( _skin.x = v ) return;
    if ( _useWholePixels ) _skin.x = Math.round(v);
    else _skin.x = v;
}

Таким образом, например, вы можете напрямую управлять своим экземпляром AssetWrapper. Кроме того, вы можете указать, хотите ли вы, чтобы он был размещен в круглых числах (x = 100) или нет (x = 100,5)

Для методов все та же идея:

public function addChild( child:DisplayObject ):DisplayObject {
    return _skin.addChild( child );
}

Затем, чтобы использовать его, вы должны расширить AssetWrapper и реализовать конкретное поведение:

package {
    import flash.display.DisplayObjectContainer;
    import flash.events.MouseEvent;


    public class SimpleButton extends AssetWrapper {


        public function SimpleButton( skin:DisplayObjectContainer = null ) {
            super(skin)
        }

        override public function setSkin( skin:DisplayObjectContainer):void {
            super.setSkin( skin );      
            addEventListener(MouseEvent.ROLL_OVER, _onRollOver );
            addEventListener(MouseEvent.ROLL_OUT, _onRollOut );         
        }

        protected function _onRollOver(e:MouseEvent):void {
            _skin.alpha = .5;
        }
        ...
}

И вы бы использовали его следующим образом:

//you can get your graphical assets in many different ways
var buttonSkin:Sprite = new LibraryButtonSkin
//or
var ButtonSkinClass:Class = this.loaderInfo.applicationDomain.getDefinition("SimpleButtonSkin") as Class;
buttonSkin = new ButtonSkinClass;

var button:SimpleButton = new SimpleButton(buttonSkin);
button.addEventListener(MouseEvent.CLICK, _handleButton);

Это просто руководство, в реальной реализации вы хотите убедиться, что вы проверяете такие вещи, как наличие кожи, а затем удалите всех добавленных слушателей. Вы, вероятно, могли бы прослушивать событие ADDED_TO_STAGE и запускать метод инициализации ... Также отлично подходит для очистки после вашего экземпляра, реализуя метод destroy (), где вы убедитесь, что все добавленные прослушиватели удалены и обнуляете / останавливаете такие вещи, как таймеры , звуки и т. д.

person goliatone    schedule 24.03.2011
comment
@ OXMO456: Это упрощенная версия базового класса, которую я использую снова и снова. Исходный класс реализует интерфейс, который в основном содержит все или почти все методы Sprite, а затем просто делегирует вызовы скину ... - person goliatone; 26.03.2011
comment
я делал аналогичные вещи (IDisplayObject), но меня не убедили (переключение с fp9 на fp10, addChild (DisplayObject (myIDisplayObject)), я решил последний с помощью функции getDisplayObject в моем интерфейсе) ... но в этом контексте я думаю, это действительно хорошо! Молодец ! - person OXMO456; 26.03.2011
comment
спасибо за обертку. не могли бы вы добавить образец «завернутого» объекта, чтобы продемонстрировать его использование. а как насчет таких участников, как addChild. разве они не должны быть в AssetWrapper, чтобы вы могли легко добавлять динамически созданные дочерние объекты? - person Simon_Weaver; 29.03.2011
comment
@Simon_Weaver: По сути, идея состоит в том, чтобы просто использовать AssetWrapper как своего рода прокси. Что касается образца, я отредактирую asnwer. - person goliatone; 29.03.2011

Ничего себе поток и мы на финише потонули ....

ну как насчет этого

  1. AbstractButtonBehavior
  2. PlayButtonBehavior расширяет ...
  3. Хитрость заключается в том, что все графические компоненты должны реализовывать некоторый интерфейс, который позволяет им передавать поведение во время создания экземпляра или, что еще лучше, во время выполнения. Если вы просто подключите логин, логика всегда будет оставаться снаружи, а плохие ресурсы будут продолжать спрашивать или отвечать на один и тот же вызов интерфейса, позволяя вам работать вне их.

может быть?.

person user2846564    schedule 04.10.2013