顯示物件範例:SpriteArrangerFlash 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 類別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 類別其中一個子類別的實體:
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 類別實體的子清單中,它本來就已經在顯示清單上,如此會讓新的顯示物件出現在「舞台」上。 應用程式的介面包括兩個文字欄位,selectedSpriteTxt 和 outputTxt。這兩個文字欄位的 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() 方法相同。 |
|