顯示物件範例:SpriteArranger

Flash Player 9 以及更新的版本,Adobe AIR 1.0 以及更新的版本

SpriteArranger 樣本應用程式是以 Geometric Shapes 樣本應用程式 (於「學習 ActionScript 3.0」中另外說明) 為基礎而建立。

SpriteArranger 樣本應用程式將說明處理顯示物件的一些概念:

  • 擴充顯示物件類別

  • 將物件加入顯示清單

  • 建立顯示物件圖層及使用顯示物件容器

  • 回應顯示物件事件

  • 使用顯示物件的屬性和方法

若要取得此樣本的應用程式檔案,請參閱 www.adobe.com/go/learn_programmingAS3samples_flash_tw。您可以在 Examples/SpriteArranger 檔案夾中找到 SpriteArranger 應用程式檔案,此應用程式是由下列檔案組成:

檔案

說明

SpriteArranger.mxml

SpriteArranger.fla

主應用程式檔案,在 Flash 中為 FLA,在 Flex 中為 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 介面,此介面則會定義形狀的數學屬性,而不是視覺屬性。實作 IGeometricShape 介面的類別定義於「學習 ActionScript 3.0」說明的 GeometricShapes 樣本應用程式。

GeometricSprite 類別會定義 drawShape() 方法,再進一步於 GeometricSprite 的各個子類別之覆寫定義中修改。如需詳細資訊,請參閱稍後說明的「將顯示物件加入畫布」一節。

GeometricSprite 類別也提供下列方法:

將顯示物件加入畫布

當使用者按一下 Add Shape 按鈕時,應用程式會呼叫 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() 方法,使用類別的 graphics 屬性 (繼承自 Sprite 類別),繪製適當的向量圖形。例如,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() 函數的倒數第二行會設定顯示物件的 alpha 屬性 (自 DisplayObject 類別繼承),以便讓加入畫布的每一個顯示物件都有些微透明,讓使用者能夠看到背後的物件。

addChild() 方法的最後一行會將新的顯示物件加入 DrawingCanvas 類別實體的子清單中,它本來就已經在顯示清單上,如此會讓新的顯示物件出現在「舞台」上。

應用程式的介面包括兩個文字欄位,selectedSpriteTxtoutputTxt。這兩個文字欄位的 text 屬性是以有關 (加入至畫布或由使用者選取之) 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() 方法相同。