[转]每天学点as3

      flashcs3 2006-10-15 21:52

1、-------------------------------------------------------

在AS3中,你可以使用Stage类动态的修改影片的帧频。

Stage类(flash.display.Stage)的stage对象是所有的sprite和MovieClip以及其他在安全沙箱里的所有

元件的舞台。stage对象的帧频可以是0.01到1000之间的任何一个数。要修改帧频,使用下面的代码:

// 将帧频修改到12帧每秒(FPS)
stage.frameRate = 12;
*类方法的作用域和类绑定在一起

AS3完全基于类构造。当一个类被创建的时候,类中的参数,变量,方法或任何实例都同时被创建。和AS2

不同,AS3中的方法在执行的时候,将使用和类同样的作用域。例如下面的代码:

package {
    import flash.display.Sprite;
    
    public class ClassScope extends Sprite {
        
        public function ClassScope() {      
            traceThis(); // 输出"Class Instance"
            
            var obj:Object = new Object();
            obj.traceThis = traceThis;
            obj.traceThis(); // 输出"Class Instance"
            
            traceThis.call(new Sprite()); // 输出"Class Instance"
        }

        public override function toString():String {
            return "Class Instance";
        }
        
        public function traceThis():void {
            trace(this);
        }
    }
}
*图形对象和绘图API

和AS1和AS2一样,AS3也提供了绘图API来绘制矢量线段和图形。但是在AS3中,绘图API将独立于显示对象

(display objects:MoiveClip,sprites等)而被定义为图形对象(flash.display.Graphics)。图形

对象拥有各种绘图方法用来在内部绘制图形。和以前一样,图形内容将在所有对象的最下层。同时,在

AS3中有一些新的方法来帮助你方便的绘制简单的图形。包括:

园:drawCircle(x:Number, y:Number, radius:Number):void
椭圆:drawEllipse(x:Number, y:Number, width:Number, height:Number):void
矩形:drawRect(x:Number, y:Number, width:Number, height:Number):void
圆角矩形:drawRoundRect(x:Number, y:Number, width:Number, height:Number,

ellipseWidth:Number, ellipseHeight:Number):void

代码举例:

// 绘制一个蓝色的圆角矩形
var square:Sprite = new Sprite();
square.graphics.beginFill(0xFF);
square.graphics.drawRoundRect(0, 0, 100, 50, 10, 10);
square.graphics.endFill();
addChild(square);
2、--------------------------------------------------------------
----------------------------------------------------------------
*新的变量类型

AS3中有许多新的数据类型。其中有些类型是以前没有出现的。AS3中的基本数据类型如下:

简单数据类型:

Boolean
int
null
Number
String
uint
undefined复杂数据类型:

Object
Array
Date
Error
Function
RegExp
XML
XMLList新的数据类型通过类来定义,例如: Matrix (flash.geom.Matrix)
Shape (flash.display.Shape)URLRequest (flash.net.URLRequest)
等等。

注意:

特殊类型Void在AS3中被改成了全小写:void。

“*”可以用来代表所有数据类型。如下:

var anything:*;AS3中的XML和AS1和AS2中完全不一样。以前的XML类型(对象)被定义为XMLObject。AS3

中的XML是标准的E4X-based XML对象。

int和uint是number类型的新扩展,int表示整型(没有小数),unit是无符号整型(不能是十进制,不能

是负数)。 使用int型比使用Number能稍微的提升运行效率,而uint型只应该使用在必须的地方,比如颜

色值。

*显示对象

AS3有一个新的集合:显示对象。这个集合包含了所有可以在舞台上看到或者可以被添加到显示列表中的

对象,包括以前的MovieClip,button和textField对象。AS3的显示对象有:

AVM1Movie
Bitmap
Loader
MorphShape*
MovieClip
Shape
SimpleButton
Sprite
StaticText*
TextField
Video有*的表示此对象必须在舞台上手动创建,不能直接通过AS创建。

AVM1Movie是使用AS1和AS2创建的Movie,AS3创建的Movie需要通过AVM2来播放。因此用AS1和AS2创建的

Movie在AVM2中被作为一个显示对象来播放。但是不能和AS合使用。

Bitmaps是位图对象。可以通过BitmapData对象来指定显示效果,也可以通过位图文件来设定。

Loader对象用来加载和显示外部的image和swf影片文件。

MorphShapes是在时间轴上创建的图形。虽然不能通过AS创建,但是可以通过AS来引用和控制。

MovieClips人人都会用

Shapes是从MovieClip中分离出来一个只有graphics对象的图形容器。在shape中可以通过graphics对象使

用绘图API绘制各种图形。使用shape代替MovieClip可以减少内存负担。

Sprite是没有时间轴的MovieClip,在AS3使用中,可能会在很多地方使用sprite代替MovieClip,尤其在

创建自定义的显示组件时。

StaticText和MorphShapes一样,不能通过AS创建,这是在时间轴上创建的文本对象。

TextField,文本对象。

Video对象,播放flash视频。

*新的import标识

AS3中的import标识和AS2中有一些不同。在AS2中,import被用来代理引用类的长名称,在类中并不是必

须的。因此在AS2中,如果你不使用import,你也可以使用类的长名称来引用,例如:

// ActionScript 2
var myPoint:flash.geom.Point = new flash.geom.Point(0,0);在AS3中,import标识是访问类的必须标

识。在使用到其他类的时候,也可以使用类的长名称,但是import不能省略掉。例如:

// ActionScript 3
import flash.geom.Point;
var myPoint:flash.geom.Point = new flash.geom.Point(0,0);和AS2一样,import中可以使用通配符(

*)来导入整个包:

3、----------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------

4、----------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------
*唯一的类变量

(本文非直接翻译,原文如下:)
In ActionScript 2, variables defined within a class's body were defined in the class's

prototype object. This was an efficient means to handle variable definitions but it also

meant that complex data types (such as Arrays) had a tendency to be "shared" among instances

if not explicitly defined for instances within the class constructor. This is no longer a

problem with ActionScript 3. Class variables defined in the class body are now unique to

each class instance so this problem no longer occurs.

在AS2中,复杂数据类型(比如数组),如果在类体之中,方法之外直接初始化,而不在构造器中初始化

,会被理解为“共享”的数据,而被所有的实例共享使用(类似于static的效果)。但是在AS3中不存在

这个问题。类变量是每个实例独有的,唯一的变量。如下:

class myClass{
    
    private var list:Array = [1,2,3]; //在AS2中会有一定问题,AS3中就很好
            
    public function myClass(){
        //在AS2中,应该在这里初始化list
    }
}*新的MouseMove行为

mouseMove行为在AS3中有所改变。以前,mouseMove动作是一个全局概念,也就是说不管鼠标在

FlashMovie的任何一个地方,只要移动了,就会触发任何一个MovieClip的mouseMove行为。

在AS3中,Mouse对象不再用来分派(dispath)鼠标行为。对于mouseMove行为来说,你应该监听一个

InteractiveObject的实例,比如Sprites,MovieClip和Stage。所以,你可能需要使用

InteractiveObject来代替Mouse接收监听。 对于每一个InteractiveObject实例,mouseMove行为只在这

个对象的所在范围内执行。如果你要使用全局的mouse事件监听,则需要对stage添加监听。

因此,在使用mouseMove来拖动一个对象的时候,当你的鼠标离开的脱离对象,对该对象的mouseMove事件

就会失效,拖动效果也就同时实效了。这个时候,你可能需要对stage添加move行为来进行监听:

stage.addEventListener(MouseEvent.MOUSE_MOVE, dragMyObject);

5、----------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------
*delete关键字和类成员

delete关键字在Flash中是用来删除定义的变量,但是并不将对象从内存中清除掉(这是垃圾收集器的工

作)。它只是将一个变量的引用设置成无效,让内存中的这个对象无法再被引用和使用,也无法再使用

for in来枚举。

事实上,垃圾处理器(GC)将在特定的时候,自动的从内存中删除那些不再被引用和使用的变量。比如,

你创建了两个对象引用A和B,都指向了对对象ObjectX的引用,如果delete了A,并不会让垃圾收集器把

ObjectX从内存中删除,因为B的引用还是指向了这个对象。如果将A和B都delete,则不再有对ObjectX的

引用,ObjectX也将被垃圾收集器回收。例如:

var a:Object = new Object();
var b:Object = a; // b和a引用同一个new Object();
delete a;
trace(b); // 输出[object Object] - 在内存中还是存在
delete b;
// GC将回收object这个特性在Flash8和9(AS123)中几乎都是一样的,但是在Flash8中,GC的一些特性

得到改善并能更好的工作。(注意,垃圾收集不是即时的)

虽然GC在AS3中并没有什么本质上的改变,但是因为使用了新的虚拟机,delete关键字的行为有所改变。

现在,delete关键字只能针对类的动态属性和非公有成员有效。而在AS1和2中,delete能被用在所有的东

西上。

// ActionScript 2
class DeleteVarClass {
        
    public var myVar:Number;
    
    function DeleteVarClass() {
        myVar = 1;
        trace(myVar); // 1
        delete myVar;
        trace(myVar); // undefined
    }
}

// ActionScript 3
package {
    public class DeleteVarClass {
        
        public var myVar:Number;
            
        public function DeleteVarClass() {
            myVar = 1;
            trace(myVar); // 1
            delete myVar;
            trace(myVar); // 1
        }
    }
}在上面的AS3例子中,因为myVar变量是一个公有成员,所以不能用delete来删除这个变量。

尽管在AS3中不能删除类成员,但是如果你想删除一个对象的所有引用,可以通过将变量设置为null来代

替delete。如:

myVar = null;如果一个对象的所有引用都是null,GC将自动的从内存中删除这个对象。

*Dictionary类

AS3中的Dictionary类(flash.utils.Dictionary)是一个新的AS类。Dictionary类和Object唯一的区别

在于:Dictionary对象可以使用非字符串作为键值对的键。例如:

var obj:Object = new Object();
obj["name"] = 1; // 键是字符串"name"
obj[1] = 2; // 键是1 (被转换成字符串"1")
obj[new Object()] = 3; // 键是new Object(),被转传成字符串"[object Object]"

for (var prop:String in obj) {
     trace(prop); // 输出:[object Object], 1, name
     trace(obj[prop]); // 输出:3, 2, 1
}
也就是说,无论用什么类型的变量作为键,都将被转换成字符串。同时,如果你使用了不同的对象作为键

,都会北转换成字符串"[object Object]"作为键,因此而指向了同一个数据。例如:

ActionScript Code:   
var a:Object = new Object();   
var b:Object = new Object();   

var obj:Object = new Object();   
obj[a] = 1; // obj["[object Object]"] = 1;   
obj[b] = 2; // obj["[object Object]"] = 2;   

for (var prop:String in obj) {   
     trace(prop); // traces: [object Object]   
     trace(obj[prop]); // traces: 2   
}Dictionary类将没有这个限制,你可以将键设置成任何一种数据类型。例如:

import flash.utils.Dictionary;

var a:Object = new Object();
var b:Object = new Object();

var dict:Dictionary = new Dictionary();
dict[a] = 1; // dict[a] = 1;
dict[b] = 2; // dict[b] = 2;

for (var prop:* in dict) {
     trace(prop); // traces: [object Object], [object Object]
     trace(dict[prop]); // traces: 1, 2
}虽然在trace的时候,输出的还是[object Object],但是这个结果是对象的toString的结果。在

Dictionary对象中,代表的是不同的对象引用。

注意,这里的prop的类型是*。这是很重要的,因为dict对象中的键可能是任何数据类型的。


6、----------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------
*标签申明

在AS3中引入了标签,新的标签可以和循环体一起使用。例如,现在有两个嵌套的循环体,如果想要在内

循环体中break掉外循环,一般使用下面的方法:

var i:Number;
var j:Number;
var exit:Boolean = false;
for (i=0; i<10; i++) {
    for (j=0; j<10; j++) {
        if (i > 3 && j > 3) {
            exit = true;
            break;
        }
    }
    if (exit) {
        break;
    }
}在引入了新的标签以后,可以使用下面的方法从内循环体中直接break掉外循环体:

var i:Number;
var j:Number;
mainLoop: for (i=0; i<10; i++) {
    for (j=0; j<10; j++) {
        if (i > 3 && j > 3) {
            break mainLoop;
        }
    }
}在第一个循环体上设置了mainLoop的标签,因此在循环体内任何地方使用break mainLoop直接中止外循

环。

*检测鼠标离开Movie的动作

在以前的AS版本中,你无法做到检测鼠标是否还在Flash Movie上。因此影片不能检测到用户是否在关注

着当前的Movie。另外一个问题是,如果使用了自定义的鼠标样式,在鼠标移出Movie后,自定义的鼠标还

是继续停留在影片上,而不能正确的显示鼠标当前的位置。

现在,AS3允许你通过监听stage的mouseLeave行为来捕获鼠标移出Movie的动作。mouseLeave行为在鼠标

移出Movie的时候执行。但是现在并没有mouseEnter事件,不过你可以通过使用mouseMove来设置。

下面的例子中使用了一个方框来作为自定义的鼠标:

package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.ui.Mouse;
    
    public class Test extends Sprite {
        
        private var cursor:Sprite = new Sprite();
        
        public function Test() {
            cursor.graphics.beginFill(0xFF);
            cursor.graphics.drawRect(0, 0, 25, 25);
            addChild(cursor);
            
            stage.addEventListener(Event.MOUSE_LEAVE, cursorHide);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, cursorFollow);
            Mouse.hide();
        }
        
        public function cursorHide(evt:Event):void {
            cursor.visible = false;
        }
        
        public function cursorFollow(evt:MouseEvent):void {
            if (!cursor.visible) cursor.visible = true;
            cursor.x = stage.mouseX;
            cursor.y = stage.mouseY;
            evt.updateAfterEvent();
        }
    }
}当鼠标离开Movie的时候,鼠标指针将被隐藏。当鼠标再次移动到Movie上的时候,mouseMove会被执行,

然后显示鼠标。


7、----------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------
*SimpleButton实例

AS3现在有一个新的类:SimpleButton(flash.display.SimpleButton)。这个类允许你通过AS创建一个

按钮。

var myButton:SimpleButton = new SimpleButton();SimpleButton类有4个属性分别代表按钮的四个不同

状态:upState,overState,downState和hitAreaState。你可以为每一个状态创建一个新的显示对象,

然后将显示对象赋予SimpleButton的各种状态:

myButton.upState = mySprite1;
myButton.overState = mySprite2;
myButton.downState = mySprite3;
myButton.hitAreaState = mySprite4;*数组定义中的逗号

本文非直接翻译,原文解释部分如下:
When defining arrays in ActionScript 3 using the shorthand array access operator (brackets),

you can now have a trailing comma following the last element without causing an error (like

in PHP). This makes working with multi-line array definitions a little less error-prone when

rearranging elements.

先来看一个例子:

var myList:Array = [
    "The",
    "quick",
    "brown",
    "fox",
];在AS1和2中,"fox"后的逗号会导致一个编译错误,但是在AS3中不会了。

注意,这个逗号只是在使用[]定义数组的时候有效,使用Array()或new Array()的时候是无效的。


8、----------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------
*包块

AS3中的包定义方式和AS2中有所不同。在AS3中,包路径不再是类定义的一部分,而是使用一个包块来包

含类。定义包块使用的是package标签,如下:

package my.package.path {
    class MyClass {
    }
}而在AS2中,应该是下面的样式:

// ActionScript 2:
class my.package.path.MyClass {
}实际上,在AS3中,所有的类都必须定义在包里面,如果一个类不属于任何一个包,也需要使用空的包路

径来定义:

package {
    class NotInAPackageClass {
    }
}每一个包块可以将一些有关联的类或者方法包含在一个文件里面。文件中包块里的类或方法必须使用和

文件名相同的名称:

package com.kirupa.utils {
    function StripString(str:String):void {
        // ...
    }
}上面的代码应该保存在一个名称为StripString.as的文件中,并放在路径为com/kirupa/utils的文件夹

里。

*一个文件中的多个类

一般来说,一个.as文件中就一个类,但是在AS3中,现在允许在一个文件中定义多个类用来辅助主类。

在.as文件中的辅助类,必须定义在类包以外,并且只针对此文件中的主类和其他辅助类可见。

例如:

package {
    class MyClass {
        function MyClass() {
            var helper:MyHelper = new MyHelper();
        }
    }
}
class MyHelper {
    function MyHelper() {
        var helper:HelpersHelper = new HelpersHelper();
    }
}
class HelpersHelper {
    function HelpersHelper () {
    }
}注意,在包块中最多只能定义一个类。在同一个文件中的辅助类不是包块的一部分,并且只能在此文件

中可见和被使用。


9、----------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------
*访问属性

AS3为类和类成员引入了两个新的访问属性来扩展AS2中的private访问属性。在AS3中,现在有下面的访问

控制属性:

public
protected
private
internal (默认)


public:public属性和AS2中一样。在任何地方定义的public属性,能在任何地方和被任何成员引用。

构造器必须定义成public。

应用程序类必须是public的。

protected:protected是一个新的属性。被protected指定的成员,只能被其本身或其子类访问。如果外

部类尝试访问被protected的成员,将会抛出编译错误。

类和构造器不能被声明为protected。

private:AS2中已经有private属性,但是在AS2中,子类成员可以任意的访问父类的private成员。现在

在AS3中,private属性只能在类内部被访问,其他类包括子类都不能直接访问此成员。也就是说,在子类

中可以定义一个名称和父类某成员名称一样的成员,只要父类的此成员是声明为private的。

类和构造器不能被定义为private。

internal:internal和public比较类似,不同的地方在于类成员只能被同一个包中的成员所访问,而其他

包中的成员不能访问。

internal是除了构造器以外的所有类和类成员的默认声明。

辅助类的访问控制有所不同。由于辅助类不属于任何包,internal的声明将限制其被访问只能是当前文件

之内。注意:主类不能继承辅助类,只有辅助类能继承辅助类,并且要在同一个文件内。

访问控制的错误,并不仅仅是编译时错误,有时候也是运行时错误,在AS2中用来访问隐藏方法的方式,

在AS3中不能用了,如:


 
package {
    
    import flash.display.Sprite;
    
    // 应用类必须定义成public (默认是internal)
    public class AccessControl extends Sprite {
        
        // 构造器总是public的
        function AccessControl() {
            
            // 只有在这个文件中才能访问辅助类
            var helper:Helper = new Helper();
            
            trace(helper.pubNum); // OK
            // trace(helper.protNum); // Error - 错误,不能访问protected成员
            // trace(helper.privNum); // Error - 错误,不能访问private成员
            trace(helper.interNum); // OK
        }
    }
}

// 辅助类默认是internal
class Helper {
    
    // public声明允许在任何地方被访问
    // 变量通常被设置为private的,然后通过声明public的get set方法来访问
    public var pubNum:Number = 1;
    
    // protected声明只允许在子类中被访问
    protected var protNum:Number = 2;
    
    // private声明只能在类内部被访问
    private var privNum:Number = 3;
    
    // internal声明只允许在同一个包中被访问
    // 但是对于辅助类来说,只能在同一个文件类被访问
    internal var interNum:Number = 4;
        
    // 构造器永远都是public的
    function Helper() {
    }
}

// 子辅助类默认是internal的
// 可以继承其他辅助类
class SubHelper extends Helper {
    
    // 构造器,public
    function SubHelper() {
        trace(pubNum); // OK
        trace(protNum); // OK - 继承得到的
        // trace(privNum); // Error - 不能访问private
        trace(interNum); // OK
    }
}另外一个例子:
package {
    
    import flash.display.Sprite;
    import containers.*;
    
    // Application class needs to be public (internal by default)
    public class AccessControl extends Sprite {
        
        // constructors are always public
        function AccessControl() {
            
            // can access classes in other packages
            // only if public
            var bowl:Bowl = new Bowl(); // OK
            // var basket:Basket = new Basket(); // Error - cannot access internal
            
            trace(bowl.pubNum); // OK
            // trace(bowl.protNum); // Error - cannot access protected
            // trace(bowl.privNum); // Error - cannot access private
            // trace(bowl.interNum); // Error - cannot access internal
        }
    }
}
ActionScript Code:
package containers {

    // public class accessible anywhere
    public class Bowl {
        
        // public access granted anywhere
        public var pubNum:Number = 1;
        
        // protected access granted only for
        // subclasses in that class
        protected var protNum:Number = 2;
        
        // private access granted only in this class
        private var privNum:Number = 3;
        
        // internal access granted only in the same package
        internal var interNum:Number = 4;
            
        // constructors are always public
        function Bowl() {
            
            // can access inteneral classes if in same package
            var basket:Basket = new Basket();
            
            trace(basket.pubNum); // OK
            // trace(basket.protNum); // Error - cannot access protected
            // trace(basket.privNum); // Error - cannot access private
            trace(basket.interNum); // OK - same package
            
            // clone using public method
            var basketCopy:Basket = basket.clone();
        }
    }
}
ActionScript Code:
package containers {
    
    // interal only accessible
    // from other classes in package
    internal class Basket {
        
        // public access granted anywhere
        public var pubNum:Number = 1;
        
        // protected access granted only for
        // subclasses in that class
        protected var protNum:Number = 2;
        
        // private access granted only in this class
        private var privNum:Number = 3;
        
        // internal access granted only in the same package
        internal var interNum:Number = 4;
        
        // constructors are always public
        function Basket() {
        }
        
        // accessible anywhere as long as
        // referencing a Basket instance
        public function clone():Basket {
            var basket:Basket = new Basket();
            basket.pubNum = pubNum; // OK
            basket.protNum = protNum; // OK - same class
            basket.privNum = privNum; // OK - same class
            basket.interNum = interNum; // OK
            return basket;
        }
    }
}*抽象类

不幸的是,AS3中并没有抽象类(只能继承,不能实例化)。因此你不能在Flash中直接创建抽象类。但是

,AS中的一些内置类实际上是抽象类。包括:
DisplayObject
InteractiveObject
DisplayObjectContainer

和抽象类一样,你不能使用new关键字创建这些类的实例。例如:

var myObj:InteractiveObject = new InteractiveObject(); //错误但是,除此之外,在AS中,你也不

能创建这些类的直接子类,例如:

package {
    import flash.display.DisplayObject;
    public class MyDisplay extends DisplayObject{
        public function MyDisplay (){
            // ERROR
        }
    }
}这个类在的特性和在Player中如何定义有关。如果你创建这些类的直接子类并实例化,或者直接实例化

这个类,都会出现Argument Error。

因此,如果你想扩展一个抽象类,可以采用扩展抽象类的现有的internal子类的方法。例如,如果你想扩

展DisplayObject,你可以扩展Shape,一个轻量级的,internal访问级别的,DisplayObject的直接子类

 
标签集:TAGS:
回复Comments() 点击Count()

回复Comments

{commenttime}{commentauthor}

{CommentUrl}
{commentcontent}