第五部分
1.AS3视觉编程精要
1.显示对象(Display Object)
- 容器(包含其他显示对象)
- 非容器对象(单纯的显示对象)
2.显示对象的等级结构
- 舞台(stage)最根本的容器,包含SWF所有的显示对象
- SWF主类实例
- Flash内容部分(容器与显示对象组成)
- 父容器可以通过
getChild(),getChildAt()
方法访问每个子对象 - 子对象可以通过
parent
属性访问到父容器
3.显示列表
- 是一张清单,只有在清单上列出的内容才会在stage中显示
- 显示对象分为在显示列表中的对象(on-list)和不在显示列表中的对象(off-list)
- 一个显示对象加入显示列表,用
addChild()
或者addChildAt()
方法
4.显示对象的种类划分(一个统一,两个层次)
- 一个统一:所有的显示对象都统一于
DisplayObject
类 - 两个层次:
- 可否接受互动事件(接受鼠标点击,键盘敲击等人机交互事件):可互动显示对象,非互动显示对象
- 可否容纳其他显示对象(将其他显示对象纳为自己的子对象):显示对象容器,非容器显示对象。
5.显示对象类库架构
- 所有显示对象都是继承父类
DisplayObject
,父类DisplayObject
继承于EventDispatcher
类,意味者所有的显示对象天生就可以发送事件 - 核心类:
DisplayObject,InteractiveObject,DisplayObjectContainer
(一个统一,两个层次) - 非InteractiveObject类:
AVM1Movie,Bitmap,MorphShape,Shape,StaticText,Video
- 不用代码接触:
StaticText,MorphShape
,只能通过Flash创作工具来创建或改变 - 用代码创建:
- Bitmap(位图对象):通过
BitmapData
对象创建,也能外部载入 - Shape(形状):绘制矢量图
- Video(视频对象):播放视频,可以来自文件或网络流媒体、
- AVM1Movie(AS虚拟机1所支持的SWF影片)
- Bitmap(位图对象):通过
- 不用代码接触:
- 非DisplayObjectContainer类:
- TextField:动态文本框
- simpleButton:简单按钮
- DisplayObjectContainer类(抽象类):
- Sprite:子类
MovieClip
,含有Craphic对象,是容器(不同于shape) - Loader:所有和外部资源的加载,与网络资源交互用URLRequest对象
- Stage:舞台类
- Sprite:子类
- 非FlashAPI的几个显示对象类
FlexSprite(mx.core.*)
:- 一个显示对象被Flex程序架构接纳,必须是UIComponent类的子类或实现IUIComponent的接口
6.AS3视觉架构优越性
- 更高效的渲染,更好的内存利用
- 自动化的深度管理
- 完整遍历显示列表
- 列表外的显示对象
- 更易于创建自定义的显示对象
2.DisplayObejct类与矢量图,位图
1.显示对象
- 可视属性列表
属性名称 | 实例属性 | 说明 |
---|---|---|
横坐标 | x | 显示对象注册点离自己父容器注册点的横向距离,以像素为单位 |
纵坐标 | y | 显示对象注册点离自己父容器注册点的纵向距离,以像素为单位 |
宽度 | width | 显示对象最左边到最右边的距离,以像素为单位 |
高度 | height | 显示对象最上边到最下边的距离,以像素为单位 |
横向缩放比例 | scaleX | 比例值 |
纵向缩放比例 | scaleY | 比列值 |
鼠标相对横坐标 | mouseX | 当前鼠标相对于显示对象注册点的横向距离。只读 |
鼠标相对纵坐标 | mouseY | 当前鼠标相对于显示对象注册点的纵向距离。只读 |
顺时针旋转角度 | rotation | 显示对象绕轴点顺时针转动的角度 |
透明性 | alpha | 值在0-1之间,0表示完全透明,1表示完全不透明 |
可见性 | visible | 布尔值,控制显示列表中对象是否可见,true为可见 |
- 其他属性(部分)
属性名称 | 实例属性 | 说明 |
---|---|---|
显示对象姓名 | name | 字符串类型,是显示对象的名字 |
父容器 | parent | 在显示列表中的每个显示对象都有其父容器 |
根对象 | root | 一般是返回当前SWF主类的实例的引用 |
舞台 | stage | 该属性持有的引用指向该显示对象所在的舞台,每个Flash程序只有一个舞台 |
遮罩 | mask | 持有的引用是用来遮罩显示对象 |
2.矢量图(Shape类绘制简单的矢量图)
- Graphics对象(继承根类Object)
- 绘制代码
var circle:Shape = new Shape();
circle.graphics.beginFill(0xff0000);
circle.graphics.drawCircle(100,100,40);
circle.graphics.endFill();
addChild(circle);
3.位图
- Bitmap类代表位图
- BitmapData对象中bitmapData属性存储位图的所有像素信息(特殊的数组)
4.遮罩(显示对象可以拖动,设置动画,动态调整大小)
- 普通遮罩:
public class SampleSimpleMask extends Sprite{
private var _bitmap:Bitmap;
private var _circleMask:Sprite;
public function SampleSimpleMask(){
initMask();
startLoadImg();
}
private function loaded(evt:Event):viod{
_bitmap = evt.target.content as Bitmap;
addChild(_bitmap);
_bitmap.mask = _circleMask; //设置遮罩
}
private function initMask():void{
_circleMask = new Sprite();
_circleMask.graphics.beginFill(0xff0000);
_circleMask.graphics.drawCircle(60,60,60)
_circleMask.graphics.endFill();
addChild(_circleMask); //要拖动添加到显示列表中
_circleMask.startDrag(true);
}
private function startLoadImg():void{
var loader:Loader = new Loader();
var request:URLRequest = new URLRequest(“url”);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loaded);
loader.load(request);
}
}
- Alpha通道遮罩(显示对象用位图缓存)
5.文本
- 创建文本,TextField类
autoSize = “left” //文本长度变化框的尺寸变
type = TextFileType.DYNAMIC //用户不可编辑
type = TextFileType.INPUT //用户可编辑文本框
- appendText()属性
6.碰撞检测
显示对象碰撞检测
hitTestObject(obj:DisplayObejct):Boolean
hitTestPoint(x:Number,y:Number,shapeFlag:Boolean=false):Boolean(shapeFlag中检测的是显示对象的实际像素(true)或者边框(false))
7.自定义显示对象类
- 继承DisplayObject的具体子类
- 不成为容器,不需要互动,继承Shape,Bitmap,Video类
3.容器:DisplayObjectContainter与Sprite,MovieClip
1.DisplayObjectContainter类成员
numberChildren:int //子显示对象数目属性
addChild,addChildAt //添加子对象
removeChild,removeChildAt //删除子对象
getChildAt,getChildByName,getChildIndex,getObjectsUnderPoint //访问子对象
contians,areInaccessibleObjectsUnderPoint //检测子对象
setChildIndex,swapChildren,swapChildrenAt //设置叠放次序的方法
2.Sprite类(轻量容器):自定义容器类多数继承Sprite类
3.添加,删除视觉元件
- 方法
- 容器对象.
addChild
(显示对象) - 容器对象.
removeChild
(显示对象) - 容器对象.
contains
(显示对象)
- 容器对象.
- 显示对象的状态独立与显示列表
- 显示对象的坐标是相对坐标,不是绝对(父容器不同,坐标不一样)
4.深度管理
- 深度产生顺序:当容器使用addChild方法向容器加入子对象,子对象索引值从0开始增加
- 方法
- 容器对象.
getChildIndex
(显示对象)//获取索引值 - 容器对象.
addChild
(显示对象,深度)//添加对象 - 容器对象.
removeChildAt
(深度)//移除对象 - 容器对象.
swapChildren
(显示对象A,显示对象B)//交换 - 容器对象.
swapChildrenAt
(深度A,深度B)// - 容器对象.
setChildenIndex
(显示对象,指定深度)//重设列表已有对象的深度
- 容器对象.
- 访问遍历容器子显示对象
getChildAt
:通过深度访问,访问速度最快,效率最高getChildByName
:通过名字访问,注意重名问题getObjectsUnderPoint
,返回数组,在这个坐标容器下所有子对象
5.MovieClip(影片剪辑)
- 实例属性
currentFrame
:记录当前播放的是第几帧currentLabel
:表示当前播放帧的标签,没有返回nulltotalFrames
:表示影片一共含有多少帧currentScene
:持有当前Scene场景对象引用scenes
:一个数组,记录MovieClip含有的全部场景对象数组currentLabels
:记录当前所有场景下所有FrameLabel标签对象数组enabled
:默认为true,控制MovieClip对象是否具有按钮行为
- 实例方法
plag()
:让播放头开始播放stop()
:停止播放gotoAndPlay(帧数,标签字符串,场景)
:从指定地方播放gotoAndStop(帧数,标签字符串,场景))
:跳到指定地方,并停止播放nextFrame()
:跳到下一帧并停止prevFrame()
:跳到上一帧并停止nextScene()
:跳到下一个场景prevScene()
:跳到上一个场景
6.加载外部图像,SWF文件
- 使用Loader对象的
load()
方法加载 - 使用侦听contentLoaderInfo对象的
Event.COMOLETE
事件加载侦听完成事件 - 加载成功后使用Loader对象的
content
属性访问到
4.Flash CS3:库元件的类绑定与stage,文档类
1.类绑定
Flash创作工具与AS3代码结合的重要途径,实现了代码与界面的分离
2.绑定类时一般都基于MovieClip类或Sprite类
3.绑定类中访问剪辑子元件的两种方法
- 手工声明public属性方法(飞机开火实例)
public class Plane extends MovieClip{
//属性名和剪辑子元件的名字相同
//访问控制必须要设为public
public var fire_mc:MovieClip;
public function Plane(){
initBehavior();
}
private function initBehavior():void{
this.gotoAndPlay(2);//从指定的地方开始
this.startDrag(true);//飞机剪辑跟随鼠标移动
//监听鼠标单击事件,单击执行fire方法
this.stage.addEventListener(MouseEvent.CLICK,fire);
}
private function fire(evt:MouseEvent):void{
trace(“fire”);
fire_mc.gotoAndPlay(2); //控制剪辑子元件
}
}
- 自定义新属性方法
public class Plane extends MovieClip{
private var fire_mc:MovieClip;
public function Plane(){
super();
initView();
initBehavior();
}
private function initView():void{
fire_mc = getChildByName(“fire_mc”) as MovieClip;
}
private function initBehavior():void{
this.gotoAndPlay(2);//从指定的地方开始
this.startDrag(true);//飞机剪辑跟随鼠标移动
//监听鼠标单击事件,单击执行fire方法
this.stage.addEventListener(MouseEvent.CLICK,fire);
}
private function fire(evt:MouseEvent):void{
trace(“fire”);
fire_mc.gotoAndPlay(2); //控制剪辑子元件
}
}
4.三中不同的类绑定
- 自动生成的类绑定,用代码直接生成库元件对象
public class SampleLinkedClass extends MovieClip{
private var _sky:Class;
public function SampleLinkedClass(){
initView();
var sky:Sprite = new _sky();
//sky变量应当使用库元件绑定中的基类类型
addChild(sky);
}
private function initView():void{
_sky = getDefinitionByName(“SkySprite”) as Class;
}
}
- 元件与独立类的绑定
- 不同的库元件继承自共同的类
- 编写一个基类控制对象动作)(控制云运动)
public class CloudMovieClip extends MovieClip{
private var _speed:Number = 1;
public function CloudMovieClip(){
super();
addEventListener(Event.ENTER_FRAME,move);
}
public function set speed(ns:Number):void{
_speed=ns;
}
//每帧云彩运动
public function move(evt:Event):void{
this.x -= _speed;
}
}
- 使用编写的级基类作为类型
var cloudA:CloudMovieClip = new _CloudA();
var cloudB:CloudMovieClip = new _CloudB();
5.舞台与文档类
- 执行顺序:
- Stage初始化
- 舞台元件绑定的类的初始化
- 文档类初始化
- 主时间轴代码初始化
- 元件的时间轴代码初始化
5.显式编程与事件,人机交互
1.事件的事件流(Event Flow)机制
- 事件流只是与显示列表相关联的事件流机制只存在与显示模型中,用于处理人机交互事件。
- 事件流机制的3个阶段
- 捕获阶段:显示列表中有个显示对象被单击,Flash Player发出一个事件对象,事件对象按照显示列表,从根容器舞台开始一层层向下寻找直到找到被单击到最里层的显示对象
- 目标阶段:事件对象停留在目标对象时的阶段
- 冒泡阶段:事件对象从目标对象再次沿显示列表向上移动
2.事件currentTarget属性与target属性
currentTarget
:表示当前侦听事件的节点,往往是容器target
:表示发生事件的显示对象,一般处于最里层
3.事件侦听时的事件流阶段
- Event对象的事件流阶段由
eventPhase
属性表示:捕获(值为1),目标(值为2),冒泡(值为3) - 侦听器一般在冒泡阶段调用
- 侦听器的参数
useCapture
为true可以在捕获阶段侦听事件
4.事件流机制(定义3个对象层层嵌套)
public class SampleEventFlow extends Sprite{
public function SampleEventFlow(){
//构建RectContainer函数继承Sprite类
var outter:Sprite = new RectContainer(10,10,200,200);
var middle:Sprite = new RectContainer(30,30,150,150);
var inner:Sprite = new RectContainer(50,50,100,100);
outter.name = “外部”;
middle.name = “中部”;
inner.name = “内部”;
addChlid(outter);
outter.addChlid(middle);
middle.addChlid(inner);
inner.addEventListener(MouseEvent.CLICK,clickHander);
middle.addEventListener(MouseEvent.CLICK,clickHander);
outter.addEventListener(MouseEvent.CLICK,clickHander);
}
private function clickHander(evt:MouseEvent):void{
trace(evt.target.name+evt.tcurrentTarget.name+evt.enentPhase);
}
}
5.鼠标相关事件
- MouseEvent类
- 单击:
MouseEvent.CLICK
,MouseEvent.DOUBLE_CLICK
- 按键状态:
MouseEvent.MOUSE_DOWN
,MouseEvent.MOUSE_UP
- 悬停或移开:
MouseEvent.MOUSE_OVER
,MouseEvent.MOUSE_OUT
,MouseEvent.ROLL_OVER
,MouseEvent.ROLL_OUT
- 移动:
MouseEvent.MOUSE_MOVE
- 滚轮:
MouseEvent.MOUSE_WHEEL
- 单击:
- 鼠标事件对象的属性:
- 鼠标当前坐标:相对坐标
localX,Y
; 舞台坐标stageX,Y
- 相关按键是否按下(Boolean):
altKey
,ctrlKey
,shiftKey
,buttonDownKey
- 鼠标当前坐标:相对坐标
- 鼠标事件对象的目标:
mouseChildren
属性(默认true),(false)点击后容器中的子对象不会与鼠标互动。
- 用代码模拟鼠标输入
- 新建鼠标事件对象
- 选择好发送鼠标事件的对象,并用它来dispatchEvent()
- MouseEvent构造函数
MouseEvent(type:String,bubbles:Boolean=true,cancelable:Boolean=false,localX:Number,localY:Number,relatedObject:InteractiveObject=null,ctrlKey:Boolean=false,altKey:Boolean=false,shiftKey:Boolean=false,bottonDown:Boolean=false,dalta:int=0)
6.键盘相关事件
- KeyboardEvent类
- 按键按下:
KeyboardEvent.KEY_DOWN
- 按键弹起:
KeyboardEvent.KEY_UP
- 按键按下:
- KeyboardEvent对象属性
- 按键信息(uint型):
keyCode
,charCode
- 辅助键是否按下(Boolean型):
altKey
,ctrlKey
,shiftKey
- 按键区域(正整数值):1
- 按键信息(uint型):
- Tab键与tabChildren
tabChildren
属性设为(false)则容器中的子对象都不能再和Tab键交互
7.拖曳,鼠标跟随
- 拖曳:
startDrag()
,stopDrag()
,dropTarget
属性
circle.addEventListener(MouseEvent.MOUSE_DOWN, beginDrag)
circle.addEventListener(MouseEvent.MOUSE_UP, endDrag)
private function beginDrag(evt:MouseEvent):void{
circle.startDrag();
}
private function endDrag(evt:MouseEvent):void{
circle.stopDrag();
}
- 鼠标跟随:
MouseEvent.MOUSE_MOVE
事件
6.ActionScript3动画编程
1.AS3产生动画的方式有两种
- 定时更新:每隔一定事件让显示对象改变一次,可以使用定时更新,使用Timer类对象定时发出事件,并侦听该对象的TimerEvent.TIMER事件,在侦听到事件时,执行动画代码
- 每帧更新:如果希望跟随Flash本身播放速度,在每次Flash屏幕更新时改变显示对象,那么应当帧听该显示对象发出的Event.ENTER_FRAME事件(一点点改变显示对象的属性)
2.使用Timer类实现动画效果
- Timer对象发出事件
TimerEvent.TIMER
:这是计时事件,每隔指定的时间发出TimerEvent.TIMER_COMPLETE
:计时结束事件,当计时结束时发出
- 使用Timer对象
public class SampleTimer extends Sprite{
private var star:StarShape;
private var timer:Timer;
public function SampleTimer(){
star=new StarShape();
addChild(star);
setStarPosition();
//设置计时器,每500毫秒发出一次计时事件,共20次
timer = new Timer(500,20);
//计时事件侦听
timer.addEventListener(TimerEvent.TIMER,moving);
//计时结束事件侦听
timer.addEventListener(TimerEvent.TIMER_COMPLETE,ended);
timer.start();
//鼠标按下停止计时器
stage.addEventListener(MouseEvent.MOUSE_DOWN,stopTimer);
//鼠标弹起继续计时器
stage.addEventListener(MouseEvent.MOUSE_UP,resumeTimer);
//滚动
private function moving(evt:TimerEvent):void{
star.x +=5;
star.rotation +=5;
evt.updateAfterEvent();//强制屏幕在事件后更新
}
//重设
private function ended(evt:TimerEvent):void{
setStarPosition();
timer.reset();
}
private function setStarPosition():void{
star.x=0;
star.y=0;
star.rotation=0;
}
private function stopTimer(evt:MouseEvent):void{
timer.stop();
}
private function resumeTimer(evt:MouseEvent):void{
timer.start
}
}
}
3.借助其他包(fl.transitions)中现有类创建动画代码
- Tween类
- 构造函数:
Tween(obj:Object,prop:String,func:Function,begin:Number,finish:Number,duration:Number,useSeconds:Boolean=false)
- obj:目标对象
- prop:目标属性
- func:变化方式
- begin:起始值
- finish:终止值
- duration:动画长度(帧数)
- useSeconds:是否以时间计时
- 构造函数:
- TransitionManager用法(只接受MovieClip对象作为目标对象)
starMov =new MovieClip();
var trans:TransitionManager = new TransitionManager(starMov );
trans.startTransition({
type:Zoom,direction:Transition.IN,duration:1,easing:Bounce.easeOut
});
Animator
- 构造函数:
Animator(xml:XML=null,target:DisplayObject=null)
控制播放方法:
end():void//停止播放动画,返回动画序列最后一帧
nextFrame():void//前进到动画序列下一帧
pause():void//暂停动画,直到调用resume方法
play():void//开始播放动画
resume():void//在动画由pause方法暂停后继续播放
rewind():void//设置到动画的第一帧
stop():void//停止播放动画,返回动画序列第一帧
常用属性:
autoRewind:Boolean//将动画设置为完成后重写开始播放
isPlaying:Boolean//指示动画当前是否开始播放
target:DisplayObject//正呈现动画效果的显示对象
time:int//从零开始的整数,指示和控制当前动画中的时间
事件
MotionEvent.MOTION_END//动画播放完成后发出
MotionEvent.MOTION_START//动画播放开始时发出
MotionEvent.MOTION_UPDATE//动画更改且屏幕更新时发出
- 构造函数: