1. 程式人生 > >[轉]ActionScript2.0程式設計技術教程(第二章)

[轉]ActionScript2.0程式設計技術教程(第二章)

  2.4 路徑

  在一個學校中有校長、老師、學生,老師中又有語文老師、數學老師等。校長和老師之間有資訊交流,老師和學生也有資訊交流等。

  一個 Flash 影片好比是一個學校,可以由多個影片剪輯組成,這些影片剪輯中,可以有自己的時間軸,有自己的變數等。影片剪輯之間是怎樣進行交換資訊的呢?這與 Flash 中的路徑有關。

  2.4.1 絕對路徑

  如果校長要找學生,可以這樣進行,校長先找到下一級的老師,老師再找下一級的學生,表示如下:

  校長 . 老師 . 學生

  主場景( _root )好比是校長,主場景中的影片剪輯( mcA )好比是老師,影片剪輯( mcA )下的影片剪輯( mc1 )好比是學生,如果要在主場景中訪問影片剪輯 mc1 ,用如下方式:

_root.mcA.mc1; 

  在 Flash 影片中從起點(如從主場景開始)呼叫變數或影片剪輯,這樣的語法稱為絕對路徑。它簡單、容易理解,但移植性差。

  範例 2-13 :使用絕對路徑

  ( 1 )開啟 Flash MX 2004 ,新建一個 Flash 文件。

  當建立一個新檔案時,出現在面前的場景即主場景,用 _root 表示。

  ( 2 )在主場景中建立一個例項名為“ mcA ”的影片剪輯例項,雙擊 mcA 進入元件的編輯場景,建立一個例項名為“ mc1 ”的影片剪輯例項。在【時間軸】的上方可以顯示出影片剪輯例項的順序。如圖 2.18 所示。

圖 2.18 影片剪輯例項的順序

  ( 3 )返回主場景,新建一層,單擊此層的第 1 幀,開啟【動作】面板,輸入下列程式碼:
trace(_root.mcA._width);
// 輸出影片剪輯例項 mcA 的寬度
trace(_root.mcA.mc1._width);
// 輸出影片剪輯 mc1 的寬度
  ( 4 )測試影片,觀看【輸出】面板中輸出的資料。
  ( 5 )返回主場景,把主場景第 1 幀中的程式碼中改為:

trace(mcA._width); 
trace(mcA.mc1._width); 

  測試影片,結果是一樣的。

  從測試結果可看出,在主場景中使用絕對路徑,可省略 _root 。

  ( 6 )返回主場景,把第 1 幀中的程式碼加上註釋,在主場景中加入一個按鈕,單擊按鈕,開啟【動作】面板,輸入下列程式碼:

on (release) { 
trace(_root.mcA._width); 
trace(_root.mcA.mc1._width); 

  測試影片,單擊按鈕,觀看測試結果。
  ( 7 )返回主場景中,把按鈕中的程式碼改為:

on (release) { 
trace(mcA._width); 
trace(mcA.mc1._width); 

  測試影片,單擊按鈕,觀看測試結果,測試結果不變。

  從測試結果可看出,主場景中的按鈕上的程式碼可以看成是在主場景中的時間軸上執行,所以可以不加 _root 。

  ( 8 )返回主場景,把按鈕中的程式碼加上註釋,雙擊場景中的影片剪輯例項,在第 1 幀上加上下列程式碼:

trace(_root.mcA._width); 
trace(_root.mcA.mc1._width); 

  測試影片,結果與前面相同。

  ( 9 )關閉測試視窗,把第 1 幀上的程式碼改為:

trace(mcA._width); 
trace(mcA.mc1._width); 

  測試影片,結果錯誤。

  從測試結果可看出,影片剪輯有自己的時間軸,它的程式碼是在自己的時間軸上執行,所以必須加路徑 _root 。

  原始檔見“ 2-13.fla ”(檔案路徑:配套光碟 / 原始檔 /part2 /2-13.fla )。

  試一試: 在本例的基礎上,做如下修改:

  Flash 檔案可以由多個影片組成,一個影片可從外部動態的匯入到另一個影片的影片剪輯中,比如,影片“ 1.swf ”被匯入到影片“ main.swf ”中的影片剪輯例項 mc 中,如果在影片“ 1.swf ”中的程式中有 _root ,匯入到 mc 後,不再是主場景,所以路徑改變,這時“ 1.swf ”的中的程式碼就不能正確的執行,這時,就要使用相對路徑來解決這個問題。

  相對路徑是以自己所處的起點去訪問其它的變數或影片剪輯。如在範例 2-13 中,以 mc1 為起點訪問上一級的影片剪輯 mcA 就屬於相對路徑,這裡的上一級用 _patent 表示。因為 mcA 是 mc1 的上一級,在 mc1 的時間軸上加上:
_parent._x ;
  意思是訪問 mc1 的上一級 mcA 的 x 座標,轉換為絕對路徑即:
_root.mcA._x;
  使用相對路徑有兩層意思,一是以自己為起點向上訪問,需要用 _parent 。二是以自己為起點向下訪問,只需用點運算子。

  範例 2-14 :使用相對路徑訪問變數

  ( 1 )開啟 Flash MX 2004 ,新建一個 Flash 文件。

  ( 2 )建立如圖 2.20 所示影片剪輯例項及其結構,圖 2.20 中的名稱代表它們的例項名。

圖 2.20 影片剪輯的關係

  ( 3 )單擊主場景的第 1 幀,開啟【動作】面板,輸入下列程式碼:

var root_var = "_root"; 

// 在主場景中定義一個字串變數,代表主場景
  ( 4 )在四個影片剪輯例項的時間軸的第 1 幀上分別定義一個變數,如下所示:
  在 mcB 中:

var mcB_var = "mcB"; 

  在 mc2 中:

var mc2_var = "mc2"; 

  在 mcA 中:

var mcA_var = "mcA"; 

  在 mc1 中:

var mc1_var = "mc1"; 

  ( 5 )在 mcB 的時間軸上的第 1 幀上輸入下列程式碼:

trace(_parent.root_var); 

  ( 6 )測試影片,輸出 _root 。
  在這個範例中, _root 是 mcA 的上一級,即 _root 是 mcA 的父級,要在 mcA 的時間軸上訪問 _root 中的變數 root_var ,只需向上訪問一級,表示如下:

_parent.root_var; 

  而 mcA 又是 mc1 的父級,要在 mc1 的時間軸上訪問 _root 中的變數 root_var ,需向上訪問兩級,表示如下:

_parent._parent.root_var; 

mcB 是 _root 的下一級,即 mcB 是 _root 的子級。要在 _root 的時間軸中訪問 mcB 的變數 mcB_var ,只需用點運算子,向下訪問一級,表示如下:

mcB._mcB_var; 

  同樣的,要在 mcB 的時間軸上訪問 mc2 中的變數,表示如下:

mc2._mc2_var; 

  要在 _root 的時間軸上訪問 mc2 中的變數,要向下訪問二級,表示如下:

mcB.mc2._mc2_var; 

要在 mc2 的時間軸中訪問 mc1 中的變數 mc1_var ,先向上訪問二級,再向下訪問二級,表示如下:

_parent._parent.mcA.mc1.mc1_var; 

  原始檔見“ 2-14.fla ”(檔案路徑:配套光碟 / 原始檔 /part2 /2-14.fla )。
  試一試: 在本例的基礎上,做如下修改:
  ( 1 )在 mcA 中訪問 mc2 中的變數。
  ( 2 )在 mc2 中訪問 mcA 中的變數。
  分別用 trace() 語句輸出。

  注意: 在定義主場景中按鈕的動作指令碼時,訪問主場景中的變數不用加路徑。

  通過【動作】面板的【插入目標路徑】按鈕可把例項的路徑自動新增到【動作】面板中,這給程式設計帶來了很多方便。

  開啟原始檔“ 2-14.fla ”,單擊第 1 幀,按 F9 開啟【動作】面板,單擊【動作】面板上的【插入目標路徑】按鈕 ,彈出【插入目標路徑】對話方塊,如圖 2.21 所示。

圖 2.21 【插入目標路徑】對話方塊

  利用【插入目標路徑】對話方塊可新增例項的相對路徑和絕對路徑。單擊【插入目標路徑】對話方塊中【絕對】單選按鈕,再單擊要插入目標路徑的例項名,即可顯示出相關例項的絕對路徑,單擊【確定】按鈕可把路徑新增到動作面板中。如圖 2.22 所示。

圖 2.22 例項的絕對路徑

  雙擊主場景中的例項 mcB ,單擊時間軸的第 1 幀,開啟【動作】面板上的【插入目標路徑】對話方塊, 單擊【相對】單選按鈕,再單擊要插入目標路徑的例項名,可顯示出相關例項的相對路徑。
另外,要獲取相對路徑還可用上一節的方法:先獲得絕對路徑,理清楚各個影片剪輯例項的層次關係,再決定向上還是向下訪問。

  2.4.3 動態路徑

  影片剪輯一般通過手工建立,通過【屬性】面板可以設定影片剪輯例項的例項名,通過例項名和路徑就可以訪問不同層次的影片剪輯例項。但有些影片剪輯的例項是通過程式來建立的,例如通過複製函式可以複製出若干個新的電影剪輯例項,它們的例項名也是在程式中指定的。要訪問這些複製出來的影片剪輯例項,最好的方法是用動態路徑。

  動態路徑是利用陣列運算子來實現的,在範例 2-14 中可以使用絕對路徑訪問 mcA :
_root.mcA
  如果用動態路徑可以這樣表示:
_root[“mc”+”A”]
  注意: 動態路徑使用陣列運算子“ [ ] ”實現,路徑和例項名間沒有點運算子 。

  使用動態路徑的好處是可以批量實現路徑。假如主場景中有影片剪輯例項 mc1 、 mc2 、 … 、 mc100 ,假如用絕對路徑,要寫 100 行程式,用動態路徑就非常方便,因為這些例項名有一定的規律,開頭兩個字母是一樣是,都是 mc ,後面的數字可用一個變數 n 來表示,因為變數是可以變化的,表示如下:
_root[“mc”+n]
  Flash 中的關鍵字 this 代表自己,如果不用 _root ,可用 this 來指定,如:
this[“mc”+n]
  使用 this 的前提是不使用其它路徑,就是指當前路徑,這裡指的是主場景。
  使用動態路徑時也可以用相對路徑,如:
_parent[“mc”+n]
  如果有多重路徑,要訪問主場景下的 mcA 下的 mc1 到 mc100 ,可以這樣表示:
_root.mcA[“mc”+n]
  範例 2-15 :使用動態路徑批量更改影片剪輯的屬性
  ( 1 )開啟 Flash MX 2004 ,新建一個 Flash 文件。
  ( 2 )在主場景的【圖層 1 】上建立五個影片剪輯,例項名分別為 mc1 、 mc2 、 mc3 、 mc4 、 mc5 。
  ( 3 )新建一層,在此層第 1 幀上輸入下列程式碼:

var n = 1; 
// 定義變數 n ,初始值為 1 

  ( 4 )在第 2 幀插入空白關鍵幀,輸入下列程式碼:

_root["mc"+n]._visible = false; 
// 設定影片剪輯例項為不可見 

  ( 5 )在第 3 幀插入空白關鍵幀,輸入下列程式碼:

n += 1; 
// 變數 n 加 1 
gotoAndPlay(2); 
// 跳到第 2 幀並播放 

  ( 6 )測試影片,可以看到全部的影片剪輯例項都變化不可見。

  原始檔見“ 2-15.fla ”(檔案路徑:配套光碟 /part2/ 原始檔 /2-15.fla )。

  分析 : 此範例中,在第 1 幀中定義一個初始值為 1 的變數 n ,當執行到第 2 幀時,因為 n=1 , _root["mc"+n]._visible = false 的作用是相當於 _root.mc1._visible=false ,所以 mc1 變為不可見。執行第 3 幀, n 加 1 ,變為 2 ,然後跳到第 2 幀,使 mc2 變為不可見。由於第 2 和 3 幀不斷迴圈, n 不斷加 1 ,使場景上影片剪輯例項一個個變為不可見。
試一試: :把第 2 幀上程式碼改為:

this["mc"+n]._visible = false; 

  測試影片看看效果。
  動態路徑在實際程式設計中的運用非常廣泛,它大大提高了程式的編寫效率,有關動態路徑的更多應用將在後面的章節中講解。

  PII 應用程式開發
  翻譯:zjs35
  zjs35.5dblog.com

  這部分內容將教你怎樣用ActionScript 2.0構建完整的應用程式,你將學會架起和建立一個OO物件的最好實踐,並學會UI元件和MC怎樣適合一個有好結構的flash應用程式,你還將學會怎樣和其它開發者共享程式碼和使用其它人開發的程式碼庫。這此都將幫助你建立一個可升級的、擴充套件的、穩定的應用程式。

  第11章    一個純OOP的應用程式框架
Flash is notoriously open-ended,If there are several of ways to skin a cat, there are even more ways to build a Flash application. (大致意思是flash建立應用程式的方法太多了)flash的彈效能讓開發者混淆,特別是它們建立第一個應用程式時。通過提供一個清晰的怎樣構建一個OOP的應用程式的例子,達到解決這種混淆的目標。這裡介紹的這個例子決不是建立flash應用程式的唯一方法,但它對確是合理的、可複用的能為任何OOP工程打好基礎的方法。我們先在抽象層次上考慮這個例子,此時並沒有涉及任何特殊的應用。,我們的框架能夠應用到從一個email應用程式到一個計算機遊戲的任何東西。在下一章,我們將把我們的普通框架應用到一個真實的案例裡――貨幣轉換應用程式。
本章描述的應用程式的框架源自Java思想,更確切的說,是一個微軟的VB風格。那也就是說,這個應用程式將是一個純粹的OOP應用程式,所有的東西都在類裡面,而fla檔案只是用來載入類和提供元件聯接。並不是每個flash應用程式都是純粹OOP的。Flash也充分支援drag-and-drop(拖放)的可視的開發。可視開發的操作包括在創作時通過面板手工的把元件放在場景中、設定元件的屬性和資料繫結,這些操作超出這本書的範圍。(下面的部分內容教你怎樣使用幫助和google檢視資訊,還有原始檔下載。skip)
11.1 基本的目錄結構
在我們開始創作之前,先建立應用程式的目錄結構。
(步驟略,另和我說不會,哈哈)
建立目錄結構如下,隨便放在硬碟的哪個位置:
AppName/deploy/source
在我們的例子中,我們有一些外部的素材如文字,聲音、圖片等,如果這些素材很多,們應該建立一個AppName/assets目錄來存放這些素材。
11.2 flash文件檔案
每個flash應用程式至少包含一個fla檔案,fla檔案是用來匯出影片(swf檔案)的原始檔,影片實際上是在播放器中展示內容的。許多應用程式都含有多個在執行時單個載入的swf。例如,在一個遊戲中,一個swf可能代表某一級別的遊戲,在一個站點中,一個swf可能代表如“聯絡我們”這部分內容。在一個含有多個swf的應用中,某個swf只是一個一個用來顯示進度條的容器等等(moock可真會寫)。
我們的基本的應用程式只包含一個swf檔案,因此,只需一個fla檔案。然而,我們的應用程式框架不排除其它swf的使用,這些swf可能是站點的某部分,一個表單或測驗的某個場景,一個遊戲的不同級別部分。
下面建立我們的應用程式的主要fla檔案:
建立一個flash文件檔案,存放在AppName/source目錄中,檔名為AppName.fla。
下面讓我們來建立應用程式的類檔案。
11.3    類
由於我們建立的是一個純粹OOP的應用程式,因此所有的內容都在類檔案中建立。在flash中,大部分應用程式都是包括可視的使用者介面圖形,因此,一個典型的OOP應用程式中,由類檔案建立和管理UI元件。但在我們的例子裡,只有兩個類。現在,把我們的焦點只放在框架的構建上,所以既不用類建立視覺元素,也不用類完成特定的實際任務。為了強調框架的一般性和自然性,我們把兩個類命名為A和B。我們來看怎樣建立元件和管理基於現在的框架的結構使用者介面。
一個OOP應用程式可能有許多個類,但只有一個用來開始應用程式,在我們的例子中,類A用來開始應用程式,類A有一個通常命名為main()的方法,按照習慣,這個方法包含應用程式的開始程式碼。在真實的應用程式中,類A將被含一個用來完成開始任務的main()方法的類代替。例如,在一個測驗應用程式中,主要的類可能是Quiz,main( )方法用來初始化測驗和顯示第一個問題。在一個聊天應用程式中,首要的類可能是ChatClient,main()方法可能用來連線伺服器。在上面的兩個例子中,應用程式的接下去的部分是從main()方法執行之後開始的。例如,第1個問題答案的出現可能使第2個問題出現,或者伺服器的成功連線使聊天介面出現。
基於對我們的應用程式的框架的考慮,我們認為類A的開始任務是建立類B的一個例項。
注:類方法main()的使用是嚴格按照java方法的,在flash中,main()的使用是可以選擇的。在java中,由於語言的需要,main()方法是必須的,main()方法會被自動呼叫。但在flash中,你必須手工呼叫main()方法,時間軸的第1幀要跟在應用程式預載之後。
我們將把類儲存在包com.somedomain中,在你的應用程式中,你應讓包com.somedomain與你的站點的蜮名相匹配。例如,我的站點的蜮名是moock.org,我建立的所有類都在包moock.org之內。
建立包:
1、    在AppName/source目錄下建立一個名為com的資料夾
2、在AppName/source/com目錄下,建立一個名為somedomain的子資料夾
建立類A:
1、建立一個動作指令碼檔案
2、輸入下列程式碼:

import com.somedomain.B; 
class A { 
    private static var bInstance:B; 
    public function A() { 
        // 在這個例子中,類A的建構函式不使用 
    } 
    public static function main():Void { 
        trace("Starting application."); 
         bInstance = new B( ); 
    } 

3、儲存到AppName/source/com/somedomain,檔名A.as
建立類B:

class com.somedomain.B { 
    public function B() { 
        trace("類B的一個例項被建立"); 
    } 

在我們的框架中,請注意,我們把類儲存在AppName/source目錄中,這是合理的,但這不是一定要這樣做,理論上講,類能儲存在任何地方,只要這個目錄能被新增到全域性或文件類路徑,些目錄中的類就能在時間軸上或其它類中使用。
11.4 時間軸
現在我們已經建立兩個類和一個flash文件,讓我們看看AppName.fla怎樣載入類和呼叫類方法A.main()來開始我們的應用程式。
在我們的應用程式框架中,將使用AppName.fla來建立基本的應用程式狀態:loading 和 main,每種狀態都是在相應的有標籤的幀通過暫停播放頭來實現,在幀標籤loading中,當類載入時顯示一個載入資訊,在幀標籤main中,呼叫A.main( )方法開始應用程式。
注:在應用程式中使用幀標籤作為程式的狀態是一個通常的做法(不管是OOP還是沒有OOP),雖然這種用法是非常普遍的,但對於熟悉其它語言的程式設計師來說,這種做法很不適應,也很不熟悉。為了解決這個情況,flash引入了基於螢幕的表單應用程式,關於螢幕類更多的資訊請看….
要載入類A和B,需要這些步驟:
1、在幀中為類指定輸出幀
2、在AppName.fla的時間軸上新增幀標籤loading 和 main
3、當影片載入時,新增程式碼顯示載入資訊
這些步驟的詳細方法將在下面列出來:
1、開啟AppName.fla檔案
2、選擇檔案――釋出設定
3、在釋出設定對話方塊中,選擇flash標籤,單擊設定按鈕,在彈出的對話方塊中,在匯出用於類的幀的文字框中輸入10,這個10是任意的,但這個指定的幀須在顯示載入資訊的程式碼之後(也就是預載之後)。
4、單擊兩次確定按鈕完成操作
在AppName.fla的時間軸上新增幀標籤,
1、修改圖層1的名稱為scripts,我們將把程式碼放在這一層中,做為一個好的習慣,你應該把所有的程式碼放在scripts圖層中,在時間軸中,這個圖層位於最上層,它只包含程式碼,不含mc或其它內容,一些開發者用actions代替scripts,但目的是一樣的。
2、選擇scripts圖層的第15幀
3、播放一關鍵幀
4、插入一個新的圖層,
5、把新圖層命名為labels.
6、在labels圖層的第4和15幀,插入一關鍵幀,就像scipts圖層只包含程式碼一樣,labels圖層專門用於設定幀標籤,用幀標籤代替幀數目指定某個幀是非常便利的、友好的。
7、在labels圖層的第4幀,加入標籤loading
8、在labels圖層的第15幀,加入標籤main
新增程式碼用來顯示載入資訊:
1、在scripts圖層的第5幀插入一關鍵幀
2、在scripts圖層的第5幀,輸入下列程式碼:

if (_framesloaded == _totalframes) { 
    gotoAndStop("main"); 
} else { 
    gotoAndPlay("loading"); 

3、在scripts圖層的第1幀,輸入下列程式碼:

this.createTextField("loadmsg_txt", 0, 200, 200, 0, 0); 
loadmsg_txt.autoSize = true; 
loadmsg_txt.text = "Loading...Please wait."; 

4、在scripts圖層的第15幀,輸入下列程式碼:

loadmsg_txt.removeTextField( ); 

我們現在已經提供了基本的時間軸結構,接下去呼叫A.main()方法來開始應用程式,我們將在幀標籤main處來完成它,下面是此幀的程式碼:

loadmsg_txt.removeTextField(); 
import com.somedomain.A; 
A.main(); 

在理論上講,這是我們對AppName.fla的最後一次改動,除非我們要增加元件、聲音或傳統的圖形。應用程式的所有程式碼都在通過A.main()方法直接引用或間接引用類中,在AppName.fla中將不放置任何程式碼。
我們的應用程式完成了,現在我們測試應用程式是否能正常執行,要進行測試,我們要輸出一個swf檔案,然後在flash播放器中執行。
11.5 輸出flash影片
指定一個目錄用來輸出AppName.swf檔案:
1、在AppName.fla開啟的狀態下,選擇檔案――釋出設定――格式
2、在檔案下面,輸入:../deploy/AppName.swf.
3、單擊確定按鈕
4、為了在測試模式下測試我們的應用程式,選擇控制――測試影片,實際上測試影片就是在AppName/deploy目錄建立一個swf檔案和立即把它載入進播放器的偵錯程式。
對於我們的應用程式,我們將輸出flash7格式,如果你想別人使用其它版本的播放器,你也可以輸入其它版本的格式
如果你的應用程式能正常執行,在輸出面板中將看到下列資訊:
Starting application.
An instance of class B was constructed.
如果上述的資訊沒有出現,可嘗試比較你的原始檔和本書的原始檔
釋出html檔案:略
在所有支援的flash播放器版本、所有的網頁瀏覽器和所有的平臺中測試是不個好想法,如果你等到所有專案完成之後才在各種各樣的瀏覽器中測試,你可能會發現嚴重的問題,如果它們被儘早發現,修復起來也是容易的。
11.6 flash中的專案
為了在大的應用程式中管理檔案,flash支援專案的概念,一個專案是一群有關係的檔案,這些檔案能通過專案面板進行管理,一個專案面板像資源管理器,有以下的特徵:
l    綜合了控制應用程式的原始檔
l    容易訪問關聯的檔案
l    即使在編輯類檔案時,也可以釋出應用程式
這個內容超出了本書的範圍,更多內容請看幫助
11.7 小結
雖然這章感覺是非常概念化的,但它展示了非常重要的OOP開發的基礎,也是這本書下面的許多例子的基礎。
譯自:Essential ActionScript 2.0 第二部分第11章

  貨幣轉換應用程式這個例子只進行簡單的貨幣轉換,下圖顯示了這個程式所需的介面,包括一些UI元件例項(Button, ComboBox, Label, TextArea, and TextInput)。在這個應用程式中,使用者必須輸入一個加拿大元的數目,然後從下拉列表中選擇貨幣型別,再單擊轉換按鈕,就能在文字框中顯示出轉換後的等量的貨幣數值。 
圖12-1 應用程式的介面
和第11章的使用的結構對應,我們將把元素放在下面的目錄下,在建立目錄時要注意, deploy和source都是CurrencyConverte資料夾的子目錄,org/moock/tools是source資料夾的子目錄。
CurrencyConverter/
deploy/
source/
org/
moock/
tools/
這個應用程式的主要部分是名為CurrencyConverter.fla的flash文件檔案,為了建立這個檔案,我們把AppName.fla(在第11章建立的)複製到CurrencyConverter/source目錄中,然後把AppName.fla重新命名為CurrencyConverter.fla。這樣CurrencyConverter.fla就具有了基本的所需結構,包括類的預載等(詳見第11章)。
這個應用程式只有一個CurrencyConverter類,這個類位於CurrencyConverter/source/org/moock/tools中,而匯出的CurrencyConverter.swf位於CurrencyConverter/deploy目錄中。
現在讓我們開始貨幣轉換應用程式的每個細節。
12.2 準備flash文件檔案
CurrencyConverter類將在執行時例項化應用程式所需的元件。雖然我們是在執行時建立元件的例項,flash仍然要求把元件新增到CurrencyConverter.fla的庫中。不幸的是,flash不允許直接從元件面板中把元件拖到庫中。如果我們要在庫中新增一個元件,必須在場景中先建立元件的例項。雖然元件例項可以直接留在了fla檔案的場景中,但這種開發模式不是我們現在的重點,因此必須把場景中的元件例項刪除。不管哪種方法,flash都把元件加入了庫中(這是我們最初的目的)。
12.1.1 新增元件到flash文件檔案
步驟:拖入元件,然後刪除
如果我們在一個全新的fla檔案中創作,元件就已準備好被例項化了,然而,回憶我們在第11章的fla檔案中的創作,當類被載入時,在第10幀匯出類和顯示載入資訊。由於這個預載結構,如果我們想使用元件,這些元件將不能工作,因此我們要把元件整合到預載結構裡。
注:當一個類在fla檔案中的第1幀以後被匯出時,元件將不能工作,除非元件是在類匯出幀的後面載入。
為了在第10幀以後載入元件,必須設定元件在第1幀不能匯出,然後我們在第10幀後放置每個元件的虛的例項,這些虛的例項是不能被使用的,它只是用來載入元件。
下面的步驟就是阻止Button例項在第1幀匯出,其它元件的設定方法與些類似:
1、在庫中選中Button元件
2、單擊庫面板的右上角,從下拉選單中選擇“連結”
3、在連結屬性對話方塊中的連結一欄,不選中“第1幀匯出”多選按鈕
4、單擊確定按鈕
當一個元件的“第1幀匯出”多選按鈕沒選中時,除非一個元件例項被放在了時間軸上,否則元件將不被影片編譯。元件將在放置它的例項的幀上匯出,但是在元件匯出之前,元件的初始化過程仍需要一個可用的類。因此,在CurrencyConverter.fla檔案中,我們將在第12幀放置每個元件的例項。為了存放虛的元件例項,要建立新的圖層和關鍵幀:
建立一個名為load components的圖層,在第12和13幀插入關鍵幀,這兩幀的作用是不讓虛的例項顯示在應用程式中,虛的例項只是用來載入,CurrencyConverter類是真正的元件例項的創造者。
當元件載入幀製作好後,把虛的例項放在時間軸上:
1、選中第12幀
2、從庫中拖入每個元件到場景中
3、就像在圖12-2中顯示的一樣,隨便的使用元件檢查器為元件例項增加虛的表示不被使用的文字。
圖12-2 應用程式的時間軸和場景
12.2.2 開始應用程式
在第11章,我們知道了通過呼叫第一個類的mian()方法來開始應用程式,在這裡,也將通過呼叫urrencyConverter類的mian()方法來開始應用程式,當類和元件被載入後,main方法將在CurrencyConverter.fla時間的scripts圖層的第15幀被呼叫。下面是呼叫的程式碼:

import org.moock.tools.CurrencyConverter; 
CurrencyConverter.main(this, 0, 150, 100); 

注意:通過使用完整的、有效的包路徑,import關鍵字允許我們通過CurrencyConverter類的類名訪問CurrencyConverter。上述的程式碼的意思是,類的main( )方法要指定四個引數:擁有貨幣轉換的mc、深度、水平位置和垂直位置。
fla檔案現在已經準備好了,我們將把注意力轉移到類的建立和管理應用程式本身。
12.3 CurrencyConverter類
CurrencyConverter類要實現3個任務:
l    提供一個方法開始應用程式
l    建立應用程式介面
l    響應使用者的輸入等操作
在除錯完成上述任務的類程式碼之前,你應該快速瀏覽例12-1中程式碼清單。現在,你沒有必要太仔細的閱讀程式碼,在這章的後面將會對這些程式碼做詳細的介紹。
例12-1: CurrencyConverter類
12.3.1 匯入元件包
CurrencyConverter類需要用到各種各樣的元件類,我們需要的元件類位於包mx.controls中。在CurrencyConverter類中,我們要通過元件類的類名來使用這些元件,如as mx.controls.Button 或 mx.controls.ComboBox,這個明顯是很麻煩的,因此,在定義CurrencyConverter類之前,我們匯入整個包:

import mx.controls.*; 

一旦這個包被匯入,我們就不用使用完整的類名,可以直接使用如Button等元件類,要特別注意的是,並不是所有的元件都是位於mx.controls包中,如一些容器元件如Window 和 ScrollPane是位於包mx.containers中。要檢視元件的包,可參考幫助。
12.3.2 CurrencyConverter類屬性
CurrencyConverter類定義了兩種一般的屬性:類屬性指定了貨幣的兌換率,例項屬性儲存了應用程式所需的元件:
程式碼略
出於對本例子的考慮,在類屬性中的兌換率是不變的,在真實的貨幣轉換應用程式中,它們更可能是通過動態的、儲存在伺服器中的資料代替。
要注意,不是所有UI元件都儲存在例項屬性中,如果一些元件不需要被再次使用,就不用儲存在例項屬性中。當建立一個元件時,我們儲存對元件例項的一個引用只是設想類裡的另一個方法稍後要使用它。
12.3.3 main()方法
這個應用程式開始的方法就是main()方法:

public static function main(target:MovieClip, depth:Number, x:Number, y:Number):Void { 
        var converter:CurrencyConverter = new CurrencyConverter(target, depth, x, y); 
    } 

main()方法是一個類方法,因為它是為完整的應用程式呼叫,並且沒有和一個特別的類關聯。Main()方法建立了CurrencyConverter類的第一個例項,並把例項儲存在一個本地變數converter中。實際上, CurrencyConverter類建立了一個自己的例項,這個做法是合理的、普遍的。
就像我們先前看到的,main()方法從幀標籤main處被呼叫,當main()方法消失時,指向例項的變數converter也將不存在,它會自動被刪除。然而,應用程式將繼續執行,建立的mc和元件例項即使沒有被儲存在變數或屬性中,也繼續留在場景上,直到它們被移除。
正如我們後面看到的,通過main()方法產生的例項在buildConverter( )方法中能繼續存在,通過buildConverter( )方法建立的mc和元件例項也保持著一個對例項的指向,沒有這個指向,應用程式將不會響應元件事件。
12.3.4 類的建構函式
這個類的建構函式是簡單的,它只是呼叫了buildConverter( )方法來建立應用程式的使用者介面。

public function CurrencyConverter(target:MovieClip, depth:Number, x:Number, y:Number) { 
        buildConverter(target, depth, x, y); 
    } 

這個建構函式傳遞引數給程式的另一個部分,在這個例子中,是傳遞給通過引數建立使用者介面的buildConverter( )方法。
12.3.5 建立使用者介面
正如剛才學的,這個應用程式的介面是通過buildConverter( )方法建立的,為了建立使用者介面,buildConverter( )方法例項化了UI元件,定義了事件處理器來指示介面的行為。
你已經在前面的例12-1中看了buildConverter( )方法,現在讓我們一行一行來看。
buildConverter( )方法的第一行對一些程式設計師可能是陌生的,它定義一個區域性變數thisConverter,來儲存對當前物件的一個引用。
var thisConverter:CurrencyConverter = this;
儲存一個當前物件到一個區域性變數,只是允許當前物件能被巢狀的函式呼叫,當這些巢狀的函式存在時,當前物件也是存在的。不久我們將看到,事件處理器能在巢狀的函式中執行。它們使用變數thisConverter來訪問CurrencyConverter類的例項,關於這個技術的更多資訊,在第14章還會提到。
12.3.5.1 介面容器
現在我們繼續建立介面元素,首先,要建立一個影片剪輯容器用來放置所有的元件,我們將給這個容器命名為converter,放在指定深度的target影片剪輯裡面,回憶在main()中的引數target和depth,這兩個引數先傳遞給建構函式,再傳遞給buildConverter( )方法:
converter_mc = target.createEmptyMovieClip("converter", depth);
把所有的元件放在一個影片剪輯裡,把這些元件做為一個群體來操作將變得非常容易。例如,要移動所有的元件,只需移動影片剪輯的座標:

converter_mc._x = x; 
converter_mc._y = y; 

這時的x和y是提供給main()方法的引數。
注意:我們的影片剪輯容器儲存在例項屬性converter_mc中,儲存影片剪輯到屬性保證了它能被外部的buildConverter( )訪問,或者說是出於重新設定或刪除它的目的。在我們的這個案例裡,我們沒有重置或刪除這個容器。因此,從理論上講,我們能把它儲存在代替屬性的區域性變數裡。然而,我們把它儲存在了例項屬性converter_mc裡,只是為了在將來能把類增加功能。
13.5.5.2 標籤(Label)元件
現在我們的容器已經準備好了,我們就能把元件放在它的裡面,通過使用Label元件,先給應用程式一個標題,Label元件常來顯示一個單行的文字:
下面的程式碼是在converter_mc裡建立一個名為title的Label元件例項,title的深度為0:
var title:Label = converter_mc.createClassObject(Label, "title", 0);
在我們這個應用程式裡,所有的元件都是用UIObject 類的 createClassObject( )方法來建立,這個方法有三個引數,分別用來指定:
l    要建立的元件類
l    元件的例項名
l    在父影片剪輯或元件裡的深度
createClassObject( )方法返回了一個新元件例項的指向,在這個案例的title例項裡,我們把這個指向儲存在了變數title裡,之所以使用區域性變數title,是因為在後面不需要使用title例項,如果在其它地方我們還要訪問title,我們應把它儲存在一個例項屬性中。
注意那個例項名title,只是按照習慣要被使用,我們從來不會在程式碼中使用這個名字。在我們的應用程式中,我們都通過變數或屬性來指向元件。在這個案例中,我們通過變數名title指向title例項,而不是通過它的例項名(這時變數名和例項名碰巧是相同的)。按照習慣,大部分的元件的例項名都與儲存這個例項名的變數或屬性相匹配。然而,沒有規定例項名要和變數或屬性名要匹配,只有變數或例項名與我們的應用程式有關(例項名被忽略)。
現在讓我們近處看一下常用於建立Label例項的程式碼:

converter_mc.createClassObject(Label, "title", 0); 

MovieClip類有沒有定義createClassObject( )方法,為什麼能在MovieClip類的例項converter_mc裡面呼叫createClassObject( )方法呢?因為在執行時,通過V2元件架構(連同各種各樣的方法)把這個方法加入到了MovieClip類裡。只有一個類宣告為動態時,才能在執行時把方法或屬性加到這個類裡面,就像在MovieClip類裡面定義一樣。
因為我們是通過mc來訪問createClassObject( )方法,所以我們也不用擔心這個方法返回了一個數據型別為UIObject的物件。通過使用title變數,型別Label是不必需的。從理論上講,下面的程式碼通常會出現型別不匹配的錯誤,因為createClassObject( )方法返回的是UIObject的型別,但是title的資料型別是Label。

var title:Label = converter_mc.createClassObject(Label, "title", 0); 

然而,沒有錯誤發生是因為型別檢查在執行時對動態加入的方法沒有進行,但如果這個方法不是動態加入的,如任何元件都有createClassObject( )方法,如果你在一個元件中呼叫createClassObject( )方法,就要進行型別檢查,此時這個不匹配錯誤就會發生。為了阻止一個編譯錯誤,你必須指定返回值為你建立的物件的型別,例如,這裡我們指定createClassObject( )方法的返回值為Label型別,如果converter_mc裡用元件例項代替影片剪輯例項,下面的型別轉換是必需的:

var title:Label = Label(converter_mc.createClassObject(Label, "title", 0)); 

現在,title例項已經被建立,我們將調整它的屬性:

title.autoSize = "left"; 
title.text = "Canadian Currency Converter"; 
title.setStyle("color", 0x770000); 
title.setStyle("fontSize", 16); 

12.5.3 說明(Label)元件
要建立這個說明元件,我們將建立另一個Label元件,建立方法與title的類似,我們把label例項儲存在名為instructions的變數中:

var instructions:Label = converter_mc.createClassObject(Label, "instructions", 1); 
instructions.autoSize = "left"; 
instructions.text = "Enter Amount in Canadian Dollars"; 
instructions.move(instructions.x, title.y+title.height+5); 

上述程式碼的最後一行是把instructions例項放在低於title例項5畫素的位置。
注:設定元件位置的方法只有move()方法,通過讀寫屬性x和y來設定元件的位置是沒有用的,要注意,元件支援x,y,width等屬性(沒有下劃線),而MovieClip例項支援_x等屬性(有下劃線)
12.3.5.4 輸入(TextInput)元件
隨著兩個Label的建立,我們把目光移向接受使用者輸入的TextInput元件,第一個TextInput元件建立的程式碼如下:

input = converter_mc.createClassObject(TextInput, "input", 2); 
input.setSize(200, 25); 
input.move(input.x, instructions.y+instructions.height); 
input.restrict = "0-9."; 

注:設定元件的尺寸只能通過setSize()方法,不能使用width和height屬性。
接下去要定義當用戶按下ENTER鍵時發生什麼,首先建立一個事件偵聽器物件,用來接收事件:

var enterHandler:Object = new Object( ); 

在這個物件例項裡面,定義一個enter()方法,當用戶按下ENTER鍵時,這個方法會自動被呼叫:

enterHandler.enter = function(e:Object) { 
    thisConverter.convert(); 

enter()方法通過thisConverter變數訪問了convert()方法,當input例項存在時,變數thisConverter是可以被巢狀的enterHandler.enter()方法訪問:
最後,註冊物件例項接收enter事件:
input.addEventListener("enter", enterHandler);
雖然使用一個物件例項處理事件是很合理的,但在更復雜的例子中,一個事件偵聽器物件有充分的理由是一個獨立的類的例項,不管怎樣,當一個單一的事件產生單一的響應時,用事件處理函式比用物件例項處理事件更有可能的。在的應用程式轉換按鈕中,我們將使用事件處理函式來處理事件。後面我們也將學習MM為什麼不鼓勵使用事件處理函式。在這個特殊的enterHandler.enter()的例子中,由於Textinput類不能使用事件處理函式的bug,我們被迫使用一個偵聽器物件。
12.3.5.5 貨幣拾取(ComboBox)元件
現在我們準備一個下拉選單,來列出讓使用者進行轉換的貨幣型別,ComboBox元件儲存在currencyPicker屬性中:

currencyPicker = converter_mc.createClassObject(ComboBox, "picker", 3); 
currencyPicker.setSize(200, currencyPicker.height); 
currencyPicker.move(currencyPicker.x, input.y+input.height+10); 

然後列出使用者可以選擇的貨幣型別,其中data屬性將被convert( )方法使用:

currencyPicker.dataProvider = [ 
{label:"Select Target Currency", data:null}, 
{label:"Canadian to U.S. Dollar", data:"US"}, 
{label:"Canadian to UK Pound Sterling", data:"UK"}, 
{label:"Canadian to EURO", data:"EU"}]; 

12.3.5.5 轉換按鈕(Button)元件
在前面我們已經設定一個按鍵事件(ENTER),現在要為不喜歡使用按鈕的使用者增加一個可見的轉換按鈕。
我們這時建立是的mx.controls.Button元件類的例項,注意要和Button符號的例項區別開來。因為我們較早的匯入mx.controls.*包,編譯器就能知道它指向的是Button元件類的例項。
建立Button元件例項:

var convertButton:Button = converter_mc.createClassObject(Button, "convertButton", 4); 
convertButton.move(currencyPicker.x+currencyPicker.width+5, currencyPicker.y); 
convertButton.label = "Convert!"; 

最後,我們用事件處理函式定義一個click事件:

convertButton.clickHandler = function(e:Object) { 
    thisConverter.convert(); 
}; 

上面的程式碼示例了元件事件使用的一種方法,它定義了一個的匿名函式,當click事件發生時,這個函式能自動呼叫。
由於匿名函式是巢狀在buildConverter( )方法的裡面,它已經訪問了buildConverter( )的區域性變數,因此,通過區域性變數thisConverter ,convertButton能指向當前的CurrencyConverter類的例項。
13.3.5.7 結果(TextArea)元件
我們的介面幾乎已經完成了,還需要一個TextArea元件例項顯示貨幣轉換的結果,下面是建立的程式碼:

result = converter_mc.createClassObject(TextArea, "result", 5); 
result.setSize(200, 25); 
result.move(result.x, currencyPicker.y+currencyPicker.height+10); 

為了阻止使用者替換TextArea元件例項中的內容,要加上下面的程式碼,因為它預設值是true,表示可編輯的:
result.editable = false;
12.3.6 基於使用者的貨幣轉換
在前面,我們建立了使用者介面,當用戶click轉換按鈕時,會呼叫convert( )方法,這個方法能夠進行轉換貨幣,也能顯示出錯誤資訊,方法中的程式碼提供了元件怎樣被訪問和操作的一個很好的例子,程式碼如下:
這個類方法首先建立兩個區域性變數,convertedAmount用來儲存轉換後的貨幣值,origAmount用來儲存使用者輸入的值:

var convertedAmount:Number; 
var origAmount:Number = parseFloat(input.text); 

輸入框的內容可能是空的,或者它不是一個有效的值,因此下面程式碼的任務是檢查是否把這個值進行了String到Number的轉換,如果轉換不成功,origAmount的值將是NaN,因此當這個值是NaN時,我們說它不是一個有效值。
if (!isNaN(origAmount)) {
如果這個值是有效的,我們就檢查currencyPicker.selectedItem.data(下拉列表中被選中的貨幣值), selectedItem屬性儲存了一個對ComboBBox中當前選項的指向,它是前面建立的dataProvider陣列的一個物件,為了確定哪個選項被選中,我們參考物件的data屬性,它可能是null, "US," "UK," or "EU."中的一個,如果data屬性為null,說明沒有選項被選中,我們就不用進行轉換貨幣:
if (currencyPicker.selectedItem.data != null) {
如果是其它的幾個之一,我們用switch語句來確定到底是哪個值,根據這個值進行相應的轉換:

switch (currencyPicker.selectedItem.data) { 
                case "US" : 
                    convertedAmount = origAmount/CurrencyConverter.rateUS; 
                    break; 
                case "UK" : 
                    convertedAmount = origAmount/CurrencyConverter.rateUK; 
                    break; 
                case "EU" : 
                    convertedAmount = origAmount/CurrencyConverter.rateEU; 
                    break; 
                } 

一旦轉換成功,我們將結果列出:

result.text = "Result: "+convertedAmount; 

當沒有貨幣被選中時,我們提示使用者進行選擇:

result.text = "請選擇一種貨幣"; 

如果是一個無效值,提示使用者輸入一個有效值:

result.text = "當前值是無效的"; 

12.3.7 匯出最終的應用程式

匯出時要注意版本,V2 元件要求播放器的版本是6.0.79.0 或更高,但我在6.0.40.0中測試時,應用程式能很好的執行。

  這章討論在許多工程中和開發者之間共享類庫的各種方法。在開始討論之前,要注意:flash的類分配特徵並不是很精煉,到目前為止,共享類最簡單的方法是釋出原始碼。在講不通過釋出原始碼怎樣共享類之前,我們將先講這種最簡單的方法,因為當你出售一個專業類庫的時候可能要那樣做。
類庫是一個通常的程式術語,只是簡單的指一群類,不要把它和fla檔案庫、庫面板、共享庫(在創作時共享庫資源)和執行共享庫(在執行時共享庫資源)混合起來,這些術語中的每一個都是唯一的,這不是當前討論的內容。
類庫只是程式設計師用來發布一群類到一個團隊或其它地方的行話,在另一個方面,包是一個正式的用來定義類的語法名稱空間(為了防止和其它類的命名衝突)。
類庫可能通過as、swf和swc的形式分配給其它開發者,這章將討論這三種方法。 
14.1 共享類的原始檔
共享類庫最可能的原因是為了在多個工程中重複使用它們。例如,假設你正在做一個名叫Spider Services的網上商店(http://www.spiderservices.com/),你已經寫了一個處理各種文字效果的TextAnimation類,你要在你做的兩個站點中使用這個類,比在兩個工程的資料夾中放置一份拷貝更好的方法是,你把類放在中間,每個工程只是指向它,例如,在windows中,你應該把類儲存在下面的目錄中:
c:/data/actionscript/com/spiderservices/effects/TextAnimation.as
為了使這個類能被兩個工程都能訪問,你應把c:/data/actionscript增加到flash的全域性類路徑中。
如果在你的團隊中有多個成員,你可能認為把類放在中間伺服器是方便的,這樣每個人都可以使用它。例如:你可能要把所有的共享類都放在叫codecentral的伺服器上,存放目錄與你公司域名相配(/com/spiderservices)。
//codecentral/actionscript/com/spiderservices/effects/TextAnimation.as
這個方法是極度危險的,也是不推薦使用的。
注:
如果你把類放在一箇中間伺服器上並允許其它開發者直接修改,一個開發者容易覆蓋另一個開發者的修改,而且,如果伺服器和個人電腦的時鐘不同步,在編譯時,類的最後一個版本可能不會被包括在影片內。為了避免這個問題,你將總是使用版本控制軟體去管理你的類檔案。一個流行的選擇是CVS (見 www.cvshome.org)。
在一個大的工程中,你可能使用一些工具使swf的輸出自動化,例如Apache Ant (http://ant.apache.org).,為了那樣做,你將執行JSFL告訴flash為每個fla建立swf檔案,這些內容超出了本書的範圍,但這有一個例子

// Code in exportPetSupplies.jsfl: 
// =============================== 
// Open the .fla file. 
var doc = fl.openDocument("file:///c|/data/projects/pet/petsupplies.fla"); 
// Export the .swf file. 
doc.exportSWF("file:///c|/data/projects/pet/petsupplies.swf", true); 
// Quit the Flash MX 2004 authoring tool (optional). 
fl.quit(false); 
// Command issued on command line from /pet/ directory: 
// ==================================================== 
"c:/program files/macromedia/flash mx 2004/flash.exe" exportPetSupplies.jsfl 

14.1.1 在執行時載入類
當使用同一個類製作多個swf檔案時,把類編譯到每個swf中是一種空間浪費,當檔案的尺寸有關係時,為阻止這種事情發生,你可能把類庫放到一個單獨的swf檔案並在執行時載入它,一旦這個庫在第一時間載入,它可能隱藏在使用者的機器中,然後不需重新下載它就能被其它swf利用。
注:一個類庫在執行時載入稱為動態類庫
為了建立這個動態類庫,我們編譯類庫到一個swf檔案中,然後使用loadMovie()把它載入到任何一個需要類庫的swf檔案中。然而,為了使這種技術能正常工作,我們必須確定在庫中的類被排除在載入它們的影片中。為了實現阻止類被編譯到載入它們的影片中,我們使用排除XML檔案。這個xml能讓fla檔案本地訪問類,但能阻止這些類被包含在輸入的swf檔案,這樣允許在執行時被載入。
為了建立執行載入的類庫,我們返回到前面的例子:
下面這些步驟是必須要做的:
1、在類庫中建立類
2、建立含類庫的swf檔案
3、建立載入含類庫swf檔案的影片
4、建立排除xml檔案
14.1.1.1、在類庫中建立類
建立一個類庫的第一步是建立它包含的類,我們的角色類是TextAnimation,儲存在c:/data/actionscript/com/spiderservices/effects/TextAnimation.as,對於這個例子,我們的焦點是類庫的建立 ,因此我們沒給出真實的類程式碼,只在建構函式中提供了一個trace()來檢查這具類是否在工作。

class com.spiderservices.effects.TextAnimation { 
public function TextAnimation ( ) { 
trace("Imagine a text effect with great majesty."); 

現在類庫已經建好,下一步建立含類的swf檔案
14.1.1.2、建立類庫(swf檔案)
為了建立這個swf檔案,跟隨以下步驟
1、建立目錄c:/data/spiderservices/spidercore。
2、增加全域性類路徑c:/data/actionscript
3、建立一個fla檔案,儲存在c:/data/spiderservices/spidercore/spidercore_runtime.fla
4、第1幀輸入:

com.spiderservices.effects.TextAnimation 

如果類庫中含有更多有類,這些類都應列在第1幀,編譯器會自動查詢幷包括所有有關的類(例如,在TextAnimation中使用了Tween,Tween類就會自動的包括到swf檔案中),這樣,我們就不用一個個匯入TextAnimation類中所需的類。
5、在第2幀插入一關鍵幀,輸入:
6、在第2幀輸入程式碼:

_parent.spidercoreLoaded(); 
stop(); 

7、輸出swf檔案。
8、儲存fla檔案
類庫建立好後,就可以在任何一個影片中使用它們
14.4.1.3、建立載入類庫的影片
在這個例子中,載入spidercore_runtime.swf是公司的主頁,建立主頁影片:
1、增加目錄c:/data/spiderservices/barkys
2、新建一個fla檔案,儲存在c:/data/spiderservices/barkys/barkyshome.fla
3、在第1幀輸入:

import as.TextAnimation; 
function spidercoreLoaded():Void { 
    var ta:TextAnimation = new TextAnimation(); 

// Load class library. 
this.createEmptyMovieClip("spidercore", 0); 
this.spidercore.loadMovie("../spidercore/spidercore_runtime.swf"); 

homepage這個影片是準備用來使用類庫的,這裡有個問題:如果在當前使用,它會自動包含TextAnimation類到影片中,我們可不想讓這種事情發生,因為我們要通過spidercore_runtime.swf來載入類。我們不需要載入兩次類,因此,需要建立一個特殊的xml檔案,告訴編譯器不要把TextAnimation包含進barkyshome.swf中。
你可能設想只通過移除c:/data/actionscript路徑,就能使TextAnimation類不被包含到barkyshome.swf中。事實上,就是可以的,但由於型別檢查的原因也阻止編譯器查詢TextAnimation類,因此,型別錯誤將發生,barkyshome.swf將不能被編譯,因此,雖然我們在執行時載入類,我們仍需在創作時訪問這些類。
14.1.14、建立xml檔案
在這個檔案中,指定哪些類將被編譯進相關的swf檔案中,我們將阻止在執行時動態載入的類編譯進應用的swf檔案中。
1、建立一個名為barkyshome_exclude.xml檔案,儲存在c:/data/spiderservices/barkys/barkyshome_exclude.xml。
排除檔案的精確名字是很重要的,這必須與應用它的fla檔名正確匹配。
2、這個排除檔案阻止指定類被編譯進相關的swf檔案,為了阻止TextAnimation類被編譯到swf檔案,在barkyshome_exclude.xml中增加程式碼:

這時有一個假定的排除檔案,顯示怎樣來排除多個類,它排除了下面列出的三個類

3、儲存
在標籤中通過列出TextAnimation類,我們強迫它排除在barkyshome.swf檔案中。在spidercore_runtime.swf類庫中的每個類都應該列在標籤中。
注:編譯不會自動排除依賴的類,例如:要spidercore類庫包含一個被TextAnimation 使用的Tween類,但barkyshome_exclude.xml沒有在標籤列出此類,Tween將被包含在barkyshome.swf中。
我們的spidercore類庫現在已經準備好使用了
14.1.1.5 測試
通過輸出barkyshome .swf檔案來測試這個類庫,barkyshome.sw將不包含TextAnimation類,但通過動態類庫spidercore_runtime.swf可以訪問它,記住,類庫能載入是因為我們告訴它:

// Load class library. 
this.createEmptyMovieClip("spidercore", 0); 
this.spidercore.loadMovie("../spidercore/spidercore_runtime.swf"); 

你將在輸出面板中看到:
Imagine a text effect with great majesty.
如果我們想要載入另一個類庫,第2版本的類庫不會覆蓋第一個版本的,它將被hu略,為了防止命名衝突,特別我們使用動態類庫的時候,讓你的類在有唯一名字的包裡。