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

Я создаю видеоплеер, используя 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. Теперь я могу создать экземпляр кнопки pp и добавить на сцену, например:

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

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

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

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

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

- По мере усложнения дизайна дизайнер вкладывает символы для размещения элементов управления видео на панели управления. Он создает символ панели управления и связывает его с активами. ControlBarAsset. Символ панели управления содержит символ кнопки pp.

- Дизайнер публикует 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.

Ответы [ 3 ]

4 голосов
/ 02 апреля 2010

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

Вместо создания 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)
}

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

2 голосов
/ 24 марта 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);
        }


    }
}

EDIT: Тогда вы, конечно, можете просто добавить столько свойств / методов в 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. Кроме того, вы можете контролировать, хотите ли вы, чтобы он был помещен в круглые числа (х = 100) или нет (х = 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 (), где вы убедитесь, что все добавленные слушатели удалены, и обнулите / остановите такие вещи, как таймеры, звуки и т. Д.

0 голосов
/ 04 октября 2013

Ух ты весь поток и мы утонули в финишной черте ....

хорошо, а что-то вроде этого

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

может быть?.

...