Flash片頭loading與MovieClipLoader_Flash教程
推薦:Flash片頭加載loading的基礎討論很早之前我曾經說過“沒有loading的flash,不是完整的flash”。我想那個句話可能偏激了。因為有時候一些不到10k的flash,確實不需要做什么loading。但我始終認為
很早之前我曾經說過“沒有loading的Flash,不是完整的flash”。我想那個句話可能偏激了。因為有時候一些不到10k的flash,確實不需要做什么loading。但我始終認為,做一個優秀的loading是衡量一個flasher水準、甚至態度的,因為loading是唯一一個你不會多看而所有用戶、客戶會看的東西,所以你對loading的重視程度,甚至可以反襯你這個flasher的職業道德。轉載請保留原文地址:http://www.awflasher.com/blog/?id=444
Flash的loading的技術討論共分為三部分:
1、基礎
2、MovieClipLoader相關討論(較深入)
3、V2組件相關問題
前面我們介紹了基礎部分,今天我們對MovieClipLoader做Flash loading做一些深入的相關討論。
讀取外埠數據參與Flash應用程序部署是一件非常重要和常見的工作,尤其是我們經常需要檢測這些數據加載的進度。MovieClipLoader(下稱MCL)類就可以幫我們大大簡化這項麻煩工作。此外,它使得我們能獲取更多的需要,并減少代碼量。我們可以用一個單獨的MovieClip類來載入一個,或者多個外埠資源到指定的MC或者層級,或者我們可以為每一個加載工作制定不同的MCL實例。
我決定分兩部分來完成這篇教程。首先,我們將介紹MCL的基本用法;然后我們將介紹如何使用一個單獨的MCL實例來讀取外埠資源到不同的MC,并且,我們將加入偵聽器對象來參與工作。當然,不通過偵聽器也可以完成任務,我們暫時不介紹偵聽器,因為這樣你會更加輕易理解MCL。
那么,我們首先來大體了解一下MCL有哪些回調函數,后面也會有具體介紹(aw附:回調函數我個人理解就是某一個類組、參數事先確定,擁有指定功效的方法)這里可以了解一下什么叫做回調函數):
MovieClipLoader對象的回調函數:
事件回調函數(嚴格要求數據類型的時候,它們并不是方法,后祥):
* MovieClipLoader.onLoadStart() - 當加載開始的時候觸發
* MovieClipLoader.onLoadProgress() - 在讀取進行中觸發
* MovieClipLoader.onLoadInit() - 讀取資源載入后的第一幀執行完成后觸發
* MovieClipLoader.onLoadComplete() - 當讀取的外埠資源已經完全下載到本地時觸發。
* MovieClipLoader.onLoadError() - 當加載外埠資源出錯時觸發。
* MovieClipLoader.unloadClip() - 將加載的外埠資源移除或終止一個加載工作。
方法回調函數:
* MovieClipLoader.getProgress(target:Object):Object - 讀取外埠資源的進展,參數為MC對象(aw附:其實MC這種數據類型也就是一種對象)。返回一個對象,該對象包含兩種事先預定好的屬性(后祥)
要想好好理解這些回調函數,我們動手試驗一下是最好的方法。當然MCL是Flash7之后才有的,所以別忘了發布的時候發布成為7 的版本號。假如直接用FlashPlayer來調試可能會碰到一些問題,我們推薦在瀏覽器中進行調試(個人意見:對于外埠資源難以獲得情況,比如教育網獲取公網資源,最好不要在IDE中調試)
在我們的例子中,我們將用一個MCL對象來讀取不同的圖片,并將它們置入不同的空MC中。本例中要用到的swf文件和圖像源文件將在Actionscript.org找到(個人建議:其實看完這篇文章要不要源文件沒有必要了)
1、建立一個新的Flash文檔,并在第1幀輸入以下腳本:
function myTrace(msg)
{
_root.traceBox.text = msg newline;
_root.traceBox.vPosition = _root.traceBox.maxVPosition;
}
我們這里是在建立一種跟蹤調試機制,調試的(變量)將輸出到文本框組件中。這里的方法"myTrace"是預先定義好的一個函數,它幫助我們順利完成對某些信息的監控;其中第二句的作用是使文本框隨時輸出最新監控值。
2、現在從組建庫托拽一個TextArea組件進入場景,并給以合適的大小,以及一個實例名稱traceBox(對應上面的腳本)
3、接下來,我們要建立一個新的MC元件。并在場景上部署3個實例,為它們分別命名為myMC1,myMC2,myMC3。我們將把圖片或者swf影片裝載進入它們,并且,在它們下載到本地后按照需求調整它們的尺寸。其實,對圖片人為地改變尺寸會造成許多不好的后果,比如鋸齒的產生,但是為了讓大家了解onLoadInit事件的使用,我們將會這么做。
4、然后,我們建立一個MCL對象,在第一幀輸入以下腳本:
aw附:這里我想羅索以下,關于Object的翻譯。因為上述代碼的注釋中,老外用的是instance這個詞,直譯的話,Object是“對象”;Instance代表“實例”。前者更注重于其數據類型,而后者則更注重于其客觀存在性。
5. 現在我們就可以部署腳本了,在第一幀:
myMCL.onLoadStart = function (targetMC)
{
var loadProgress = myMCL.getProgress(targetMC);
myTrace ("The movieclip " targetMC " has started loading");
myTrace("Bytes loaded at start=" loadProgress.bytesLoaded);
myTrace("Total bytes loaded at start=" loadProgress.bytesTotal);
}
這個函數的第一行中申明了一個(對象類型的)變量,顯然,這個變量的值由myMCL對象的getProgress方法獲得.剛才已經介紹了getProgress方法,這里可以看到,返回的loadProgress.bytesLoaded就是loadProgress對象的bytesLoaded屬性.
這里我再啰嗦一句:為什么返回一個對象,而不返回具體的值。這是有原因的。函數返回值的功能使得程序設計更加完美,然而很多情況下,我們要返回的并非一個值,我們可能返回兩個或者更多的值,甚至它們的數據類型都不相同。這樣,只有通過對象的形式來返回了。這是解決問題最簡單最高效的方法。下面三句myTrace就呼應了之前我們定義的監控函數,這樣就能看到我們關注的變量了。
6、我們已經為onLoadStart事件部署了相應的工作,接下來我們要為上述其他事件部署工作了。緊接著是onLoadProgress,它接受三個參數:targetMC, loadedBytes, totalBytes。分別代表目標容器MC實例;已經讀取的體積、總體積。
myMCL.onLoadProgress = function (targetMC, loadedBytes, totalBytes) {
myTrace ("movie clip: " targetMC);
myTrace("Bytes loaded at progress callback=" loadedBytes);
myTrace("Bytes total at progress callback=" totalBytes);
}
7、我們的onLoadComplete方法僅接受一個參數,它就是容器MC實例。像onLoadStart一樣,我們用getProgress方法來返回讀取情況。
myMCL.onLoadComplete = function (targetMC)
{
var loadProgress = myMCL.getProgress(targetMC);
myTrace (targetMC " has finished loading.");
myTrace("Bytes loaded at end=" loadProgress.bytesLoaded);
myTrace("Bytes total at end=" loadProgress.bytesTotal);
}
8、onLoadInit方法將在所有加載的內容被下載到本地容器MC中之后才開始執行。這將使得你能更好的控制加載進來的內容的屬性。我選擇的圖片非常大,這樣我們可以把讀取過程看得更加清楚,而我也要對已經加載的圖片尺寸進行修整,讓它能全部顯示出來。
myMCL.onLoadInit = function (targetMC)
{
myTrace ("Movie clip:" targetMC " is now initialized");
targetMC._width = 170;
targetMC._height = 170;
}
9、還有一個回調方法onLoadError。假如有錯誤發生,它將會被觸發。作為一個優秀的程序員,部署完善的應用程序的時候,對錯誤發生的避免措施是必不可少的!
myMCL.onLoadError = function (targetMC, errorCode)
{
myTrace ("ERRORCODE:" errorCode);
myTrace (targetMC "Failed to load its content");
}
10、我們終于將最復雜的工作部署好了。接下來我們只用使用loadClip方法讀入我們需要的內容就行了。loadClip方法的兩個參數分別是外埠資源的地址和容器MC的實例。
myMCL.loadClip("http://www.yourdomain.com/test1.swf","_root.myMC1");
myMCL.loadClip("http://www.yourdomain.com/test2.swf ", "_root.myMC2");
myMCL.loadClip("http://www.yourdomain.com/pic.jpg", "_level0.myMC3");
路徑可以選擇相對路徑。注重,路徑的相對性也是一個大問題,當SWF在非本路徑的HTML中被引用的時候,遵從HTML所在的路徑!這一點是很多Flash教程都忽視的。所以,有時候絕對路徑也有絕對路徑的好處。
所有的調試工作最好在瀏覽器中,而非IDE中完成。而且腳本輸出方式必須是AS2。
接下來,我將介紹實時調用MCL的情況。為了能適應更多的應用,我們經常動態地為MCL制定工作。
aw話外音:有時候,我們這樣寫:
1、var mcl:MovieClipLoader = new MovieClipLoader ();
2、var mcl = new MovieClipLoader ();
發現第一種寫法無法為MCL制定onLoadStart等事件方法。這是編譯器根據指定變量的數據類型產生的問題。osflash的一些朋友給了一些有用的觀點,我也發現這個問題正好涉及到Flash內部的事件響應機制,不妨介紹一下:
Flash的三種事件響應機制
1、簡單的回調函數,最老的;
2、偵聽器,ASBroadcaster,FlashMX時代;
3、事件偵聽器,EventDispather,FlashMX2004時代
這里,MCL用的是第二種機制,而整套V2組件則使用最后一套機制。
附:MCL官方申明,注重:上述方法中,僅包含getProgress方法!
intrinsic class MovieClipLoader
{
function MovieClipLoader();
function addListener(listener:Object):Boolean;
function getProgress(target:Object):Object;
function loadClip(url:String, target:Object):Boolean;
function removeListener(listener:Object):Boolean;
function unloadClip(target:Object):Boolean;
}
個人補充:1、2在不嚴格要求數據類型的時候可以通用。
下面開始介紹用偵聽器來檢測MCL事件的方法。在此之前,我們解決一個最常見的問題,我們經常會在論壇中看到有人這樣提問:
引用:我動態地建立了一些MC,并逐個分配給它們一個事件句柄(標志)。然后,我將外埠資源讀取到它們之中。但是這些分配好的事件句柄都不工作了!
緊接著,發問人一般會貼出一對亂七八糟的代碼,并大呼救命。
那么,我們首先來分析一下這個錯誤發生的原因:當外埠資源被載入到一個MC中時,這個MC將會重新初始化。這意味著任何被預先制定好的代碼都將付之東流。對于開發人員已經手動在舞臺上安排好的MC則并沒有相關的麻煩,這是因為任何直接通過onClipEvent制定到MC的代碼都能幸免被重新初始化。而動態建立的MC則進行上述的“初始化”,因為我們是在運行中給它們配置的事件代碼。
我們如何避免這個問題呢?其實方法太多了,很多論壇也進行了極為具體的討論,我就不多贅述了。
你現在也許還記得剛才我介紹的“讀取外埠數據參與Flash應用程序部署是一件非常重要和常見的工作,尤其是我們經常需要檢測這些數據加載的進度”
我們已經介紹了MCL的幾個回調函數,所以這里也不再贅述了。我們現在制作這樣一個效果:縮略圖標式的圖片瀏覽系統。我們將要從外部讀取一些JPG圖片,將它們放入我們動態部署的MC中。并且我們希望這些動態建立的MC都具有各自的onPress事件。我們通過在MC裝載好外部資源之后再為之分配事件。
在我們開始之前,我還想提醒大家注重一些經常出現的疏漏:一定要在發布的時候設置成Flash7 AS2以上的版本;其次,用瀏覽器測試你的效果,而不是IDE;否則你將會得到希奇的結果。
現在,我們開始編制代碼,你會發現它比你想象的要簡單得多。
1、新建一個Flash文檔。
2、找四張100*100像素的縮略圖片。
3、建立一個動態文本框,大概在300*300像素左右,使用12號字體,并使之現實邊框,這樣我們更好監測。別忘了設置它為多行的。
4、建立一個100X100像素的矩形,轉變為MC,然后將它移出場景。這時候,他已經出現在庫中了。在庫中,設置他的鏈接名為“img”,并使其“在第一幀導出”。其實這個矩形會在外部資源載入的時候被取代,現在只是為了調試方便。
5、在剛才放置textBox文本框的層之上新建一層,這一層用于放置我們的代碼,先寫上:
6、現在我們定義一個MCL的實例,此外定義一個基本對象,作為我們的偵聽器:
myListener = new Object(); //define listener
7、接下來我們用偵聽器來偵聽onLoadComplete事件,該事件的作用上文已經提到了。我們現在把它交給listener對象,而不是MCL實例。當然,最終要把偵聽器對象再交回MCL(以偵聽其回調函數)的時候,得到的效果就是我們需要的效果了。
記住,只有當讀取完畢的時候,對MC部署事件任務才是安全可靠的!所以,在onLoadComplete被觸發的時候才部署這個onPress事件給MC:
myListener.onLoadComplete = function(targetMC){
debug.text = "LOADING OF " targetMC
" COMPLETE" newline;
targetMC.onPress = function() {
debug.text = newline
"targetMC = " targetMC._name;
}
}
注:上述代碼中有幾行被人為打斷,但這并不影響效果。
你也許已經注重到了,MC的實例名稱在onLoadComplete被觸發的時候是作為一個參數的身份傳遞給onLoadComplete的,這樣我們控制這個MC就非常方便了。比如這里就可以用點擊MC來檢測事件是否被成功部署給MC。
8、現在我們建立一個函數,它包含一個簡單的循環來部署場景上的MC。并且及時地為每一個部署好的MC分配讀取外埠資源的任務(loadClip方法),代碼如下:
function initClips(){
for (i=1; i<=4; i ){
this.attachMovie("img", "img" i, i);
this["img" i]._x = i*110;
myMCL.loadClip("0" i ".jpg" ,
this["img" i]); //code wrapped
}
}
9、到這里基本上就完成了,F在我們剩下的工作就是注冊偵聽器并且按照需求調用相關函數、方法,反映到代碼上就是以下兩行:
myMCL.addListener(myListener);
initClips();
注重這里的順序,我們的偵聽器對象在調用initClip()函數之前就被作用于MCL實例了,F在我們的MC的onPress事件可以順利工作了,因為當圖片被完全讀入之后,事件才被分配過去。我們的代碼也非常簡潔。我們再也不用為了loading而去制作麻煩的循環了,MovieClipLoader幫我們完成了所有工作!
附:完整代碼如下:
stop();
myMCL = new MovieClipLoader();
myListener = new Object();
myListener.onLoadComplete = function(targetMC)
{
targetMC.onPress = function ()
{
trace("pressed");
}
}
function initClips()
{
for (i=1;i<=4;i )
{
this.attachMovie("img","img" i,i);
this["img" i]._x = i*110;
myMCL.loadClip(url,this["img" i]);
}
}
myMCL.addListener(myListener);
initClips();
到此為止,你應該相信MCL確實是一個不可多得的好東西了吧?
下一節我們討論用V2組件項目做Flash loading的問題。
分享:Flash游戲制作:簡單射擊游戲教程(Fla源文件)本游戲教程涉及自定義鼠標,鼠標跟隨,鼠標事件,簡單動畫,文本框等方面,最終成品如下,游戲難度變化:假如你感愛好,先把所有源文件下載,然后對照文件看以
- 相關鏈接:
- 教程說明:
Flash教程-Flash片頭loading與MovieClipLoader。