三、深度(Depth)
深度(Depth)僅僅需要一個數(shù)字描述,F(xiàn)lash Player 使
用這個數(shù)字來指定對象的層疊位置。所謂層疊是指一種顯示時的的遮蓋關(guān)系。深度值較大則顯示較前,深度值較小則顯示較后,較后的要被較前的遮蓋。深度具有可
比性但僅限于兄弟節(jié)點(diǎn),所以同一父節(jié)點(diǎn)下的兄弟具有不同的深度,同時這個深度也描述了他們之間的層疊關(guān)系。屬于不同父節(jié)點(diǎn)的子節(jié)點(diǎn)可以有相同的深度,但他
們不具有可比性。
編輯環(huán)境下,F(xiàn)lash使用了圖層(Layer) 來組織對象。這時, Flash 并沒有給對象指定一個深度,只有當(dāng)Flash 文檔在運(yùn)行時 Flash Player根據(jù)用戶最初在編輯環(huán)境下的拖放情況來指定對象的深度。這里的圖層可以認(rèn)為是同一父時間軸節(jié)點(diǎn)下子時間軸節(jié)點(diǎn)的集合。圖層和圖層之間不存在交集,而且圖層是一個動態(tài)的集合,隨著程序的運(yùn)行,集合中的元素也會發(fā)生變化。Flash 也可以在運(yùn)行時動態(tài)地創(chuàng)建時間軸,例如使用 attachMovie()、duplicateMovieClip()等語句,但必需以參數(shù)的形式給出要被創(chuàng)建的時間軸的深度。
對象在編輯環(huán)境下的拖放順序以及時間軸上圖層的層疊關(guān)系,用來幫助Flash 確定對象的深度。圖層在Actionscript中是不被引用的,所以在swf文件中也不會有圖層這個概念。在編譯時,圖層被分解為多個對象(多個時間軸),并且每一個對象都會被指定一個深度。當(dāng)Flash 播放時,時間軸會讀取圖層中的內(nèi)容,并根據(jù)和其他對象的相對位置關(guān)系指定它的深度。如果對象所在的圖層較高則獲得一個比較高的深度,如果對象所在的圖層較底則獲取一個較低的深度。與此同時,F(xiàn)lash也會為對象指定一個名稱,實現(xiàn)腳本對該對象的引用。深度概念也影響Flash 中對象的創(chuàng)建,在FileàPublish SettingàLoad Order 中可以設(shè)置對象被創(chuàng)建的順序,指定是由低深度到高深度(Bottom up)地創(chuàng)建,還是由高深度到低深度(Top down)地創(chuàng)建,F(xiàn)lash中的默認(rèn)為前者。
Actionscript 還提供了一些與深度相關(guān)的方法和管理對象:
深度方法或深度管理對象
|
功能描述
|
返回值
|
MovieClip.attachMovie()
|
從庫中創(chuàng)建一個電影剪輯實例。
|
被創(chuàng)建的電影剪輯的引用
|
MovieClip.createEmptyMovieClip()
|
創(chuàng)建一個空的電影剪輯
|
被創(chuàng)建的電影剪輯的引用
|
MovieClip.createTextField()
|
創(chuàng)建一個文本框
|
無返回值
|
MovieClip.duplicateMovieClip()
|
創(chuàng)建一個電影剪輯的拷貝
|
被創(chuàng)建的電影剪輯的引用
|
MovieClip.getDepth()
|
返回電影剪輯的深度
|
深度數(shù)值
|
MovieClip.getInstanceAtDepth()
|
返回占據(jù)指定深度的電影剪輯
|
指定深度下電影剪輯的引用
|
MovieClip.getNextHighestDepth()
|
返回最高的可用深度
|
深度數(shù)值
|
MovieClip.removeMovieClip()
|
移除動態(tài)創(chuàng)建的電影剪輯
|
無返回值
|
MovieClip.swapDepths()
|
交換兩個電影剪輯的深度
|
無返回值
|
DepthManager Component
|
深度管理器
|
|
深度方法和功能描述
這里需要加以說明的是,SwapDepth()方
法可以把在不同深度的兩個對象進(jìn)行深度交換。如果要實現(xiàn)這種交換有兩種方法:一是把兩個對象進(jìn)行調(diào)換,即把上面的拿到下面,把下面的拿到上面,這是對對象
本身進(jìn)行操作;二是直接更改對象的深度屬性,即直接修改指定對象深度的數(shù)值。但是如果使用后者顯然不是在交換深度而是在設(shè)置深度了。SwapDepth()方法是實現(xiàn)對象深度位置的交換而非設(shè)置深度。可以把深度理解為一個容器,比如說是房子,如果兩個人要交換房子,那么必須是你搬過來我搬過去,而僅僅更換門牌是沒有什么用處的。所以深度是只讀的。另外,getDepth()方法可以很方便的獲取MovieClip、Button和TextField對象的深度數(shù)據(jù)。
另外,深度管理器(DepthManager)是一個專門對深度進(jìn)行管理的Flash V2組件,它封裝了若干深度管理的方法:
DepthManager.createChildAtDepth():在指定深度處創(chuàng)建指定元件的子級。
DepthManager.createClassChildAtDepth():在該指定深度處創(chuàng)建指定類的對象。
DepthManager.createClassObjectAtDepth():在指定深度處創(chuàng)建指定類的實例。
DepthManager.createObjectAtDepth():在指定深度處創(chuàng)建一個對象。
DepthManager.setDepthAbove():移動實例到指定實例的深度之上。
DepthManager.setDepthBelow():移動實例到指定實例的深度之下。
DepthManager.setDepthTo():將實例移動到指深度。
四、深度區(qū)域:
在為對象指定深度時必須清楚地了解Flash在深度上的三個區(qū)域。在Flash 中,深度的范圍在-16384到2130690045之間,任何Flash的可視對象都不會超出這個范圍。在播放時,F(xiàn)lash把時間軸中的對象按照默認(rèn)的設(shè)置進(jìn)行加載。-16384到-1是深度的第一個范圍,在這個深度區(qū)域?qū)ο蟛豢梢允褂媚_本創(chuàng)建和移除,用于放置用戶在編輯環(huán)境下創(chuàng)建的對象,這里把它稱為時間軸區(qū)(Timeline)。接下來是0到1048575的深度范圍,在這個深度范圍內(nèi),對象可以使用腳本創(chuàng)建和移除,所以稱為動態(tài)區(qū)(Dynamic)。之后一個區(qū)域稱為保留區(qū)(Reserve),深度范圍在1048576和2130690045之間,可以放置MC但是不可以移除。
Flash的深度區(qū)域:
區(qū)域
|
深度范圍
|
特征
|
時間軸區(qū)
|
-16384 到 -1
|
主要用于放置Flash 編輯時的對象,且對象不可用腳本移除,但可以使用腳本創(chuàng)建。
|
動態(tài)區(qū)
|
0到1048575
|
實現(xiàn)運(yùn)行時的動態(tài)創(chuàng)建、動態(tài)訪問和動態(tài)移除
|
保留區(qū)
|
1048576到2130690045
|
實現(xiàn)運(yùn)行時的動態(tài)創(chuàng)建、動態(tài)訪問,但不支持使用腳本移除對象。
|
Flash 在動態(tài)區(qū)之前提供了時間軸區(qū),用于放置編輯環(huán)境下時間軸中的對象。在編輯環(huán)境下,最底層的對象放置到區(qū)域的最深處——-16384。在通常情況下會從-16383這個深度開始,F(xiàn)lash依次向較高深度放置時間軸中的對象。
接下來是動態(tài)區(qū),在這個區(qū)域可以放置那些可以動態(tài)創(chuàng)建和移除的對象。而且這個區(qū)域也符合一般人的使用習(xí)慣,因為它的深度是從0開始的,而開發(fā)者在創(chuàng)建對象時通常也會考慮這個范圍。在這個范圍可以獲得比較大的自由權(quán),開發(fā)者可以使用腳本動態(tài)地創(chuàng)建和移除對象。如果對象不在動態(tài)區(qū),那么首先可以把對象交換到動態(tài)區(qū),然后再進(jìn)行移除。
保留區(qū)可以理解為動態(tài)區(qū)的一個擴(kuò)展,只是在保留區(qū)中無法使用腳本移除對象,對象在那個區(qū)域可以動態(tài)地被創(chuàng)建。在這個區(qū)域?qū)ο笠部梢允褂胹wapDepth()方法交換到其它的深度區(qū)域。但保留區(qū)還是一個比較特殊的區(qū)域,因為那里的對象不可以被移除,而且深度高的有點(diǎn)離譜。在保留區(qū)Flash為對象提供了一定的存儲空間。
需要特別注意的是,F(xiàn)lash 在使用createEmptyMovieClip()方法創(chuàng)建的空MC時,深度的分配上幾乎沒有什么限制,深度可以指定在-999999999999以下或是999999999999以上。雖然這個深度已經(jīng)超出了剛才討論的那個范圍。
五、時間軸刷新:
關(guān)于深度,可能會遇到一些另人混淆的問題,特別是動態(tài)區(qū)和時間軸區(qū)。當(dāng)時間軸被刷新時,所有的對象將被重新創(chuàng)建。Flash 會掃描位于該時間軸的時間軸區(qū)域,并清除保存在這些深度上的對象。然后Flash 讀取時間軸上的數(shù)據(jù)并重新創(chuàng)建這些對象,但是通過動態(tài)方法創(chuàng)建的對象將被忽略。其中一個例子就是使用gotoAndPlay()返回播放已經(jīng)播放過的幀,例如從第10幀返回到底5幀播放,這時Flash為了重新展示第5幀的內(nèi)容必須刷新時間軸并完全重構(gòu)第5幀的內(nèi)容。但是使用動態(tài)方法創(chuàng)建的對象如果在時間軸刷新時被移除,那么這時并不被自動創(chuàng)建,除非程序給出。
很
明顯,這樣可能會引起一些問題。首先,這樣會失去在時間軸區(qū)域或是使用動態(tài)方法已經(jīng)創(chuàng)建并交換到時間軸區(qū)域的對象。也就是在這中情況,不可以把使用動態(tài)方
法創(chuàng)建的對象交換到時間軸區(qū)域,否則在時間軸刷新時會丟失這些對象。在開發(fā)時為避免這種情況的發(fā)生,可以創(chuàng)建一個單幀停止的MC,這樣的MC可以是安全的,可以不必為時間軸刷新而擔(dān)憂。
另外一個問題是無法移除所需要移除的對象。其原因是由于使用深度交換方法把時間軸區(qū)的對象轉(zhuǎn)移到了非時間軸區(qū),這樣在時間軸刷新時就無法清除該對象了,而且這次刷新還會創(chuàng)建一個新的該對象到時間軸區(qū)。這種情況也應(yīng)該避免發(fā)生。
還有一個需要清楚的問題是場景(Scene)跳轉(zhuǎn)的問題。場景間的跳轉(zhuǎn)不會引起時間軸的刷新,也不會觸發(fā)其他一些特殊的事件。作為場景本身而言,它們是主時間軸的片段,當(dāng)Flash被發(fā)布以后,這些場景便會整合到一起,變成單個的主時間軸。所以用戶在一個場景創(chuàng)建的對象,它仍舊可以在接下來的場景出現(xiàn),當(dāng)然也可以使用腳本使那些對象消失。
六、播放器執(zhí)行順序:
在
深度問題上,還有一點(diǎn)比較容易被人們忽視。正如前面所提到的,深度也會影響到腳本的執(zhí)行順序。事實上深度本身并不影響腳本的執(zhí)行順序,但是深度卻與對象的
創(chuàng)建順序有關(guān)。一般我們都會認(rèn)為,在同一時間軸上,首先被創(chuàng)建的對象會首先執(zhí)行它所包含的腳本。另人感到奇怪的是,在默認(rèn)的發(fā)布設(shè)置下,那些最晚被創(chuàng)建的
對象反而首先執(zhí)行了EnterFrame事件中的腳本。在默認(rèn)情況下對象從最底層開始被創(chuàng)建,這一點(diǎn)我們可以在Flash的發(fā)布選項中設(shè)置。幀腳本是按照它們被創(chuàng)建的順序執(zhí)行的。這樣如果在bottom up 模式下,從技術(shù)角度而言,較低層的腳本反而較早執(zhí)行,但是值得一提的是,EnterFrame事件中的腳本剛剛與之相反。
看來很有必要追究一下EnterFrame事件到底是怎樣的一個事件。EnterFrame事件隨著電影剪輯的幀速被持續(xù)地觸發(fā)。可以認(rèn)為EnterFrame事件是在播放頭進(jìn)入某一幀時觸發(fā)的一個事件,但是在EnterFrame事件中的代碼將先與幀腳本執(zhí)行。但是,對象的創(chuàng)建和Flash的播放(對象狀態(tài)的改變過程)到底是怎樣一個關(guān)系呢?在Flash中第一幀的幀腳本和其它幀的幀腳本有著不同的行為。當(dāng)運(yùn)行一個Swf文
件時,它的第一幀將首先被創(chuàng)建,然后開始載入該文檔中的對象并拖入到舞臺,這個過程可以認(rèn)為是一個初始化的過程。所以在這個過程中隨著對象的載入第一幀的
容量將不斷增大。這樣做的原因也是顯而易見的,只有當(dāng)對象全部載入后,腳本才能執(zhí)行,設(shè)想如果腳本所要操作的對象都不存在,那么腳本必然會發(fā)生錯誤。一旦
所有的對象載入完畢,除第一幀外的其它幀都將被一次性創(chuàng)建,并開始播放。這樣做的另外一個原因是,如果按照先創(chuàng)建,先播放的原則,那么必然導(dǎo)致不同電影剪
輯播放時步調(diào)的不一致。因為創(chuàng)建對象是需要時間的,特別是在網(wǎng)絡(luò)上,它還要有一個下載的過程。這里還要注意的是#initclip和#endinitclip中的代碼塊,它們通常定義在電影剪輯的第一幀,只要符號被定義且被編譯(電影剪輯符號定義了,但不一定都被編譯),那么就執(zhí)行該代碼段,它用于電影剪輯的初始化,所以優(yōu)先于其它腳本執(zhí)行,并且僅執(zhí)行一次,它的運(yùn)行效果將作用到該剪輯的所有實例。
這樣,就可以得出,F(xiàn)lash的執(zhí)行可以分成兩個過程。首先是對象的下載、創(chuàng)建和初始化,接下來是一個播放的過程。播放是一個對象狀態(tài)隨著幀速改變的過程,其狀態(tài)的兩個極端是存在與不存在。這樣在Flash的執(zhí)行過程中,電影剪輯第一幀的腳本將首先被執(zhí)行;然后是播放過程,其腳本執(zhí)行的原則是EnterFrane事件腳本的執(zhí)行先于幀腳本的執(zhí)行。
七、圖層(Layer)、層級(level)和深度(depth)
通常人們會把圖層和層級混淆起來使用,但事實上它們是兩個完全不同的概念。時間軸可以以兩種方式獨(dú)立于主時間軸:電影剪輯(Movie Clip)和層級(Level)。這里所謂的獨(dú)立是指獨(dú)立的播放與停止。圖層(Layer),只在編輯環(huán)境下被看到,用于存放和組織在時間軸上的對象。它們僅僅只是在編輯環(huán)境下出現(xiàn),當(dāng)發(fā)布一個Flash文件時,這些圖層將被壓縮到同一個時間軸上。
層級(Level)位于一個獨(dú)立的時間軸上,用于存儲使用loadmovie方法加載的外部Swf文件。層級(Level)可以使用_level0, _level1, _level3, _leveln 對其進(jìn)行引用。層級越高,就越接近觀察者,也就越容易被看到,這一點(diǎn)與深度是一致的。使用該方法加載的電影將貫穿電影的主時間軸。由于這個原因從外部加載電影的目的常常是為了加載某些聲音,因為聲音不會影響到原來電影的播放。
電影剪輯(Movie Clip)同樣是一個獨(dú)立的時間軸,但是電影剪輯位于庫(Library)中,并不是位于電影的外部。所以它與層級不同,如果需要的話,你可以在幀上創(chuàng)建一個電影剪輯的實例。 從庫中拖動一個電影剪輯到舞臺(Stage),那么就創(chuàng)建了該電影剪輯的一個實例,可以指定一個唯一的名稱對其進(jìn)行引用。電影剪輯可以包含其它的電影剪輯,這就是通常所說的嵌套(nesting)。
深度(Depth)通常會用于swapDepth()和attachMovie()這些方法,用于指定電影剪輯的層疊順序。它可以被認(rèn)為可視對象在時間軸上的層疊順序(Z-Order)。
這里還要指出的是 _root 和 _level0 的區(qū)別。_root 和_level0引用的并非同一個對象,它們是有差別的。_root 指代電影的主時間軸,如果一個電影有多個層級那么_root指代當(dāng)前腳本正在執(zhí)行的那個層級。例如:在層級n中的某個腳本包含了 _root,這時_root返回 _leveln,_root和_leveln才是等同的。
posted on 2008-06-16 15:41
七星重劍 閱讀(965)
評論(0) 編輯 收藏 引用 所屬分類:
Flash Scaleform GFx