AS3的精典功能经验技巧
作者:aaron 日期:2009-01-13
在L4cd的BLOG上看到几个比较好的文章,现在整理一下,统一发布,感谢Lc4d共享他的经验
1.getDefinition - 模块化你的程序
为了加快程序的加载..
我们通常会把不同的功能模块做成不同的swf,要需要的时候再进行加载.
开始的时候..我们通常会直接使用loader加载,,然后用addChild把loader显示出来..
这样就完成了最简单的"模块"化了..
当然进一步..我们会发现上面的方法已经满足不了我们的需求..
有时候我们需要的不是一个实例对象,我们想得到的是一个类..让我们可以像调用自身库中的类一样可以实例化..复制..等等
这时候我们就可以使用ApplicationDomain(应用程序域),把加载进来的swf中的库的东西当自己的库一样使用
概念性的东西还是不好说...
直接看代码吧..下面的代码就是一个最简单的例子
- //还是需要loader先进行加载
- var loader:Loader = new Loader()
- loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderComplete)
- //sub.swf是一个外部swf,该swf库里有一个链接名叫"k_abc"元件
- loader.load(new URLRequest("sub.swf"))
- function loaderComplete(e:Event):void{
- //创建一个应用程序域
- var app:ApplicationDomain = loader.contentLoaderInfo.applicationDomain
- //使用getDefinition返回sub.swf的库中链接名为k_abc的Class
- var c:Class = app.getDefinition("k_abc") as Class
- //接下来就不多说了..像普通的类一样操作就
2.AS3中for循环创建(复制)对象
在as2中,我们经常使用for来创建或复制多个相同的对象,
到了as3,由于建立对象的方法的改变,以前的方法已经不适用了.
今天介绍一下as3的方法:
方法常用的有两种,
第一种适用所有的对象,方法是先建一个数组,然后把建立的对象的引用指定对数组相应的索引
第二种适用显示对象,其实在as3中,都应该用这种方式,就是给对象指定name,然后使用getChildByName的方式来引用该对象.
- //通用的方法,适用所以对象
- var obj:Array = new Array()
- for(var i:uint=0;i<10;i++){
- var m:MovieClip = new MovieClip()
- addChild(m)
- obj["mc"+i] = m
- }
- trace(obj["mc1"])
- //适用显示对象
- for(var k:uint=0;k<10;k++){
- var mm:MovieClip = new MovieClip()
- mm.name = "mc"+k
- addChild(mm)
- }
- trace(getChildByName("mc1"))
另外,有时候我们会遇到这样的情况
var obj0:MC0 = new MC0()
var obj1:MC1 = new MC1()
var obj2:MC2 = new MC2()
var obj3:MC3 = new MC3()
这个时修,我们可以使用getDefinitionByName,用字符串返回类
- for(var i:uint=0;i<4;i++){
- var _class:Class = getDefinitionByName("MC"+i) as Class
- var m = new _class()
- addChild(m)
- }
3.代理类
对于代理类,它的作用就是在不能传参数的时候帮助你传参数,什么时候不能传参数,
像:
addEventListener(Event.COMPLETE,function)
这个时候如果我们需要给function参指定的参数以达到不同的效果,就需要用到代理..,我们看看以下的用了代理函数的代码
addEventListener(Event.COMPLETE,getFun(function,args))
这样,我们就可以在本来不可以传参的情况下传送参数.其中getFun就是代理函数.(一般网上都已经直接写成了代理类),getFun会帮我们把function,args生成一个无参数的函数再传给addEventListener,那么我们原来的function只需要写成
function(e:Event[,参数]):void{
//代码
}
就可以了
- function getFun(_function:Function,...alt):Function{
- var _fun:Function = function (e:*):void {
- var _alt:Array = new Array()
- _function.apply(null,_alt.concat(e,alt));
- };
- return _fun;
- }
4.让对象removeChild时自动删除子对象/属性/侦听
在AS3里..我们无法手动完全删除一个对象,,
以MovieClip为例..
我们只有在删除它的时候
除了removeChild(对象)外
还必须清空它的子对象
删除所有动态添加的属性
删除所有侦听
删除所有引用
然后等待垃圾回收,
可是实际操作的时候..
在长长的代码当中..经常会忘记自己什么时候写了侦听..什么时候添加了动态属性
其实,,我们可以借用显示对象中的Event.REMOVED,在删除对象的时候,让对象自己调用删除函数,删除相关的东西
下面这个类继承了MovieClip,当他的实例在removeChild的时候,对象将"自我毁灭"
- package net.L4cd.display{
- import flash.display.MovieClip;
- import flash.events.Event;
- dynamic public class iMovieClip extends MovieClip{
- private var lis:Array;//定义一数组保存侦听
- public function iMovieClip(){
- lis = new Array()
- addEventListener(Event.REMOVED,remove)//侦听删除事件
- }
- //重写addEventListener,在增加侦听的时候..把相应的事件保存到数组
- override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void{
- lis.push([type,listener,useCapture])
- super.addEventListener(type,listener,useCapture,priority,useWeakReference)
- }
- //"自我毁灭"的方法
- private function remove(e:Event):void{
- if(e.currentTarget != e.target)return
- stop()
- //删除子对象
- trace("删除前有子对象",numChildren)
- while(numChildren > 0){
- removeChildAt(0)
- }
- trace("删除后有子对象",numChildren)
- //删除动态属性
- for(var k:String in this){
- trace("删除属性",k)
- delete this[k]
- }
- //删除侦听
- for(var i:uint=0;i<lis.length;i++){
- trace("删除Listener",lis[i][0])
- removeEventListener(lis[i][0],lis[i][1],lis[i][2])
- }
- lis = null
- }
- }
- }
然后我们另外新建一个flash,直接在时间轴上写下以下代码
- import net.L4cd.display.iMovieClip;
- var mc:MovieClip = new iMovieClip()
- mc.addEventListener(Event.ADDED,aaaa)
- mc.addEventListener(Event.ADDED_TO_STAGE,aaaa)
- mc.addEventListener(Event.ENTER_FRAME,aaaa)
- mc.addEventListener(MouseEvent.CLICK,aaaa)
- mc.addEventListener(MouseEvent.MOUSE_DOWN,aaaa)
- mc.a = "http://L4cd.Net"
- mc.b = "我是动态属性2"
- mc.name = "我是MC"
- addChild(mc)
- function aaaa(e:Event){
- }
- removeChild(mc)
- mc = null
运行后.,,输出框就会出现
- 删除前有子对象 0
- 删除后有子对象 0
- 删除属性 b
- 删除属性 a
- 删除Listener removed
- 删除Listener added
- 删除Listener addedToStage
- 删除Listener enterFrame
- 删除Listener click
- 删除Listener mouseDown
这样,,,我们能做的事都已经做完了..等垃圾回收进行回收就ok了
上面的remove方法就是mc在移除的时候,对自己进行的清理,,
注意的是,以上只针对MovieClip进行的清理,每个类或你自定义的类都有不同..
如Sprite不需用要stop(),不需要删除动态属性..等等..
这个就由你自己去发挥~
写一组自己的"自我毁灭"类..
还有需要注意的是..像有时候,你只想removeChild,而不想进行删除,这样可以把上面的代码进行修改.
把remove设置为公开的方法
然后把addEventListener(Event.REMOVED,remove)去掉..
最后在你想删除对象的时候,,,再调用remove()就ok了..
5.自定义双击事件 - iDoubleClick
flash从as3开始支持双击事件..
我们只需要使用对象.doubleClickEnabled = true,再侦听MouseEvent.DOUBLE_CLICK事件~
就可以使用双击事件
可是发现了一个不足的地方..
如果我们同时侦听双击跟单击事件,,
那当双击的时候.就会出现两个事件同时发生..
这种情况实在不是很符合我们一般的需求..
看来还是要用as2的老办法,用单击间的延时..来判断单击与双击..不过由于as3的事件机制~~
我们完全可以模拟发现双击..
直接看看应用代码
- //导入类
- import net.L4cd.*;
- //启用双击事件,注意一下.这里的200是指两次点击之前的延时.
- iDoubleClick.enable(mc,200)
- //另外可以使用 iDoubleClick.disable(mc) 来取消自定义双击
- //像平常一样侦听
- mc.addEventListener(MouseEvent.DOUBLE_CLICK,mcDouClick)
- mc.addEventListener(MouseEvent.CLICK,mcClick)
- function mcClick(e:MouseEvent):void{
- trace(e)
- }
- function mcDouClick(e:MouseEvent):void{
- trace(e)
- }
注意使用了自定义事件后就不要使用doubleClickEnabled = true,以免冲突然
文章来自: http://l4cd.net
Tags: 复制 代理类 removeChild iDoubleClick getDefinition模块化 第二点的复制我是将每个新类加到数组里的,然后访问数组节点来得到该类
var array:Array=new Array();
for(var i=0;i<=10;i++){
var c:Class=new Class();
array.push(c);
}
array[0].....array[9],这样调用就OK了.哈哈,没那么复杂吧.
还有,你说写的图文混排还没有出来呀?快给我出来.
上一篇
下一篇


回复






谢谢你一直关注我 呵呵
你说的第二点可能是没有理解到我说的意思
当一个序列类而不是一个类的时候会用到 比如 : Class1 class2 class3
这三个类要用一个for来创建的时候就会用到我说的方法了
还有 图文混排我为此表示抱歉 没有研究透彻就说出了大话 哈哈 本来是有思路的 但是后来我试了一下 确实不行 只能用CS4的排版了 呵呵 这么久才回复你 不好意思哈