如何使用Flash CS4中的链接类管理库符号以在Flash Builder 4中编译/调试?

时间:2010-04-02 16:33:44

标签: flex flash actionscript-3 flash-builder

我正在使用Flash CS4(以下简称“Flash”)构建一个视频播放器来创建图形符号,并使用Flash Builder 4(“FB4”)进行编译和调试。以下是我在当前工作流程中采取的步骤:

- 在Flash中创建图形符号。我为玩家创建了一些不同的符号,但我会在这里只关注播放/暂停按钮(“ppbutton”)。

- 在“库”面板中,我转到ppbutton符号的Linkage属性,并链接到一个名为assets.PlayPauseButtonAsset的类,该类扩展了MovieClip。我实际上没有资产包,也没有PlayPauseButtonAsset的类文件,因为Flash会在我发布时为我创建它们。

- 在Flash的发布设置中,我将项目设置为导出将在FB4中使用的SWC,名为VideoPlayerAssets.swc。

- 创建SWC后,我创建了名为“VideoPlayer”的FB4项目,并将SWC添加到我的路径中。 FB4会自动在默认包中创建VideoPlayer类。

- 在VideoPlayer.as中,我导入资产。*,它导入我在Flash中创建的所有符号类,并通过VideoPlayerAssets.swc提供。我现在可以实例化ppbutton并添加到舞台上,如下所示:

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

此时ppbutton没有任何功能,因为我没有为它创建任何代码。所以我创建了一个名为video.controls.PlayPauseButtonLogic的新类,它扩展了assets.PlayPauseButtonAsset。我添加了一些逻辑,现在我可以使用这个新类在舞台上放置一个有效的按钮:

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

这很好用,但你可能会问我为什么不首先将Flash中的ppbutton符号链接到video.controls.PlayPauseButtonLogic类。原因是我有一个设计师在Flash中创建UI,我不想每次在逻辑上进行更改时都必须从Flash重新发布SWC。基本上,我希望我的设计师能够在Flash中创建符号,将该符号链接到Linkage属性中的逻辑命名类,然后导出SWC。除非设计师对符号或布局进行更改,否则我不想再次触摸.fla文件。我也在为项目使用版本控制系统,确保只有设计师触摸.fla文件更清晰。

所以,最后,这是我遇到的问题:

- 随着设计变得越来越复杂,设计师正在嵌套符号以将视频控件定位在控制栏上。他创建了一个控制栏符号并将其链接到assets.ControlBarAsset。控制栏符号包含ppbutton符号。

- 设计师发布SWC和ControlBarAsset现在可在FB4中使用。我创建了一个名为video.controls.ControlBarLogic的新类,它扩展了assets.ControlBarAsset,所以我可以向控制栏添加一些逻辑,然后将控制栏添加到舞台:

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

- 这有效,但ppbutton没有做任何事情。那是因为ppbutton虽然在控制栏内,但仍然只链接到PlayPauseButtonAsset,后者没有任何逻辑。我不再实例化一个ppbutton对象,因为它是控制栏的一部分。

那是我今天被困的地方。我似乎不能简单地将控制栏的pp按钮重新投射为PlayPauseButtonLogic,因为我得到了一个Type错误。而且我不想创建一个必须实例化每个视频播放器控件的类,根据设计者放置它们的方式将它们放在舞台上的x和y值,因为这需要我打开.fla并检查符号的各种属性,然后将这些值添加到代码中。如果设计师做了改变,我每次只需更新这些属性就必须进入代码。不好。

如何重新嵌套嵌套符号以使用我创建的扩展资产类的逻辑类?请记住,解决方案不是将Flash符号链接到实际类,因此我不必继续重新编译SWC,除非有办法在不重新编译SWC的情况下执行此操作。我希望设计师做他的事情,发布SWC,并完成它。然后,我可以使用他的SWC,将我的逻辑应用于他的资产,并能够调试和编译最终的SWF。

3 个答案:

答案 0 :(得分:4)

以下是我有时使用的解决方案:

不要使PlayPauseButtonLogic扩展PlayPauseButtonAsset,而是使用此类作为PalyPauseButtonAsset的warpper,使用合成而不是继承! ; )。

您将在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)
}

希望它会帮助你

答案 1 :(得分:2)

你可以有两个类,一个持有功能,另一个提供图形实现(资产/皮肤)

让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()方法来清理你的实例之后也很棒,你可以确保删除所有添加的侦听器,并停止/停止定时器,声音等等。

答案 2 :(得分:0)

哇所有的流量,我们沉没在终点线......

好吧,这样的事情

  1. AbstractButtonBehavior
  2. PlayButtonBehavior extends ...
  3. 技巧,图形组件应该都实现一些接口,允许它们在实例化时传递行为,甚至更好,在运行时。您只需插入登录,逻辑将始终保持在外部,不良资产将继续询问或回答相同的接口呼叫,允许您在他们之外工作。
  4. 可能是?。