as3教程

1、动态修改影片的帧频

在AS3中,你可以使用Stage类动态的修改影片的帧频。Stage类 (flash.display.Stage)的stage对象是所有的sprite和MovieClip以及其他在安全沙箱里的所有元件的舞台。 stage对象的帧频可以是0.01到1000之间的任何一个数。要修改帧频,使用下面的代码:

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

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);
         }
     }
}
3、图形对象和绘图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);
4、新的变量类型

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型只应该使用在必须的地方,比如颜色值。

5、显示对象

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视频。

6、新的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中可以使用通配符(*)来导入整个包:

import flash.geom.*;

7、类型转换和as操作符

AS 允许在需要的时候,将对象的类型改成另外一种匹配的类型,这就是类型转换。AS2和AS3都支持通过像“type(object)”这样的方式进行类型转 换。例如,现定义一个数据类型为Object,你可以通过使用类型名称的语法将这个数据转换成另外一种数据类型。如:

var obj:Object = getMyCustomObject();
vay customObj:MyClass = MyClass(obj);
AS3引入了一种新的操作符“as”来进行类型转换。as操作符代替了类型名称语法来改变对象的数据类型。如:

var obj:Object = getMyCustomObject();
vay customObj:MyClass = obj as MyClass;
as操作符的工作方式和AS2中的非常类似。如果转换不可能进行,那么转换的返回值是null。

AS3 依旧支持通过type(object)的方式来转换类型,但是,这种方式和以前有一点细微的不同。以前转换失败是返回null,现在转换失败后将抛出一个 类型错误(TypeError)。当尝试转换两种对立的数据类型的时候就会失败。例如将一个数据类型转换成另外一个不可能通过联合和继承而得到的类型。

注意:AS上的全局转换方法Class(object)的优先级依旧高于type(object)转换方法。这些方法包括String(),Number(),和Array()等。

8、唯一的类变量

(本文非直接翻译,原文如下:)
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
     }
}
9、新的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);
10、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将自动的从内存中删除这个对象。

11、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对象中的键可能是任何数据类型的。

12、标签申明

在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直接中止外循环。

13、检测鼠标离开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会被执行,然后显示鼠标。

14、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;
15、数组定义中的逗号

本文非直接翻译,原文解释部分如下:

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()的时候是无效的。

16、包块

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的文件夹里。

17、一个文件中的多个类

一般来说,一个.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 () {
     }
}
注意,在包块中最多只能定义一个类。在同一个文件中的辅助类不是包块的一部分,并且只能在此文件中可见和被使用。

18、访问属性

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;
         }
     }
}
19、抽象类

不幸的是,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的直接子类。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值