blog.Ring.idv.tw

Flash

從元件庫(Library)附加你的元件(一)-「attachMovie()」

「attachMovie()」-從字面上所表徵的意思,「attach」可以解釋為「貼上」或「附加」等意思,加上後面的「Movie」便知大意為「附加上你的影片片段」,也就是說,當我們想要從元件庫(Library)附加上「元件」時,即可利用這個方法來幫助我們達成。

剖析之前的預備動作

前置處理

在開始剖析之前,我們必須先做一些前置處理,這裡我們先利用「Rectangle Tool」等工具,在Stage上任意繪製形狀,並將此形狀轉成「MovieClip」元件,接著將此元件內的形狀刪除,意即為保留此「MovieClip」為「空」的狀態,以便容易剖析。

貼上元件的識別名稱(Identifier)

開啟元件庫,將剛剛所建立的元件給予它一個「識別名稱(Identifier)」,如此才能利用「attachMovie()」來達成動態附加元件庫中的元件,如圖所示:

簡單的驗證程式

最後在此元件內的Frame[1]寫入下述程式:

trace(this);

剖析「attachMovie()」的運用方式

根據ActionScript 2.0 Language Reference的說明,在開始運用「attachMovie()」之前,我們來觀察一下必須運用的參數有哪些?

Parameters

id:String — 對應元件庫中的識別名稱。

name:String — 給予它一個「實體名稱(instance name)」。

depth:Number — 深度值,可參考「Layer」、「Level」和「Depth」之間的三角關係(四)

initObject:Object (optional) — 在Flash Player 6之後才被支援的參數,可用來初始化此實體的一些屬性。

了解上述參數的意義為何之後,我們直接寫個簡單的測試程式(如下所示),將剛剛前置作業所準備的元件來加以運用:

_root.attachMovie("rect","rect_mc",1);

結果:

_level0.rect_mc

從結果中就可以知道,原本必須在「Properties Panel」中才能設定的「實體名稱」,現在則利用「attachMovie()」便可直接來作設定了,那Flash Player是如何達成這樣的動態處理呢?

剖析深藏在元件庫(Library)中的元件

我們將剖析上述程式的bytecode,來觀察Flash Player所發佈「swf」的檔案結構,來觀看一下端倪之處。

在藍色區塊的部份是屬於「rect」元件的bytecode,而紅色區塊部份則是利用「ExportAssets」這個「Control Tag」來描述「rect」元件的「識別名稱(Identifier)」,也就是說,只要當我們設定好處於元件庫中的元件「識別名稱」,並且在發佈成「SWF」檔案之後,此檔案便內含了描述此元件的「識別名稱」,進而達成動態地從元件庫中來控制特定元件。

初探「attachMovie()」的「initObject」參數

最後我們來玩玩在Flash Player 6之後才被支援的參數「initObject」,然而在開始之前我們先來想像一個情境,當我們在呼叫「attachMovie()」之後,我們想要讓此元件固定在某特定的座標位置上,那該如何處理呢?

基本上有兩種做法,一種是直接利用「initObject」參數,另一種則是採用「實體名稱」的方式來加以控制,但相對來說,第一種的做法較有執行優先權的優勢:

利用「initObject」參數

var obj = new Object();
obj._x = 50;
obj._y = 50;
_root.attachMovie("rect","rect_mc",_root.getNextHighestDepth(),obj);

採用「實體名稱」的方式

_root.attachMovie("rect","rect_mc",_root.getNextHighestDepth());
rect_mc._x = 50;
rect_mc._y = 50;

範例下載

本文若有任何謬誤,希望請不吝地賜教,若能指正不勝感激。

2007-07-09 17:42:44 | Comments (2)

「Number()」vs.「parseInt()」(一)-效率測試

基本上我們欲將字串轉成數值來加以處理的方式,大致上有:「Number()」、「parseInt()」和「Number Object」等方式,由於使用字串轉成數值的機會相當多,例如:從「TextField」取值來處理、利用「loadVariables()」來載入外部的資料等…,究竟那種方式是最有效率的呢?

善用「Number()」來加以轉換

我們直接寫入下列程式來加以檢測:

「Number()」:

function test()
{
	for(var j = 0 ; j < 100000; j++)
	{
		Number("10000");
	}
}
var start = getTimer();
test();
trace(getTimer()-start);

結果:(取決於電腦速度而有所不一)

202

「parseInt()」:

function test()
{
	for(var j = 0 ; j < 100000; j++)
	{
		parseInt("10000");
	}
}
var start = getTimer();
test();
trace(getTimer()-start);

結果:(取決於電腦速度而有所不一)

314

從結果中我們不難發現,「Number()」在字串轉成數值的處理速度,的確比「parseInt()」較為快速~究竟是如何造成的呢?兩者不是都為「Global Function」?我們可從bytecode來觀察一下兩者究竟是如何處理的。

為何「Number()」速度較快

我們直接寫入下述程式在Frame[1],以方便驗證:

var a_num = Number("1.5");
var b_num = parseInt("1.5");

從bytecode中可得知,「Number()」是利用ActionCode「0x4a」(ActionToNumber)來處理的,而「parseInt()」則是採用ActionCode「0x3d」(ActionCallFunction)來處理之,重點在於前者只需要一個指令(Instruction),而後者卻仍需仰賴呼叫AVM(ActionScript Virtual Machine)所內建的函數。

範例下載

本文若有任何謬誤,希望請不吝地賜教,若能指正不勝感激。

2007-07-06 18:04:15 | Add Comment

「Target Path」命中你的目標實體(四)

在一系列的「Target Path」命中你的目標實體()所曾提及過的「_root」、「_parent」和「this」,在本文中我們將配合著這些觀念來加以活用。

「_root」絕對路徑 vs. 「_parent」相對路徑

這裡我們設計一個簡單的範例來說明,我們在Stage上放置兩個「MovieClip」,一個名為「red_mc」的紅色矩形,另一個為「blue_mc」的藍色矩形,並在「red_mc」裡面附上一個「Button」,同時為此「Button」寫入下述程式:

on(release)
{
	trace(this);
}

結果:

_level0.red_mc

從結果中我們可以發現,寫在「Button」上的「on」事件處理程式,「this」所參考到的是此「Button」所處在的「MovieClip」(red_mc)而非此「Button」本身,這是因為「this」只能參考到一個「Object」或是一個「MovieClip」,反之寫在「MovieClip」上的「on」事件處理程式,便是參考到此「MovieClip」本身。

接著我們再將上述程式加點額外的控制,假設我們想在此「Button」上控制一個處在於Stage上的「blue_mc」,並將它的透明值改為50%,我們其實可以利用「_root」或是「_parent」的寫法:

相對路徑的寫法

on(release)
{
	_parent.blue_mc._alpha = 50;
}

絕對路徑的寫法

on(release)
{
	_root.blue_mc._alpha = 50;
}

上述兩種寫法都可以達到同樣的作用,一個是從元件內部往上一層實體去達成,另一個則是直接從「_root」實體去控制,倘若遇到較多層結構的寫法時,例如:「_parent._parent._parent.blue_mc.alpha = 50;」和「_root.blue_mc._alpha = 50;」,兩者相形之下,若不考慮元件間的相依性,絕對路徑的寫法相較而言簡潔了許多,當然這兩種寫法均仰賴著設計者如何去取捨,。

「_root」和「_parent」的取捨

無論使用「_root」或「_parent」的確都可達到相同的作用,那該如何去取捨這兩種用法呢?筆者建議你採用「高內聚力(High Cohesion)、低耦合力(Low Coupling)」的設計準則來加以取捨,因為使用「_parent」的作法,必然會造成元件之間相依性的提高,所以若沒有適當地切割元件與元件間的相依性,那往往會造成「牽一髮而動全身」的情況發生,採用此設計準則無非是希望元件能更具有彈性與獨立性。

範例下載

2007-07-02 22:40:33 | Add Comment

「Target Path」命中你的目標實體(三)

最後搞懂你的「_parent」目標位置

「parent」,字面上可以解讀為「父親/母親」的意思,所以顧名思義,「_parent」便是意指為你目前所處在於此實體的上一層實體(父親/母親),也就是說,我們可以利用「_parent」來控制上一層實體的種種行為,例如:改變它的「_x」和「_y」屬性值或呼叫它所提供的函數等。

這裡我們將「Target Path」命中你的目標實體(二)的範例加以修改一下,直接將「red」和「green」的Frame[1]改寫成:

trace(this._parent);

結果:

_level0
_level0.red

從結果中可以明確地知道,在「green」的上一層實體為「red」(_level0.red),而在「red」的上一層實體則為「_level0」,這也就是「_parent」的作用所在,或許讀者會覺得這樣一路下來感覺好像沒什麼多大的成就感,然而明確地了解這幾個屬性的用法並釐清觀念,才能為接下來要闡述的東西打好根基。

「Target Path」目標路徑的區隔「.」(dot)

通常我們要區分目錄夾的層級時,我們可以利用「\」符號來判別,例如:「C:\windows\temp」,倘若是要區分網址的層級時,我們便可利用「/」符號來加以判斷,例如:「http://blog.ring.idv.tw/temp/test.html」,然而在Flash要區分層層的元件結構,則必須採用「.」(dot)符號來加以區隔,例如:「_level0.red.green」。

範例下載

2007-07-02 21:05:20 | Add Comment

「Target Path」命中你的目標實體(二)

再搞懂你的「this」目標位置

「this」,字面上可以解讀為「這個」或是「這東西」的意思,所以顧名思義,「this」便是意指為你目前所處在於此實體的這東西,然而從「Target Path」命中你的目標實體(一)我們已知「_root」所指的就是處於「_level0」這個「MovieClip」,倘若我們在此「MovieClip」為它加上「this」,所以如果沒意外的話,那它應當也是代表著「_level0」囉?答案更是肯定!

trace(targetPath(this));
trace(this); //此作法較簡潔

結果:

_level0
_level0

結果如同我們所預期的顯示出「_level0」,或許上述的例子過於簡單,我們再來看一個稍為有點結構的例子:

範例:

我們先在Stage上放置一個紅色矩形的「MovieClip」,並在此「MovieClip」再放置一個綠色圓形的「MovieClip」,並給予兩者分別為「red」、「green」的實體名稱(instance name),結構如下圖所示:

並分別在這兩個「MovieClip」的Frame[1]寫下:

trace(this);

結果:

_level0.red
_level0.red.green

結果就像筆者先前所說的,基本上我們其實大多都在「_level0」活動活動筋骨而已,加上「_root」所指的就是「_level0」,所以這裡的「_level0」也代表著「根」的意思,也就是說,我們放置在Stage上的「red」和「green」這兩個「MovieClip」,它們的「根」也就是「_level0」,這從結果中可以清楚地知道,然而重點在於我們在這兩個「MovieClip」所寫的程式,它們分別呈現為「_level0.red」和「_level0.red.green」,不僅分別對應我們放置在Stage上的結構順序,也呼應「this」這個屬性的意義。

範例下載

2007-07-02 19:29:01 | Add Comment

Next Posts~:::~Previous Posts
Copyright (C) Ching-Shen Chen. All rights reserved.

::: 搜尋 :::

::: 分類 :::

::: 最新文章 :::

::: 最新回應 :::

::: 訂閱 :::

Atom feed
Atom Comment