第二章 配置开发环境
目前,主流的ActionScript 3.0开发环境分为Flash和Flex两大类。前者是设计和开发一体的集成环境,后者是严肃的脚本开发平台,更符合程序猿的析构。开发者应根据自己的习惯和项目的需要,灵活选择。
Flash cS3建议选择英文版,它也支持中文注释和输入。英文官方文档较为准确,更新也很及时。
代码的书写和编辑是在代码编辑器中进行的,使用F9快速打开或隐藏。使用代码编辑器时,需要选择舞台元件。
Adobe FlexBuilder是Adobe官方支持的最完整的RIA开发解决方案,适应专业程序员的开发习惯。
使用Adobe FlexBuilder 2可以开发出功能强大,结构健壮,跨平台的企业级应用程序,是一个相对耗费资源的开发环境。Java虚拟机运行环境总是对磁盘要求甚高。
FlexBuilder基于Java开发环境,在安装之前需要先安装配置好Java运行时环境。在FlexBuilder安装包中提供的FlashPlayer可能不是最新的,请从官网下载更新。为了调试应用程序,需要安装浏览器的FlashPlayer Debug版本插件。安装完成后,应及时检查浏览器的FlashPlayer是否是debug版本。
第三章
FlexBuilder是一个很优秀的代码编写工具,其提供的代码提示要比Flash强大很多。使用FlexBuilder弹出的相关代码提示窗口,可以快速而无错的编写代码
工具栏中的绿色运行按钮,
快捷键Ctrl+F11,编译并在浏览器中执行,不仅编译了应用程序,还生成了相关的HTML文件,所以在浏览器中看到的是嵌入HTML文件的SWF应用。可以勾选自动编译。
Flex程序有自己的规范和构成
与Flash不同,Adobe公司为Flex设计了一种新的文件结构:MXML。
FlexBuilder的程序,一般都由三部分组成:MXML,ActionScript, Flex类库。这三者本质上,依然是使用ActionScript 3.0实现的。
MXML主要为用户界面组建布局,并记录和存储这些信息。负责记录界面的布局信息。它是XML 1.0语言,由一系列标签和标签属性组成。
数据块标签:<![CDATA[......]]>
块注释: <!--注释部分-->
对于MXML应用程序,一般总有一个最外层的标签<mx:Application>,Application标签定义了一个应用程序,命名空间的命名一般都放在这里,mx是命名空间,内部的标签都可以使用该命名空间
MXML组件文件,一般会有一个最外层的<mx:Canvas>,它是一个容器,包含HBox,VBox,x坐标,y坐标
标签名称以大写字母开头,标签属性以小写字母开头,都可以大小写混合。属性需要加上双引号。
在MXML语言中,创建组件和调整组件属性都非常简单,形式如下
<mx:组件名称 属性1="数值" 属性2="数值" 属性3="数值">
Flex的组件种类更加全面,功能更加强大,是对Flash基础类的整合和加强。
使用MXML构造用户界面非常便捷,创建组件,改变组件外观,移动组件位置,都简化为操作相应的标签和属性。MXML设计目的之一就是令外观样式的设计和代码的逻辑实现分析,也就是
表现层和逻辑层的分离。利用这一特性,程序部门和美术部门可以同步工作,互不影响。一旦应用需求确定了,只需要快速地开发出“原型界面”,确定交互部分各组件的ID,程序部门就可以进行深入的开发和调试,而美术部门可以依据确定的组件ID,自由调整界面的布局和风格。
应用程序的逻辑是利用ActionScript 3.0来控制,它是Flex程序的灵魂。类库是开发软件自身提供的一些常用功能代码的集合,Flex类库是ActionScript 3.0编写的,包含组件(容器和控件),管理器类,数据服务类和所有其它功能的类库。
上述三者相结合,产生最终编译得到的swf文件。一个应用程序对应一个swf文件
使用FlexBuilder的MXML构建"Hello World"应用程序
应用程序舞台的左上角是坐标系的原点(0,0)
在屏幕上输出文本
<mx:Text x="50" y="20" text="Hello World" id="mytxt">
用户不仅能描述界面元素,还能包含脚本代码
添加标签事件响应
事件和响应,可以简单理解为,条件和结果的关系
编译器将MXML编译为ActionScript,再将ActionScript编译为二进制的SWF文件
ActionScript的内联,级联和外联
<mx:Script source="/Hellofunc.as"></mx:Script>
FlexBuilder中的辅助设计模式,其实本质上就是MXML的可视化编辑器,都是以MXML记录保存的。
MXML文件的设计模式只解释MXML文件内部的可视化标签,可以在设计模式下调整组件的属性。
在代码编辑器中打开.mxml文件,在Source和Design标签之间切换,
在编译包含众多复杂控件标签的项目时,编译过程还会很长。较长的编译过程,是swf文件执行效率提高的重要保证。
与更改代码的程序员和更改设计视图的设计人员合作,开发您的应用程序。
用户界面开发者布局 UI、汇集 MXML 组件、提供某些轻逻辑,并可以在无需进行客户端数据处理的情况下连接到后端数据源。
对于Flash CS3创建的默认空白项目,总是拥有一层layer和一帧frame。从某种程度上,Flash是利用帧保存脚本。在Flash CS3中,ActionScript 3.0要求所有的代码都必须写在帧上。写在不同的位置,代码的作用范围也不同。
前面帧上的ActionScript无法访问后续帧的ActionScript,但是后续帧上的ActionScript能访问当前帧的所有ActionScript。代码总是写在当前激活的帧上。如果选中的帧不止一个,则代码会写在选中帧的第一帧。
trace()语句是调试语句,它的功能是将括号内的内容输出到Flash IDE的调试输出窗口中。
凡是指定了ID的舞台元件,都可以使用ActionScript控制。舞台元件有其特殊性,并不是代码所在帧之前指定的舞台元件都能访问。如果在代码所在帧的时间点上,该舞台元件不存在,则代码依然不能访问。
操作动态舞台对象的属性使用,对象ID.属性方式访问。Flash中的坐标系以舞台左上角为原点,y轴向下为正方向。
ActionScript要求,任何对象,只有加入到显示列表中,才会被显示在舞台上。显示列表是一个树状结构,最顶端的是舞台对象stage。任何在舞台上显示的对象,在显示列表中都是stage根节点的分支,使用addChild()将显示对象加入显示列表中。
stage.addChild() 简化为 addChild()
第四章 语法基础结构
ActionScript 3.0是一种基于ECMAScript ed4规范的脚本语言,其基本语法构成包括标识符,关键字,数据类型,运算符和分隔符。
这些有着特定含义的专有名称叫做标识符。按照定义的场所,标识符分为两类:语言内建标识符(变量,类,函数的名称)和用户自定义标识符。比如:
decodeURIComponent(), gotoAndPlay()
掌握标识符的命名规则非常重要,包括如下几点:
(1)所有标识符大小写敏感
(2)必须英文字母或者_开头,数字等不能开头
(3)标识符应由0-9,A-Z,a-z和_构成,不应使用其他特殊符号
(4)不能与ActionScript 3.0内建关键字冲突,参见附表
(5)考虑到代码未来的复用性,尽量避免使用保留字,参见附表
命名约定
(1)保持自然语义,如totalNumber,FirstName
(2)保持标识符的术语统一
(3)利用缩写前缀,增强代码可读性
(4)规范利用大小写,标识符主要使用小写字符,但可以利用大小字母分割单词,比如addLastNode(),在标识符中使用数字时,一般使用_将字母和数字区分开;常数可以全部大写
(5)保持标识符首字母小写,便于使用代码输入器自动补全
(6)避免长标识符,尽量10字符以内,照顾代码编辑器的格式和编译器的编译速度
(7)避免相似名称,
(8)保持标识符的格式统一,比如last_field,current_field, first_field这些
关键字
按照功能不同,ActionScript 3.0中的关键字可以分为:表达式关键字,语句控制,属性关键字,定义关键字,编译指令,保留字
(1)表达式:
false,true,null,this,Infinity -Infinity,NaN
null不同于_undefined
NaN 表示非数字
(2)语句控制
for,while,if,switch,throw,try,break, case,
for...in 遍历对象的动态属性或是数组中的元素,并对每个属性或是元素执行statement
with 建立要用于执行一条或是多条语句的默认对象
(3)定义
最基础最常用的是关键字var,用以指定一个变量
...param 指定函数将接受任意多个以逗号分隔的参数
(4)属性关键字,用于操作变量或者对象的访问访问
dynamic,final,internal,native,override,private,protected,public,static,
(5)编译指令
包括一组在编译时起作用的关键字,主要是辅助ActionScript 3.0的编译器,帮助编译器正确的处理和分析代码
defaultxmlnamespace 指定默认的命名空间
usenamespace
import 使外部类或是包可用于您的代码
include 将过长的代码文件分块存储,便于代码的管理操作
区分:import和include是两个功能完全不同的关键字
import关键字仅仅是引领编译器找到外部类的定义,所以编译器不会破坏out.as文件的内容;
include关键字执行的是文本操作层面的命令,只是简单地将外部文件的内容插入include位置,而import关键字提供的是程序逻辑层面的功能,用于在多个文件之间共享类的声明。
二者之间有着根本的区别,不能换用,也不应混淆。
(6)类的长名称
类的长名称并不是指类的名字比较长,而是指类的隶属关系比顶级类要深。
Point类,长名称却是flash.geom.Point
AS3借助包管理类的定义文件,每个包对应相应级别的同名文件夹。利用类的长名称,编译器能更准确的找到类的定义,并做进一步编译。
在ActionScript 3.0中,也可以使用通配符*包含整个包。这会降低编译器的效率,增加编译时间。
借助开发辅助工具,并不需要经常关心类和包的结构关心。
Class和Package
数据类型
ActionScript 3.0的数据类型包含两个大集合:
基元值
包括Boolean,int, Number,String和uint
复杂值
Array,Date,Error,Function,RegExp,XML和XMLList
还允许用户自定义数据类型,它属于复杂值集合。参见P121表4-6
ActionScript 3.0第一种完全的面向对象的语言,基元值和复杂值都被视为对象。
Number数据类型可以表示整数,无符号整数和浮点数。为了尽可能提高性能,应将Number数据类型仅用于浮点数,或者用于int和uint类型无法存储的大于32位的整数值。
void数据类型仅包含一个值:“undefined”,表示未声明类型的变量类型。
字面值是最简单的数据形式,是直接出现在代码中的值
在ActionScript 3.0中,声明变量必须使用var关键字显式声明。
var 变量名标识符:数据类型
通常,在声明变量的同时为变量赋值的方法,在创建数组或是实例化类的实例时最为常用。
变量的作用域
变量的作用域是指,能够通过引用变量名来访问相应变量值的代码区域。全局变量是指在代码的所有区域都能访问的变量,局部变量是指尽在代码某个部分方能访问的变量。
变量的作用域同变量的声明位置息息相关。
多级条件流程
for...in循环是for循环的变体。循环的运行将基于复杂对象的属性遍历。
var myArray:Array = {1, "two", true};
for (var i:String in myArray) {
trace("Array child : " + i);
trace(myArray[i] + " is :"+ typeof(myArray[i]));
}
函数的定义
函数在ActionScript中始终扮演着极为重要的角色,将有效的输入值变换为唯一的输出值
在ActionScript 3.0中可通过两种方法定义函数,使用函数语句和使用函数表达式。函数语句总是以function关键字开头。在函数语句中,包含函数的四个要素:
(1)函数名,不可以重载
(2)参数,逗号分隔,参数列表
(3)函数体,{}括起来的AS3代码部分
(4)返回值,只能有一个
在ActionScript 3.0中函数的定义位置非常宽松,编译器会像对待变量声明一样对待函数定义。函数的定义声明将被提升。
arguments对象可以代指函数的参数列表。它本身是一个数组,储存了函数的所有参数。
第六章 面向对象编程
本章着重介绍面向对象的一般性概念和知识。掌握了这些,就等于打开了ActionScript 3.0内部宝库的金钥匙。
从根本上讲,OOP是一种基于过程和逻辑的编程模式。面向过程的模式是一种最基本的开发模式。面向对象的编程模式则强调将问题分解为不同的模块,用类和对象的概念去分析和组织。
包和命名空间是两个相关的概念,包的名称类似于命名空间,在包内声明的对象具有相同的包命令空间。
可以有多个对象共同属于同一个包。
通常,import语句越具体越好,建议避免导入该类所属的整个包,因为过多的导入类会增加编译器的搜索负担,降低编译效率
在正确导入类或是包之后,可以使用类的完全限定名称,也可以只使用类名称本身,建议使用后者
包的机制可以完美地区分不同包中的同名类。包的使用是必要的技术。
包和命名空间
在ActionScript 3.0中,包是用命名空间实现的,但包和命名空间并不同义。使用命名空间同包没有必然的关系,它们既不共生,也不排斥。
包可用于组织类文件。
每个包可以包含许多各类文件,这些类文件都应该存储在同一个文件夹下面。每一个类文件声明一个公共类,该类的名称同该文件的名称相同。
如果要访问某个包中的某个类,则编译器将按照包的名称查找路径中的相应文件夹,然后在该文件夹中搜索以该类名称命名的as文件。Flash就采取的是这种策略管理类文件。
区分包的概念和类继承
具有继承关系的类可以分布于同一个包中,也可以分布于多个包中。同时,位于同一个包中的两个类仅是具有共同的命名空间,其它方面都不必相关。
创建包时,该包的所有成员的默认访问说明符时internal,默认仅对所在包的其它成员可见。如果希望某个类对包外部的代码可用,则必须将该类声明为public。
利用包组织代码
包的特性决定了它最重要的作用是组织代码并防止命名冲突。
允许一个源文件中包括多个类,每个文件中应该只有一个类可供该文件外部的代码使用。这些类将仅在该文件中可用,对该源文件外部的代码,它们不可见。
包的树状结构对应文件存储系统的文件夹树状结构。多级别包结构使用.运算符,类似java,比如类
global.content.terra.civ
对应文件global/content/terra/civ.as,可以用包将代码组织成直观的分层结构,以供其他程序员使用。
import视为编译器的指向牌,帮助编译器寻找类的声明。
ActionScript 3.0在包,类和源文件的组织方式上具有很大的灵活性。
继承访问控制
四个内建的访问控制关键字
public,protected,private,internal
public属性,对所有位置的代码可见
protected属性,对子类可见,不管子类和基类是否在同一个包中
private属性,对本类可见,子类不可见
internal属性,对同一包中的子类可见
方法的继承覆盖
类继承机制仅支持继承覆盖,使用override声明,静态方法不能继承,也不能覆盖。
继承覆盖需要具备两个条件:
该方法必须是可以改写的,就是不能使用final关键字声明。
该方法必须是子类可以访问的,不能使用private关键字声明
ActionScript 3.0的编译器仅根据参数数量与参数顺序辨别方法,并不参考参数的名称。
属性的继承覆盖
非私有的实例属性可以被继承,但是不能被覆盖。只有声明静态成员时,可以不理会父类中的同名属性。
静态属性必须使用类的名称来访问,而不是实例的名称。这样在代码调用成员时,不可能出现静态成员同实例成员的混淆。
唯一可以覆盖的成员是方法成员,也就是那些使用function关键字声明的成员。鉴于方法重载的诸多限制,所以在子类中重载父类的setter/getter存取器并不能完成重新定义属性成员的任务。
关键字super
关键字super提供了对父类的直接引用,使用使用super()调用父类的构造函数,也可以使用super.成员名称的形式引用父类的成员。
注意:
super关键字仅保留距离被引用子类最近的父类的引用,不能讲super理解为父类的引用。将super关键字连用以访问继承树顶层的基类,是不成立的。
在子类的构造函数中,可以使用super()的形式显式调用父类的构造函数,也可以省略,编译器会自动在构造函数的第一行之前添加super()。显式添加的优势是,能够人工的控制调用父类构造函数的时机,
这在有些代码中是非常关键的。
在子类构造函数中任何形如super.成员名称的调用都应该在调用super()之后出现,否则后果不可预料。
多态
多态就是让这些不同行为的方法采用同一个方法名。这里偏重广义的多态,指根据不同的类使用相同方法名。严格意义上应该视作一种继承覆盖。
使用继承实现多态,具体的实现方式是允许子类继承和重新定义并覆盖基类中的方法。
ActionScript 3.0的类继承是以覆盖形式实现对父类同名方法的改写。
静态成员和作用域链
只能通过定义静态成员的类名称来访问静态属性, 类名称.静态成员名称。
允许使用与静态属性相同的名称定义实例属性。可以在静态属性所在的类中定义同名实例成员,也可以在子类中定义同名的实例成员。调用时,同名实例成员的优先级更高。
在定义静态属性的类体及该类的任何子类中,可直接访问静态成员,而不必拘泥于“类名称.静态成员名称”形式。
静态成员总是比实例成员更靠前,更优先被调用,但是使用类名称.静态成员名称也可以准备访问到静态成员。
面向对象进阶
这些内容比较抽象,需要具备一定的理论基础。但是在程序开发中又属于常见内容。
联合继承
联合继承,就是一个子类可以同时拥有多个父类。通过子类,便可以将多个父类联合起来,在子类中共享多个父类的机能。
一个父类可以拥有多个派生类,一个派生类可以具有多个父类。
联合继承得到的子类应该包含任何一个父类的共用成员,这就使子类可以充当父类的角色。
联合继承的问题
支持联合继承的语言中,都会引入严格的封包机制,以限制名称访问的冲突,联合继承在运行时的开销非常大。
下面的写法是错误的
class multi_inherit extends base1, base2{}
在ActionScript 3.0中,联合继承没有得到直接的支持,但是利用接口概念可以变相实现联合继承。
接口的概念
接口是一种特殊的类,只包含方法的声明,没有方法的实现。利用普通类将接口中的声明实现,称为实现接口。该类相应称为接口的实现。
接口类似C++语言中的h文件,具体的实现要在cpp文件中提供。
接口和接口的实现不是继承关系,一个接口的多个实现可以是完全不相关的类,而接口的作用就是零这些不相关的对象具有通用的方法,能够方便地彼此通信。
ActionScript 3.0的核心类随着Flash和Flex的发布,供全世界开发者重复使用。核心类的设计原则之一就是方法名称的统一。
FlashPlayerAPI定义了IEventDispatcher接口,其中包含的方法声明可供类处理事件对象。
public interface IEventDispatcher{}
EventDispatcher类实现了IEventDispatcher接口。
public class EventDispatcher implements IEventDispatcher{}
采用接口比在基类中定义空函数拥有更广泛的用途。在基类中定义空函数,只能保证继承树内的类可以使用,接口不参与继承机制,不必受继承树的限制。
不同继承树中的类,可以是同一接口的不同实现。
在调用时,可以查询一个类是否是某个接口的实现。
接口是一种抽象类,接口可以归属于任何包中,接口定义应该位于包的顶级,接口不能嵌套。可以为接口指定命名空间,在一个包中,可以包含多个接口。
一个接口内,可以提供多种方法。接口中的方法应尽量避免与可能的类名称冲突。接口中定义的方法声明不能包含任何访问控制说明符(public, private等),也不要包含final关键字。
只能使用public和internal访问控制说明符来修饰接口定义。
接口和类的最大区别是:
接口中不能包含变量和常数,如果要提供对属性成员操作的统一限制,建议在方法内包含setter和getter存取器,存取器将被视作方法看待。
接口可以继承,使用extends关键字,支持联合继承,一个接口可扩展为一个或多个其他接口,只要逗号分隔开就行。
FlashPlayerAPI遵循一种约定,接口名都以大写字母I开始。
接口实现
在ActionScript 3.0中,接口需要使用类实现。实现某个接口的类,与普通类没有本质区别
class 类名 implements 接口名{
//类体
}
在一个类中,可以联合使用implements和extends关键字。联合接口实现类将两个接口的方法整合在一个类中。过分别通过这两个接口的检测。
接口方法实现遵循的原则
相同方法名
参数匹配
返回值一致
公共访问权限
在运行时对接口进行选择,检测接口需要使用ActionScript 3.0内建的关键字is或是as,注意是实例不是类名称的检测。
trace(nearbycafe is Iservice);
is和as在检查接口时效果是一样的,区别在于:
当检查成功,is返回true,as返回该对象本身;当检查失败时,is返回false,as返回null
关键字instanceof不能检测接口及接口的实现。
接口使用技巧
利用接口的联合来实现类的联合继承(变相实现)。利用include分离公共接口代码实现,做到重用。
抽象类的内部机制
ActionScript 是一种基于原型的语言, 类和对象逐渐成为脚本语言的核心内容。ActionScript 3.0引入了新的继承对象:traits对象。
深入研究使我们始终不能回避一个问题:
ActionScript 3.0中类的本质是什么?
在ActionScript 3.0中,有两种构建类的方法,一种方法是利用class关键字,另一种是传统的方式,利用function关键字,两种方式的结果一样。
(以后需要仔细研究)
动态类
动态库是一种特殊类,具有开发式的成员定义机制。未使用dynamic关键字定义的普通类称为封装类。
创建动态类的实例时,会为其创建一个Hash表,用来记载动态添加的成员,Hash表将占用额外的内存。
动态类仅允许修改类的对象,为对象添加成员,并不能改变类定义本身,不能为类添加动态成员。
动态添加的属性仅限当前实例使用,并不能在类的所有对象实例中分享。在运行时动态添加,在编译时并不存在。动态成员不享有类内部成员的待遇,不能访问类的私有成员。
dynamic属性不由子类继承,若动态类作为基类,其子类不自动具备动态性。只有添加了dynamic关键字,动态类的子类才是动态的。动态成员仅在运行时添加,在编译阶段不能检查其数据类型。
在运行时,由Flash Player会对动态成员进行类型检查,使用动态成员要非常小心,以免引发运行时错误。
使用dynamic关键字定义动态类
添加的动态成员可以是属性,也可以是方法。执行效率比内部方法低。
动态方法
动态方法必须以函数表达式的形式添加。具体而言,有三种方式。
函数语句
函数变量
函数表达式
直接使用函数表达式对动态类的动态成员赋值。
成员检查
使用关键字in执行成员检查,保证成员不被非法访问,用法如下:
实例成员名称 in 对象名称
静态成员名称 in 类名称
使用in关键字只能检测到可访问的公共成员
使用in来判断数组是否包含某个索引号的元素,或是是否含有某个字符串
var myary:Array=new Array(12,31,34);
trace(2 in myary); //true
trace(5 in myary); //false
Talii.qiaqia=105;
var mystr:String="qiaqia";
trace(mystr in Talii);
删除动态成员
使用delete关键字显式地删除一个动态成员,不能使用delete删除非动态成员。用法如下:
delete 对象名.成员名
一旦成员被删除,则成员中原有的值便不可访问:
Talii.phorny=1492;
trace(delete Talii.phorny); //true
trace(Talii.phorny); //false
trace("phorny" in Talii); //false
还可以删除动态方法
Talii.outerfunc=function(){
trace("add a function out");
}
Talii.outerfunc();
trace(delete Talii.outerfunc); //true
Talii.outerfunc(); //error
事实上delete只是减少引用次数。
删除一个非动态成员,请为其直接赋null。如果一个对象失去了所有的引用,则该对象会被标记为“可回收”,并在内存管理时被释放。
ActionScript 3.0是一种自动内存管理的语言,其内存管理全部由FlashPlayer处理。
动态静态成员
运行时在类定义之外,为一个动态类添加了一个静态成员,则该成员就是一个“动态静态成员”,必须在运行时添加到类名称上。
这种情况,仅是用于个别特殊场合。动态静态成员在父类外部代码中是公开可见的,但是对于该属性对于外部代码是公开的。
运行时的特殊需要
可以使用delete删除,有利于减少内存占用
归类管理相关数据
使用较少的全局变量,是一种很好的编程习惯。
避免被子类继承
如果想避免子类中的非法调用,同时情况特殊不便于使用private关键字,则可以使用“动态静态成员”解决
第七章 AS3常用对象
字典Dictionary其实就是关联数组,对象作为键,值可以使任意类型。字典在Flash的开发中比较有用。使用字典的主要用途就是建立对象之间的映射。
Adobe Flash Player使用垃圾回收系统来恢复不再使用的内存,依据是对象的引用计数。
显示列表是Flash应用程序的重要对象,显示列表包含Flash应用程序中的所有可视化元素,是一个树状结构。
当操作显示列表时,FlashPlayer自动管理显示对象的深度,也就是间接管理对象的z顺序。
在Flash中,显示在舞台上的所有元件都是显示对象,但是显示对象也可以不出现在舞台上。
显示对象,是指,ActionScript 3.0中显示类的实例对象,显示类包括核心类DisplayObject的所有子类,以及这些子类的用户自定义子类。
flash.display包中,包括了大多数常用的显示类,还有一些显示对象分散收录于flash.text,flash.media包中。
该树非常重要,请务必牢记。
如果显示对象容器被置于屏幕上,那么该显示对象容器包含的所有元件都会显示在屏幕上面。显示对象容器具有批量操作的优势,避免对一系列对象重复的操作。
Flash在处理基元值时,开销比较小,应该尽量使用基元值集合中的数据类型,以提高Flash的执行效率。
null和“”的区别
值为null的String变量并不占用内存资源,而如果一个值为“”的String,该变量会被初始化。使用==运算符可以检查出null值和空字符串""的不同。
显示列表
显示列表在每个swf应用中只有一个且必然有一个,舞台是显示列表的根,显示列表中的显示对象如果不出现在舞台范围内,则该对象显然是不可见的。
显示对象基本上都可以经过设置alpha属性而成为完全透明的。显示对象列表中,除了位于最枝节的对象外,都是显示对象容器。
显示对象的主要部分都是由Sprite,MovieClip,Loader构成的。
第八章 脚本动画基础
第九章 动画进阶和脚本仿真
第十章 影片剪辑与图形图像
在ActionScript 3中,所有的影片剪辑MovieClip其实都是类的实例对象。对于影片剪辑,时间轴其实是一种基于计时器的switch类似的结构。
对于Flex和FlashDevelop这些没有时间轴编辑窗口的开发工具,直接在代码中管理Timer是创建动画的最佳方式。直接使用语言内置的时间轴机制,就必须使用MovieClip。使用MovieClip有四种方式:
任何以MovieClip类为基类的子类都会继承MovieClip中的时间轴机制。可以为时间轴上的任何帧分配帧标签。帧标签是字符串,不是标识符,不需要遵循ActionScript 3.0的标识符规则。使用帧标签比使用帧编号具有明显优势。
ActionScript 3.0包括FrameLabel类,其每个实例均代表一个帧标签,并有一个name属性和一个frame属性。帧标签只能在设计阶段指定和修改。
回调API是SWF应用程序的通用技术。矢量图和点阵图。
点阵图(位图)体积过大,适于描述复杂的色彩和信息,但是不利于网络传输,难于创建灵活的动画。位图常见的文件格式:bmp,jpg,gif,tga,png,主要区别在于使用不同类型的压缩算法。
矢量图是使用数学算法解释的,因此存储信息少,在运行时根据较少的信息还原为屏幕显示,需要计算机具有较高的运算能力。矢量图形是Flash的灵魂,适于制作变形动画,较小的体积也利用网络传播。
矢量图基于简单的算法和基本的形状,最权威的工具是Adobe Illustrator。
Flash基于简单的矢量绘制能力,ActionScript的绘图API基于同样的思想进行设计。可以用ActionScript的语句定义矢量图形的绘制过程,在swf文件运行,就是矢量图形在屏幕上绘制和显示的过程。
ActionScript 3.0的绘图API主要集中在flash.display包中的Graphic类,该类提供了不同的绘图功能。
在ActionScript进行矢量绘图,总是依赖于某个对象实例,然后调用该对象中的Graphics成员进行绘制。
在Shape,Sprite或MovieClip类中,都包含Graphics类的实例作为属性成员,以供开发者绘图时调用。可以在自定义类中包含一个Graphics对象。Graphics类包含用于绘制线条,填充和形状的属性和方法。
Shape实例的性能优于其他用于绘制的显示对象,因为它不会产生Sprite和MovieClip类附加功能的开销。
Graphics.lineTo(), 起始位置默认为舞台左上角的(0,0), 连续调用可绘制出一序列首尾相连的线段。
手动指定线段的开始位置,使用moveTo()方法。使用Graphic.lineStyle()方法指定线条样式。
carv.graphices.lineStyle(14, 0xff3300, 1)
指定该线条为14像素宽,颜色为“0xff3300”,透明度为1
绘制曲线curveTo(),4个参数,控制点的x,y坐标,锚点的x,y坐标,控制点仅影响曲线的走向,并不出现在曲线之上
在绘图前必须指定填充样式,在ActionScript 3.0绘图API中,具有三种类型的填充:单色填充,渐变填充,位图填充
在ActionScript 3.0内部, 位图是使用bitmap类和BitmapData类管理和操作
Adobe Flash Player支持的位图图像格式有jpg,gif,png
JPG图像不包括透明度
PNG可以使用通用的无损压缩算法,其体积比BMP小得多。但是PNG的体积一般还是比JPG大,还不能完全取代JPG。PNG的多级透明度也能使边缘显得更加平滑。
无论是GIF,PNG,JPG都仅仅是位图的外部格式,在内存中,它们都被解码并转化为最基本的像素矩阵,以Bitmap形式存储。BitmapData类中复制了此额外透明度像素字节。
在ActionScript 3.0中提供了一个专用的类:Loader类,可以处理外部swf文件和图像的加载任务。
Loader.load()加载外部文件,两个参数,第一个参数是文件地址,必须指定,必须是标准的URLRequest对象,第二个参数,可以省略是安全设置。
URLRequest类是ActionScript 3.0重要类,提供了对地址和的标准化存储和操作。精简代码
var Sharploader:Loader = new Loader();
Sharploader.load( new URLRequest("data/f1.jpg"));
为了确保加载完毕,需要添加对Event.COMPLETE事件的响应,使用Loader的contentLoaderInfo属性处理此消息,contentLoaderInfo属性是LoaderInfo类的实例,该属性指向被加载对象并处理被加载对象的信息。
下面的代码演示了Loader类加载外部图像时,如何进行消息侦听。
总是应该讲BitmapData作为数据,交给专门处理位图显示的Bitmap类。Bitmap类可视为BitmapData对象的舞台包装。
利用Bitmap和BitmapData类,可以摆脱对外部数据的依赖,直接在代码中创建位图图像。
文本不等于字符串,是指舞台上的显示对象。
若要在屏幕上显示文本,在Adobe Flash player中使用TextField类。TextField类是Flash创作环境中的提供的文本操作类。该类要解决的问题是如何将String字符串类数据显示在屏幕上。
在处理文本显示时,TextField成为不二之选。在ActionScript 3.0中,文本操作的功能已经相当成熟了。
在flash.text包中还提供了许多辅助的类,例如TextFormat类和StyleSheet类。如果要设置复杂的文本格式,可以使用TextFormat类,TextField对象能接受TextFormat对象,并根据TextFormat对象提供的信息,改变文本自动的显示格式。快速分析和显示HTML是Flash的重要功能。
第十一章 事件与交互
事件机制是ActionScript 3.0的颈骨,代码的执行,一刻也不离不开事件。Flash中的每一个动作周围,都有事件的影子。ActionScript提供了多个类来处理SWF同运行环境的交互。
事件的处理和操作渗透进ActionScript 3.0的方方面面,很难使用一个基类来定义。
事件侦听器并不仅检查和侦听事件,更主要的功能是处理事件。事件响应机制更趋向于标准的DOM结构。
事件的发送管理是Flash Player的自动机制,所有的机制由“FlashPlayer事件管理中心”统一管理。
在一个对象中可以为多个事件添加侦听器,也可以为某个事件添加多个侦听器。
事件的分发路径称为事件流,不同的事件具有不同的事件流。按照事件流的流向,将事件流分为三个阶段:
1)捕获阶段
2)目标阶段
3)冒泡阶段
并非每个事件都参与事件流的所有三个阶段
Event类
事件本身也是对象,利用类来定义。在ActionScript 3.0中,所有的事件都以Event类为超类,例如MouseEvent和TimerEvent都是子事件类。
Event类的实例属性描述了事件对象的相关信息,这些属性都是只读的。
currentTarget 当前对象, target事件目标,
Flash Player API自身定义了多个Event子类
IEventDispatcher接口处理有关事件的方法定义。EventDispatcher类实现了IEventDispatch接口,显示列表上的任何对象都可以使用IEventDispatcher接口的方法。
如果在自定义类中需要操作事件,最简单方法是扩展EventDispatcher类,这样就不需要自己编写IEventDispatcher接口的方法
IEventDispatcher接口的事件方法定义中,包括添加事件侦听器的方法,addEventListener(),至少提供两个参数,事件类型和事件侦听器名称。
事件侦听器是一个函数或是方法,应该包含一个事件对象参数,并具有void类型的返回值。
removeEventListener()方法,从对象中删除事件侦听器。
dispatchEvent()主动将事件对象派发到事件流中
查询系统信息的主要类是flash.system包中的Capabilities类。该类提供了一些属性,这些属性描述了播放swf文件的客户端系统信息。
第十二章 使用外部数据
ActionScript 3.0应用程序最终能编译为一个swf文件。根据具体情况,可以选择性的将数据置于swf文件之外。swf文件通过与外部交互数据,获得新的信息,指令和资源。从应用的角度看,数据的不同种类产生了丰富的程序功能。开发者必须掌握如何读取,分析和操作外部数据。
媒体资源数据包括声音,图像,视频,其它swf应用等类型,资源数据未必是磁盘文件,从摄像头和麦克风获取的持续数据流,也是一种动态资源数据。
Flash可以播放FLV格式的视频资源,可以存放在本地,也可以部署在远程网络服务器。使用FLVPlayback类,几乎可以完成视频播放的所有操作,包括渐进式下载的Flash视频文件,也可以播放流式加载的FLV文件。
FLVPlayback将各种功能高度集成和封装。没有提供直接调用的快进和快退方法。使用FLVPlayback之前需要
import fl.video.*
Video类和VideoPlayer类需要配合相关的处理数据传输的类,才能完成视频的读取和播放。
在ActionScript 3.0中,声音的播放和控制的类主要集中在flash.media包中,其中,最重要的声音类是Sound类。该类负责处理声音的加载,管理基本声音属性,以及启动声音播放。
播放的每种声音具有其自己的SoundChannel对象,它控制声音左右声道的音量和播放进度。
SoundChannel对象在调用Sound类的Play()方法时被自动创建并作为返回值提供
使用SoundTransform类配合SoundChannel对象控制音量。
URLLoader类加载文本或二进制数据,Loader类可用于加载swf文件或是图像(JPG, PNG,或GIF)文件
每个Loader只负责加载一个外部数据,Loader作为一个显示对象容器,本身支持被加入其它的显示对象容器。开发者利用addChild()方法将Loader对象装入舞台显示列表。
加载图像有不同的选择,可以在TextField中利用HTML标记装载图像,也可以利用位图显示对象实现舞台的显示。
为了避免内存泄露,应尽量避免直接使用打开的图像文件,而是将打开的文件写入新的位图副本,并关闭Loader对象,释放位图缓存。
通过外部文本和XML文件,能为SWF问题提供变量和内容,存放程序的配置信息,
使用URLLoader时,需要等到整个文件下载完成之后,才能访问URLLoader数据。有关下载进度的通知事件,通过bytesLoaded和bytesTotal属性,以及已调度的事件,可以监视文本的下载进度。
URLVariables类是一个辅助类,定义了处理URL字符串的常见方法。URL字符串由变量名和变量值组成,使用&相连。URLVariables对象可以使用.运算符连接任何名称。属性未定义时,按未定义处理。
URLLoader加载外部文本需要利用许多字符串的处理技巧。
var myid:URLLoader=new URLLoader();
myid.dataFormat=URLLoaderDataFormat.VARIABLES;
更清晰地定义外部数据,需要利用XML文件。在ActionScript 3.0中创建XML对象非常简单,可以使用XML类的构造函数,直接将一个XML格式的字符串转化为XML对象。XML的操作非常简单。
XMLList实例可以包含完整的XML文档,XML片段或是XML查询结果。
精简的代码片段
var x:XML;
(new URLLoader(new URLRequest("xsample.xml"))).addEventListner("complete", xl);
function xl(et:Event):void{
x = XML(et.target.data);
}
URLStream类提供了对下载的低级访问,下载文件内容作为原始二进制数据提供。可以提前关闭URLStream流的下载。
Flash Player对磁盘读写受到很多限制,为了保存信息,需要借助于共享对象和FileReference类。使用ShareObject类管理数据共享对象,也可以将共享数据对象存放到服务器端,编译在多个操作系统和不同计算机之间共享数据。
ShareObject对象有Flash Player自动创建,该类提供一个getLocal()和getRemote()方法,分别访问本地和远程的数据共享对象。
尽量将数据共享对象作为优化程序用户体验的方法,而不是左右程序功能和行为的关键技术。
本地存储和远程存储各有利弊:
本地存储不利于机器之间的数据共享,不能保证操作系统之间的数据共享,用户数据缺乏统一的官网和备份;
远程存储必须保证网络连接畅通,网络传输的不稳定不利于程序的平稳运行。
ActionScript 3.0提供了双重存储机制,可同时本地和远程永久存储,建立远程和客户端的双向副本。
网络通信
网络通信有很多类负责:
FileReference类,Socket类,XMLSocket类,NetConnection类,NetStream类
套接字连接分为两大类:二进制数据的套接字连接,XML数据的套接字连接,前者是Socket类,格式化文本传输,使用XMLSocket类
Socket套接字类
使用Socket类与服务器的二进制协议通信非常容易。连接成功后发送Event.CONNECT事件。当服务器关闭连接时,Flash player会接收到Event.CLOSE事件通知。
使用flush()方法,对套接字输出缓冲区中积累的所有数据进行刷新。
XMLSocket是一个低层次的通信对象,能够提供较低级别的读写控制。XMLSocket类存在的意义在于它实现了XML信息的套接字操作,XML消息通过全双工TCP/IP
流套接字连接发送。应用场景比如,多用户聊天室程序。在XML对象和文档的层面发送和接收消息。
FileReference类提供了在用户计算机和服务器之间上传和下载文件的方法。upload方法上传该文件,播放器正式支持的上传或下载文件大小是100MB。
FileReferenceList类选择了一个或是多个要上载文件的方法。
出于安全性考虑,Flash Player对于磁盘的操作非常有限。
许多远程通信的操作都需要服务器端的支持,开发者需要了解常见的协议,并熟悉网络环境下的异步操作。ActionScript 3.0提供 了强大的低端类和容易使用的高端类,以满足不同场合和不同开发需求的要求。
第十五章 全屏幕FLV视频播放器
为了在客户端Flash应用程序中创建视频回放,需要使用多个底层类
Video类
flash播放视频的基本类,舞台上的实际视频内容框是video类的一个实例。Video类是低端的视频处理类,不包括界面控制和网络连接控制功能。开发者需要使用NetConnection类和NetStream类,
完成网络连接和视频数据加载的相关操作。若有播放视频流,需要使用NetStream类的attachNetStream()方法,将视频数据附加到Video对象上,Video对象将回放该NetStream流中的视频数据。
Video类为开发者提供了底层的控制能力,适合开发具有严格文件体积现在和特殊自定义功能的视频播放器。
NetConnection类
该对象是到视频文件的连接,可以将其视为视频数据馈送的通道。定义连接的相关选项,并不会打开具体的视频文件。该类主要实现与视频服务器的协作。除了FMS,还可以连接标准的HTTP服务器,借助HTTP协议渐进式
下载视频文件。
NetStream类
在加载视频文件时,ActionScript 3.0使用NetStream对象实例来控制视频源。NetConnection对象通常和NetStream对象一起使用,因为创建一个NetStream对象需要NetConnection对象作为参数。
NetStream类通过NetConnection对象提供的连接,打开FlashPlayer与服务器或本地文件系统之间的单向流连接。
连接创立后,需要使用NetStream对象打开具体的数据流,传输某个视频文件中的数据。类似NetConnection对象中的一个通道。该通道可以使用NetStream.publish()发布音视频数据,也可以使用
NetStream.play()加载接收数据。
根据FLV文件的存储方式,指定视频部署方式
1)本地计算机上,
2)从标准web服务器上渐进式下载
3)从FMS流式加载
根据FlashPlayer安全机制,Flash Player可以播放与swf文件存储于同一个目录中或存储于其子目录中的本地FLV文件,或是播放具有绝对地址的远程FLV视频文件,但是不能访问swf文件所在的目录的上级目录。
在自定义类中使用Video类,需要使用该类的导入声明
import flash.media.video;
不需要视频服务器,播放本地文件,使用
connection.connect(null);
NetStream对象和NetConnection对象发出的事件不同,但是可共用一个事件侦听回调函数,在switch时判断发生的事件就可以了。
利用包命名空间限制不同控制类的访问,这种换肤机制在文件管理和编译时都非常方便。
Video类自身不提供视频的控制方法,控制视频的暂停,继续,应该利用NetStream类提供的pause()方法和resume()方法
类文件只是一个文本文件,不能在其中包含任何资源,而FLA文件是一个复合文件,包含许多资源内容。一旦FLA文件中导入了组件资源,就可以在自定义类中使用这些组件。
NetStream.time记录当前播放位置
NetStream.seek()跳转到视频流中的指定位置
NetStream.close()关闭视频流,不可恢复播放,还会删除已通过HTTP下载的FLV文件的本地副本
onMetaData() 将视频元数据作为对象参数传入,被内部处理,Flash Player自动响应该事件,这种内部机制一般称为系统回调。
为了操作视频元数据,开发者只能创建一个自定义回调函数,并让Flash Player使用自定义的回调函数,为了绑定NetStream,需要利用NetStream.client属性来确定视频流的回调对象。
函数表达式可以在函数内部定义,这是非常方便的语法特性。
追踪播放进度需要三个量:
起始时间,终止时间,以及当前时间
随着视频的播放,滑块的进度会相应地改变。
NetStream类中提供了bufferTime属性控制缓冲区大小,默认0.1秒,为了流畅播放,可以设置更大些。当前缓冲区中的数据量为bufferLength,也以秒数为单位。通过这两个量,可以确定当前缓冲区的加载情况。
NetStream.bytesLoaded属性,获取当前加载的数据量,bytesTotal属性,表示当前加载文件的总字节大小。这两个量计算出当前加载量的百分比。
取得播放时长是个很耗时的工作,目前普遍的做法是在压缩的过程中,将总时长直接写入FLV的元数据。开发人员不能过分依赖该量,因为是预先写入的。bytesTotal属性是FLV文件的大小,具有稳定性,可以动态判断。
全屏模式还是要受Flash Player版本的限制,如果使用ActionScript 3.0,Flash Player版本必须高于9.0才能正常播放。全屏模式下的运行技术已经非常成熟。不同的FlashPlayer版本对视频的回放有着巨大的影响。
保证客户端Flash Player播放器能够使用硬件加速非常重要。视频回放的解码工作可以在多个线程中进行,并且真正支持多个CPU内核。
当swf嵌入网页是,必须设置allowFullScreen属性为true时,才能起到Flash Player的全屏模式支持。
flash.display.StageDisplayState类只包括两个常量,必须在用户的交互事件中设置。
进入全屏模式,Flash Player会出现自动安全警告,告诉用户使用ESC键可以退出全屏。
全屏模式下,键盘无法控制,只有鼠标。标准模式向全屏模式的变化是一种线性映射,使用Stage.scaleMode属性控制这种投影机制。