如何在AS3中引用swf中的元件、图片等资源以及布局信息

来源:互联网 发布:综合管线设计软件 编辑:程序博客网 时间:2024/06/04 20:02
 

       凡是要被AS3引用的外部swf中的图片或者元件等资源都必须要在FLash编辑器中给它们一个“AS链接”,如:
 
“AS链接”的实质就是相当于在新建元件时的“导出成ActionScript”选项,只是“AS链接”的方式比较方便快捷。在给定“AS链接”之后,相应的元件或图片就会对应于一个类定义,如按钮继承SimpleButton类,影片剪辑继承MovieClip,图形继承Shape类,位图相当于BitmapData,而“AS链接”就会成为该类的名字。所以,在AS3中可以这样取得这些类定义:
package{ //省略相关import代码  public class BagDemo extends Sprite {  private var _bagPanelLoader:Loader;//加载背包swf   private var _mcBagPanel:MovieClip;//整个背包的影片剪辑  private var _btnClose:SimpleButton;//关闭按钮  private var _imgBagObj:Bitmap;//代表物品的位图   //构造函数  public function BagDemo()  {   loadBagSWF();//加载swf  }   //加载swf  private function loadBagSWF():void  {   _bagPanelLoader = new Loader;   /*添加事件响应,在swf加载完毕后再获取里面的资源*/   _bagPanelLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadComplete);   /*新建加载器上下文,再新建应用程序域*/   var context:LoaderContext = new LoaderContext();   context.applicationDomain = new ApplicationDomain();   /*开始加载swf*/   _bagPanelLoader.load(new URLRequest("../bag.swf"),context);  }   private function onComplete(e:Event):void  {   /*获得加载器的应用程序域*/   var domain:ApplicationDomain = (e.currentTarget as LoaderInfo).applicationDomain;   /*可以这样获取bag.swf中的bag_panel影片剪辑*/   var cls:Class = domain.getDefinition("bag_panel") as Class;   _mcBagPanel = new cls() as MovieClip;   addChild(_mcBagPanel);   /*可以这样获取bag.swf中的btn_close按钮*/   cls = domain.getDefinition("btn_close") as Class;   _btnClose = new cls() as SimpleButton;   addChild(_btnClose);       /*在资源中有个AS链接为img_1091806133的位图,可以这样加载*/   cls = domain.getDefinition("img_1091806133") as Class;   var imgdataBagObj:BitmapData = new cls() as BitmapData;   _imgBagObj = new Bitmap( imgdataBagObj );   addChild(_imgBagObj);  } }}


       上面的只是示例,一般来说若不含元件,而仅仅是位图的话,行业内的做法一般都是直接用Loader从外部加载位图,而不会将它打包成swf,因为swf一加载就必须将整个加载进去,若位图资源多了的话,内存占用量会特别大,所以一般还是使用Loader从外部按需加载位图。

       唉?一个swf内保存着类的定义,而我从swf中取得一个类定义之后new了一个实例出来,加入到舞台的显示列表中,那么该实例的默认位置就是(0,0),而不是在FLash编辑器中元件摆放好的位置,那我用Flash做资源布局的的工作岂不是白费了吗?如何才能够获得元件的位置信息呢?
       这里我们需要弄清一些问题。在Flash编辑器的舞台上能够让我们看到的东西实际上就是已经存在了的库中元件的实例,而库中列出来的东西其实就相当于类定义。注意,库中的是类定义,舞台上显示的是类的实例。所以我们要获得的不是元件的类定义,而是已经存在在舞台上的元件实例,再获得实例的位置信息。
       虽然我们能够看到Flash编辑器舞台上的实例,但是swf保存的实际上只有定义,而不会单独保存一个实例,所以这里需要一个小技巧——将所有摆放好位置的元件再包装成一个新的复合的元件,也就是一个元件中还包含很多元件,复合元件可以保存子元件的位置信息。那么只要我们获取了这个复合元件的定义并new了出来,里面的子元件的布局信息自然就可以得到了。
       现在我要获得内部子元件,这又要怎么办呢?在上面的截图中,其实背包面板bag_panel就是一个复合元件,它其实就是其他元件组合起来的新元件,第一幅图片就是它的样子。比如我要获得bag_panel内的关闭按钮btn_close的实例,可以这么做:

       为背包面板中的关闭按钮实例取一个名字,可以看到他叫close_btn,在代码中就可以这样获取了:
//上面的代码已经将_mcBagPanel加载进来了,这里就直接用了。有上图可以看到关闭按钮btn_close的实例名为close_btnvar closeButton : SimpleButton = _mcBagPanel.getChildByName("close_btn") as SimpleButton;

       其实还有一种更美观的写法:
//上面的代码已经将_mcBagPanel加载进来了,这里就直接用了。有上图可以看到关闭按钮btn_close的实例名为close_btnvar closeButton : SimpleButton = _mcBagPanel["close_btn"] as SimpleButton;

       这是利用了AS3中的关联数组的语法。我想复合元件的内部其实就是用Array的方式保存子元件的吧。

       要讲的内容到此结束,下面是乱七八糟堆码后的效果(有拖拽功能的,截图截不了鼠标,悲哀):


0 0
原创粉丝点击