DisplayObject,直译为视觉对象,意为能够被看到的对象。html
视觉是Flash 成功的主要基石。当我赏析ActionScript 3 的全部视觉元件类型和其总体构架时,感到很是满意。能够看出,此次总体的架构设计是深思熟虑的结果。与其余语言,好比C#,相比有本身强烈的特点,是对Flash视觉行为贴身定作的结果。编程
ActionScript 3的架构乍一看很复杂,不包括UIComponent的子类,就有7到8个层,20多个莫名奇妙的类。头疼!但实际上,它的设计是很是的简洁优雅,远远比ActionScript 2一个MovieClip打天下强太多了。实际上,只要真正弄清了它的设计思路,就能够高屋建瓴,尽收眼底,会发现这个架构逻辑清晰,很是的易懂易记。因此,先抛开ActionScript 3 的帮助文件,咱们一块儿来看看为何要设计这样一个架构,搞出20多个怪胎出来。网络
(如蒙转载,请留下个人Blog连接:www.kingda.org, thx)架构
先来追忆一把ActionScript 2中无所不能的先贤: MovieClip(影片剪辑)。 这位兄台无所不能:可在其中画矢量图,可在其中贴位图;可在其中作影片,也可嵌套子影片;偶尔用来加载,闲来客串按钮;三教九流皆可放,肚皮天下第一广。它的父亲何人,原来是元始天尊Object。ide
这样的玩意儿,新手用起来很爽,大大节约了脑细胞。但任何一个有过大型OOP项目经验的老手,都会绝不犹豫的指出,这样的架构设计是失败和混乱的。代价是巨大的。MovieClip类公开的属性和方法共有一百多个(本身数数)!竟然直接继承根类!竟然拥有这样多公开(public)属性和功能的类!竟然应用范围如此普遍!函数
首当其冲,其第一弱点就是系统资源的浪费。工具
举个例子, 我新建一个空MovieClip A,只是想让它作个容器,好在里面放几个有内容子MC。这样我操做A的位置和渐变时,子MC会统一变化。这样的经验你们都有吧。可就是这么一个简单的纯容器A,ActionScript 2&1都会绝不犹豫的把MovieClip全部的属性和方法都赋给A。谁让A是MovieClip类的实例呢?可在这个应用上,咱们要A的其余90多个功能干什么呢?并且还不算最耗资源的内建的对Timeline的支持!你们想一想,咱们天天都在建立MC。但事实上咱们作开发时,建立的MC有多少用到了大部分的功能和Timeline?只有一部分的经过Flash建立的MovieClip才须要时间轴的支持,其他大部分根本不须要时间轴支持。这样的设计是否是有问题呢?动画
痛批了一顿ActionScript 3以前的MC后,咱们不得不说几句公道话:这样的错误是有其历史局限性的,咱们不能苛求古人。且看如今的视觉元件架构,那叫一个爽。爽,就爽在系统设计师对整个Flash视觉系统的抽象上。抽象和解构的功力很深!不得不佩服!系统各个超类和子类的设计划分,职责清晰,稳健高效,堪称优雅!我看.Net FrameWork 的System.Drawing架构设计时都没有这个感受。毕竟Flash是靠视觉起家,与视觉动画交互打交道最深阿。网站
下面来欣赏ActionScript 3 的元件架构。spa
ActionScript 3 中全部能够被看到的视觉元件都统一于DisplayObject,即其子类的实例。DisplayObject是一个抽象类,不能生成实例。从系统架构设计上来讲,这样的超类设计是常识。DisplayObject,我在AS3.0教程(5):强大的事件机制(1)中讲过,继承于EventDispatcher类,也就意味着全部的DisplayObject子类均可以发送事件了。
啊哈,DisplayObject下面一层的抽象就精彩了,架构设计师的原意是将全部视觉元件分为两大类:能够接受人机交互事件的,和不能够接受人机交互事件的。因此就有了InteractiveObject类和非InteractiveObject类之分。因为非InteractiveObject的几个类之间差异太大,也抽象不出什么共同点,因此,干脆就分红了InteractiveObject的六个同级兄弟 AVM1Movie, Bitmap, MorphShape, Shape, StaticText, Video。但黑羽认为从系统的优雅性出发,不妨就设一个UnInteractiveObject的超类,将这六个孩子放在这个超类的下面。还便于往后的功能扩展。
在讲最重要的InteractiveObject以前,咱们先把这几个不三不四的兄弟先扫掉。这几个子类中,咱们把它分为能够代码建立的,和不能够代码接触的。所谓不能够代码建立的,是指只能经过Flash创做工具来建立的。和之前同样,StaticText仍是不能够用代码实现。另一个是MorphShape,这个东东是指在Flash中建立Shape形变时,由Flash Player自动生成的,一样的,代码没法实现。
剩下的几个都是能够用代码建立的:Bitmap,位图对象,能够经过BitmapData对象来建立,也能够从外部载入,好比经过loader。Shape,形状,专门用来绘制矢量图的,经过Graphic对象建立的。Video,视频对象,专门用来播放视频的,能够来自文件也能够来自网络流媒体。
下面要说到的是AVM1Movie,所谓AVM1Movie,意思就是说Actionscript Virtual Machine 1所支持的SWF影片,也就是ActionScript 1和2的影片。因为ActionScript 3 采用的是AVM2,因此和AVM1影片没法跨脚本交流,必需要把它同AVM2 swf影片区分开来,因此有个这个类。关于这个,感兴趣的兄弟看个人这篇文:小谈ActionScript 3.0与AS 2.0,1.0的swf兼容性。这个通常咱们不用关心,也不用直接接触,一旦咱们加载一个AVM1老影片到AVM2 swf中时,Flash Player 会自动建立一个AVM1Movie的实例包装这个swf。咱们打交道的每每是装载AVM1 swf的容器元件。
到了InteractiveObject下一层了,这一层共有三个类。
这一层的抽象理念又要赞一下。架构设计师又用了一个容器和非容器的概念来区分视觉元件。所谓容器,就是能够在其中加载其余的DisplayObject子类对象。固然也包括它的叔叔们,即非InteractiveObject的那几个类。所谓非容器,那就是说不能在它的视图里面加入其余的DisplayObject了。“容器”,这个公共性质实在过重要了,在这一层才这样抽象出来实在很高明,很到位。
那么老套路,先讲讲非容器的两个类,TextField和SimpleButton。 TextField,就基本上是咱们熟悉的动态文本框,这里暂不细说。来讲说SimpleButton,这个名字虽然和咱们在ActionScript 2中碰到的SimpleButton同样,但实际上两者有很大的差异了。实质上,ActionScript 3 中SimpleButton这个类是将Button这个重要经常使用的UI控件单独提出做为一类,而不是像之前和MovieClip混淆不清。谁都知道,在ActionScript 2和1中,只要改改MovieClip前几个帧的标签,这个MovieClip就变得和Button同样了。关于SimpleButton的使用,能够说很是简洁实用,这个放在后面细说。我在这里所要强调的是Button和MovieClip不是一个性质。虽然ActionScript 3中Sprite和其子类也能够经过buttonMode来作出和Butoon类似的行为,但原理是不一样的。
剩下的就是DisplayObjectContainer类了。DisplayObjectContainer的全部子类对象,均可以在其中添加其余DisplayObject子类对象。但要注意一点,DisplayObjectContainer自己也是一个抽象类,不能够生成实例。这是出于架构设计稳健性扩展性的考虑,和将DisplayObject设计成抽象类的缘由同样,很少说了。
重要的是看看它的几个子类,Sprite, Loader, Stage。 Stage,就是舞台,全部的视觉元件都是在它之中,当之无愧是最终容器,放在这一层也是合情合理。 Loader就有趣了,它把之前MovieClip装载的部分所有抽象分离出来了。全部和外部资源的加载,都是经过Loader来进行的。而Loader也不能直接和网络资源打交道,要经过专门的URLRequest对象来进行,各司其职,很是好。Loader能干什么?装载swf, 和各类图片。注意,视频仍是要经过Video类来进行,直接addChild到各类Container中,不必定要放在Loader中。
下面来了Sprite,这个3.0中咱们打交道最多的容器了。一句话,它是去掉了时间轴的MovieClip(即MovieClip被阉掉了)。如我开头例子所说,假若咱们只是为了建立一个容器,那么Sprite是首选。甚至能够说,咱们这些写代码的开发人员,90%以上的状况都只须要和Sprite打交道。含有时间轴的MovieClip通常是Flash工具建立出来的,每每只须要加载就能够了。准确的说,Sprite比ActionScript 2中的MovieClip不止少一个TimeLine,如装载。Sprite中也含有Graphic对象,这意味着,它也能够直接在其中代码绘图。但咱们始终要记住,Sprite不一样于Shape,区别就在于Sprite是容器,而Shape不是。从代码角度说,就是,Sprite能够addChild(),但Shape不能够。
都说到这儿了,咱们亲爱的MovieClip还不见踪迹,到底在哪儿了呢?其实就在Sprite的下一层。Sprite下一层中,共有四个子类,MovieClip是其中一个。你们能够想到,如今的MovieClip重要性大不如前了,主要就是表明用Flash建立的含有时间轴的影片。经常使用的gotoAndStop, currentFrame等等这些属性如今才能碰到了。
其他三个子类,也是来头不小,最牛的就是其中的FlexSprite。虽然它的改动只是变了一下toString()函数,但它倒是全部Flex组件的共同基石。著名的UIComponent的老爸如今就是它了。UIComponent何许人也?天下组件,皆由它出。黑羽大胆预测,咱们在Flash 9中所要用到的控件,也就是如今的Flex里面的组件,即mx.controls里面的全部组件。此类不可小看。
另两个子类Preloader和DownloadProgressBar,已经不属于flash.display包了,而是属于mx.preloaders包,主要管理的是下载进度和共享库的下载等功能,不予细说了。
到此,ActionScript 3 主要的视觉元件架构已经理出了一个清晰的脉络,设计的缘由,理由,思路都作了一一剖析,但愿你们喜欢。其实InteractiveObject下的另外两根枝条TextField和SimpleButton也有很重要的地位,在后续教程中会一一细说。
下面到了老鸟时间了,和老鸟们分享一下我对ActionScript 3 视觉架构的分析心得。能够看出的是,抽象的界限很是明确,应用的模式也比较统一。应用的模式就是OOP编程中最经常使用的模式之一:Composite模式。全部的DisplayContainer属于Composite模式中的树枝,非DisplayContainer部分的都是树叶。树枝中都有相应的汇集对象。
另外要指出的是,MovieClip和Sprite不再像之前2.0的MovieClip同样,对内部的不一样子对象给出包装接口。好比Shape下的Graphic对象,Sprite下面的SoundTransform对象,Loader下的LoaderInfo对象,等等等等。我原本迷惑,为什么不用装饰器模式,让这些元件的行为和ActionScript 2更加类似一些,过渡的痛苦少一些,但转念一想明白了架构设计师的苦心。就是要用这样清清楚楚,明明白白的Composite来增强全部开发者OOD时分工协做,更加快的熟悉和运用新的强大的架构。与这个优势相比,这么一点过渡的痛苦又算得了什么呢?
关于ActionScript 3视觉编程后续部分和具体的编程例子,会陆续放出。(11月份更新:才发如今拷贝Word文档到博客,并编辑内容时,不当心在最后一段遗漏了几行字,如今加上。请转载的网站也加以更新,否则恐有歧义,读者难以理解。)