显示对象示例:SpriteArranger

Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本

SpriteArranger 示例应用程序构建在《学习 ActionScript 3.0》中单独介绍的几何形状示例应用程序的基础上。

SpriteArranger 范例应用程序演示说明了处理显示对象的许多概念:

  • 扩展显示对象类

  • 在显示列表中添加对象

  • 分层显示对象和使用显示对象容器

  • 响应显示对象事件

  • 使用显示对象的属性和方法

若要获取此范例的应用程序文件,请参阅 www.adobe.com/go/learn_programmingAS3samples_flash_cn。可在文件夹 Examples/SpriteArranger 中找到 SpriteArranger 应用程序文件。该应用程序包含以下文件:

文件

说明

SpriteArranger.mxml

SpriteArranger.fla

Flash 或 Flex 中的主应用程序文件(分别为 FLA 和 MXML)。

com/example/programmingas3/SpriteArranger/CircleSprite.as

定义一种 Sprite 对象的类,该种对象在屏幕上呈示为圆。

com/example/programmingas3/SpriteArranger/DrawingCanvas.as

定义画布的类,画布是包含 GeometricSprite 对象的显示对象容器。

com/example/programmingas3/SpriteArranger/SquareSprite.as

定义一种 Sprite 对象的类,该对象在屏幕上呈示为正方形。

com/example/programmingas3/SpriteArranger/TriangleSprite.as

定义一种 Sprite 对象的类,该对象在屏幕上呈示为三角形。

com/example/programmingas3/SpriteArranger/GeometricSprite.as

扩展 Sprite 对象的类,用于定义屏幕形状。CircleSprite、SquareSprite 和 TriangleSprite 都扩展此类。

com/example/programmingas3/geometricshapes/IGeometricShape.as

一个基接口,用于定义要由所有几何形状类实现的方法。

com/example/programmingas3/geometricshapes/IPolygon.as

一个接口,用于定义要由具有多条边的几何形状类实现的方法。

com/example/programmingas3/geometricshapes/RegularPolygon.as

一种几何形状,这种几何形状的边长相等,并且这些边围绕形状中心对称分布。

com/example/programmingas3/geometricshapes/Circle.as

一种用于定义圆的几何形状。

com/example/programmingas3/geometricshapes/EquilateralTriangle.as

RegularPolygon 的子类,用于定义所有边长相等的三角形。

com/example/programmingas3/geometricshapes/Square.as

RegularPolygon 的子类,用于定义所有四条边相等的矩形。

com/example/programmingas3/geometricshapes/GeometricShapeFactory.as

包含“工厂方法”的一个类,用于创建给定了形状类型和尺寸的形状。

定义 SpriteArranger 类

用户可以使用 SpriteArranger 应用程序在屏幕“画布”上添加各种显示对象。

DrawingCanvas 类用于定义绘制区(一种显示对象容器),用户可以在其中添加屏幕形状。这些屏幕形状是 GeometricSprite 类的其中一个子类的实例。

DrawingCanvas 类

在 Flex 中,添加到 Container 对象的所有子显示对象都必须属于源自 mx.core.UIComponent 类的类。此应用程序将 DrawingCanvas 类的实例添加为 mx.containers.VBox 对象的子级,该对象在 SpriteArranger.mxml 文件的 MXML 代码中定义。此继承在 DrawingCanvas 类声明中定义,如下所示:

public class DrawingCanvas extends UIComponent

UIComponent 类继承自 DisplayObject、DisplayObjectContainer 和 Sprite 类,DrawingCanvas 类中的代码使用这些类的方法和属性。

DrawingCanvas 类扩展了 Sprite 类,此继承是在 DrawingCanvas 类声明中定义的,如下所示:

public class DrawingCanvas extends Sprite

Sprite 类是 DisplayObjectContainer 和 DisplayObject 类的子类,DrawingCanvas 类使用这些类的方法和属性。

DrawingCanvas() 构造函数方法设置 Rectangle 对象 bounds,它是以后在绘制画布轮廓时使用的属性。然后调用 initCanvas() 方法,如下所示:

this.bounds = new Rectangle(0, 0, w, h); 
initCanvas(fillColor, lineColor);

如下面的示例所示,initCanvas() 方法用于定义 DrawingCanvas 对象的各种属性,这些属性作为参数传递给构造函数:

this.lineColor = lineColor; 
this.fillColor = fillColor; 
this.width = 500; 
this.height = 200;

initCanvas() 方法随后调用 drawBounds() 方法,后者使用 DrawingCanvas 类的 graphics 属性绘制画布。graphics 属性继承自 Shape 类

this.graphics.clear();         
this.graphics.lineStyle(1.0, this.lineColor, 1.0); 
this.graphics.beginFill(this.fillColor, 1.0); 
this.graphics.drawRect(bounds.left - 1,  
                        bounds.top - 1,  
                        bounds.width + 2, 
                        bounds.height + 2); 
this.graphics.endFill();

DrawingCanvas 类的下列附加方法是根据用户与应用程序的交互进行调用的:

GeometricSprite 类及其子类

用户在画布上可以添加的每个显示对象都是 GeometricSprite 类以下某个子类的实例:

  • CircleSprite

  • SquareSprite

  • TriangleSprite

GeometricSprite 类扩展了 flash.display.Sprite 类:

public class GeometricSprite extends Sprite

GeometricSprite 类包括所有 GeometricSprite 对象所共有的一些属性。这些属性是根据传递到构造函数的参数,在该函数中设置的。例如:

this.size = size; 
this.lineColor = lColor; 
this.fillColor = fColor;

GeometricSprite 类的 geometricShape 属性用于定义 IGeometricShape 接口,该接口定义形状的数学属性,但不定义其可视属性。《学习 ActionScript 3.0》中介绍的 GeometricShapes 示例应用程序中定义了实现 IGeometricShape 接口的类。

GeometricSprite 类用于定义 drawShape() 方法,该方法在 GeometricSprite 的各子类的覆盖定义中已进一步精确定义。有关详细信息,请参阅后面的“在画布上添加显示对象”一节。

GeometricSprite 类还提供下列方法:

在画布上添加显示对象

当用户单击“添加形状”按钮时,应用程序将调用 DrawingCanvas 类的 addShape() 方法。它通过调用其中一个 GeometricSprite 子类的相应构造函数来实例化新的 GeometricSprite,如下面的示例所示:

public function addShape(shapeName:String, len:Number):void 
{ 
    var newShape:GeometricSprite; 
    switch (shapeName) 
    { 
        case "Triangle": 
            newShape = new TriangleSprite(len); 
            break; 
 
        case "Square": 
            newShape = new SquareSprite(len); 
            break; 
 
        case "Circle": 
            newShape = new CircleSprite(len); 
            break; 
    } 
    newShape.alpha = 0.8; 
    this.addChild(newShape); 
}

每个构造函数方法都调用 drawShape() 方法,该方法使用类(继承自 Sprite 类)的 graphics 属性来绘制相应的矢量图形。例如,CircleSprite 类的 drawShape() 方法包括下列代码:

this.graphics.clear(); 
this.graphics.lineStyle(1.0, this.lineColor, 1.0); 
this.graphics.beginFill(this.fillColor, 1.0); 
var radius:Number = this.size / 2; 
this.graphics.drawCircle(radius, radius, radius);

addShape() 函数的倒数第二行用于设置显示对象(继承自 DisplayObject 类)的 alpha 属性,所以画布上添加的每个显示对象都有一点儿透明,这样用户就可看见它后面的对象。

addChild() 方法的最后一行用于在 DrawingCanvas 类实例的子级列表中添加新的显示对象,该实例已经在显示列表中。这样会使新的显示对象出现在舞台上。

应用程序界面上包括两个文本字段 selectedSpriteTxtoutputTxt。这些文本字段的文本属性由已添加到画布中或由用户选择的 GeometricSprite 对象的信息更新。GeometricSprite 类通过覆盖 toString() 方法来处理这种信息报告任务,如下所示:

public override function toString():String 
{ 
    return this.shapeType + " of size " + this.size + " at " + this.x + ", " + this.y; 
}

shapeType 属性设置为每个 GeometricSprite 子类的构造函数方法中的相应值。例如,toString() 方法可能返回最近添加到 DrawingCanvas 实例中的 CircleSprite 实例的下列值:

Circle of size 50 at 0, 0

DrawingCanvas 类的 describeChildren() 方法通过使用 numChildren 属性(继承自 DisplayObjectContainer 类)设置 for 循环的限制,来循环访问画布的子级列表。它会生成一个列出了每一子级的字符串,如下所示:

var desc:String = ""; 
var child:DisplayObject; 
for (var i:int=0; i < this.numChildren; i++) 
{ 
child = this.getChildAt(i); 
desc += i + ": " + child + '\n'; 
}

所得的字符串用于设置 outputTxt 文本字段的 text 属性。

单击并拖动显示对象

当用户单击 GeometricSprite 实例时,应用程序将调用 onMouseDown() 事件处理函数。如下所示,此事件处理函数设置为侦听 GeometricSprite 类的构造函数中的鼠标按下事件:

this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

onMouseDown() 方法随后调用 GeometricSprite 对象的 showSelected() 方法。如果是首次调用该对象的此方法,该方法将创建名为 selectionIndicator 的新 Shape 对象,并且使用 Shape 对象的 graphics 属性来绘制红色加亮矩形,如下所示:

this.selectionIndicator = new Shape(); 
this.selectionIndicator.graphics.lineStyle(1.0, 0xFF0000, 1.0); 
this.selectionIndicator.graphics.drawRect(-1, -1, this.size + 1, this.size + 1); 
this.addChild(this.selectionIndicator);

如果不是首次调用 onMouseDown() 方法,该方法仅设置 selectionIndicator 形状的 visible 属性(继承自 DisplayObject 类),如下所示:

this.selectionIndicator.visible = true;

hideSelected() 方法通过将其 visible 属性设置为 false 来隐藏以前所选对象的 selectionIndicator 形状。

onMouseDown() 事件处理函数方法还会调用 startDrag() 方法(继承自 Sprite 类),该方法包括下列代码:

var boundsRect:Rectangle = this.parent.getRect(this.parent); 
boundsRect.width -= this.size; 
boundsRect.height -= this.size; 
this.startDrag(false, boundsRect);

这样,用户就可以在由 boundsRect 矩形设置的边界内在画布各处拖动选择的对象。

当用户松开鼠标按键时,将调度 mouseUp 事件。DrawingCanvas 的构造函数方法设置了下列事件侦听器:

this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);

此事件侦听器是针对 DrawingCanvas 对象设置的,而不是针对单个 GeometricSprite 对象设置的。这是因为当拖动 GeometricSprite 对象时,松开鼠标后它可能会在另一个显示对象(另一个 GeometricSprite 对象)之后结束前景中的显示对象会收到鼠标弹起事件,但用户正在拖动的显示对象则不会收到。在 DrawingCanvas 对象中添加侦听器可以确保始终处理该事件。

onMouseUp() 方法调用 GeometricSprite 对象的 onMouseUp() 方法,后者又调用 GeometricSprite 对象的 stopDrag() 方法。

重新排列显示对象层

应用程序用户界面上包括标有“后移”、“下移”、“上移”和“移到最前”的按钮。当用户单击其中一个按钮时,应用程序将调用 DrawingCanvas 类的相应方法:moveToBack()moveDown()moveUp()moveToFront()。例如,moveToBack() 方法包括下面的代码:

public function moveToBack(shape:GeometricSprite):void 
{ 
    var index:int = this.getChildIndex(shape); 
    if (index > 0) 
    { 
        this.setChildIndex(shape, 0); 
    } 
}

该方法使用 setChildIndex() 方法(继承自 DisplayObjectContainer 类)确定显示对象位置在 DrawingCanvas 实例 (this) 的子级列表中的索引位置 0 处。

moveDown() 方法的作用类似,不同的是它将显示对象在 DrawingCanvas 实例的子级列表中的索引位置减少 1:

public function moveDown(shape:GeometricSprite):void 
{ 
    var index:int = this.getChildIndex(shape); 
    if (index > 0) 
    { 
        this.setChildIndex(shape, index - 1); 
    } 
}

moveUp()moveToFront() 方法的作用与 moveToBack()moveDown() 方法类似。