ActionScript 2.0/MovieClip 簡介
關鍵概念
ActionScript 2.0 圍繞 MovieClip 展開。(它們在 AS3 中的重要性有所下降,但它們仍然是 Flash 應用程式的重要組成部分。)在本長篇章節中,我們將深入瞭解 MovieClip 的細節。
舞臺 是所有動作發生的地方。Stage 類是一個包含與舞臺相關的靜態函式、靜態屬性和事件處理程式的類。
我們需要了解的第一個屬性是 Stage.width 和 Stage.height。這些是只讀屬性,這意味著我們可以檢索它們的值,但不能在執行時更改它們。它們是在 Flash IDE 本身中透過修改>文件視窗設定的。以下程式碼檢索舞臺中心點的座標
| 程式碼 | 結果 |
|---|---|
var centrePoint:Object = {x:Stage.width/2, y:Stage.height/2};
trace(centrePoint.x);
trace(centrePoint.y);
|
|
請注意我們如何使用屬性 x 和 y 建立了一個物件。這將在本章以及第二節中派上用場。
有時,我們希望舞臺“跳出”播放器或瀏覽器的框框,並佔據整個螢幕。這稱為全屏 模式。Stage 類有用於執行此操作的函式。請注意,全屏模式必須由使用者輸入啟動,應用程式本身不允許這樣做。同樣值得注意的是,鍵盤輸入在全屏模式下是被停用的。此外,全屏模式只能在應用程式嵌入網頁時使用。這是因為安全原因。HTML 程式碼也需要稍微修改以支援全屏模式。
為了切換全屏模式的開啟和關閉,應該更改 Stage.displayState。
到目前為止,您應該對 Flash 時間軸非常熟悉,但它們到底是如何工作的呢?
當沒有 ActionScript 的 Flash 應用程式執行時,一個播放頭 會遍歷主時間軸的幀,並逐個播放它們。當舞臺上存在 MovieClip 符號時,它們各自也有一個播放頭和時間軸。播放頭移動的速度稱為幀速率,以每秒幀數 (fps) 為單位。例如,一個幀速率為 10 fps 的應用程式每秒移動十次。
現在,當 ActionScript 介入時,情況就有點不同了。要記住的第一件事是,每幀中的程式碼在幀顯示之前執行。例如,如果您將 gotoAndStop(3); 放在 MovieClip 的第一幀中,它將直接跳到第三幀,而不會顯示第一幀。有一些函式可以移動播放頭,我們已經在第一節中學習了它們,所以這裡快速回顧一下
play()和stop()分別按順序播放和停止播放幀。gotoAndPlay(frame)和gotoAndStop(frame)將分別跳轉到指定的幀,然後播放和停止 Flash。prevFrame()和nextFrame()分別跳轉到上一個和下一個幀。除非目標幀上存在stop()語句,否則它們將播放。
您可能認為,一旦播放頭停止,例如使用 gotoAndStop 或 stop,幀速率就不再重要了。這與事實相去甚遠。還記得事件嗎?當事件觸發時,螢幕不會立即改變。相反,它會等到下次“進入”幀時才會改變,這會以幀速率發生。此規則有兩個例外,都涉及一個特殊函式;我們將在本章稍後討論其中一個,而在下一章中討論另一個。
MovieClip 類的 onEnterFrame 事件允許程式碼以幀速率不斷執行。以下示例展示瞭如何使一個盒子落下
| 程式碼 | 結果 |
|---|---|
//Assume that 'box' is a MovieClip instance on the stage.
onEnterFrame = function(){
box._y++;
trace("The box moved!");
}
|
|
現在假設我們希望應用程式的底部邊緣充當地面。我們應該如何更改程式碼?
| 程式碼 | 結果 |
|---|---|
//Assume that 'box' is a MovieClip instance on the stage.
onEnterFrame = function(){
if(box._y != Stage.height - box._height){
box._y++;
trace("The box moved!");
if(box._y > Stage.height - box._height){
box._y = Stage.height - box._height;
}
}
}
|
|
主時間軸的幀數有限。如果您想建立一個包含大量幀的 Flash 應用程式,例如偵探遊戲,這可能不夠。此外,在一個包含大量幀的應用程式中,如果您將所有幀都放在同一個時間軸上,可能會很煩人。幸運的是,這個問題有一個解決方案:場景。一個 Flash 應用程式可能有多個場景。單擊 Flash IDE 中的視窗選單以建立、刪除和重新命名場景。有四個函式可以更改場景
- prevScene(scene);
- nextScene(scene);
- gotoAndPlay(scene, frame);
- gotoAndStop(scene, frame);
您可能想知道為什麼 gotoAndPlay 又出現了!嗯,這個 gotoAndPlay 與 MovieClip 方法 gotoAndPlay() 不同。首先,MovieClip.gotoAndPlay(frame) 和 MovieClip.gotoAndStop(frame) 不需要第一個 scene 引數。所有四個函式都是全域性函式,無論您在哪裡呼叫它們,它們始終(無一例外)會移動主時間軸。以下是一個包含三個場景(firstScene、secondScene、lastScene)的示例
| 程式碼 | 結果 |
|---|---|
|
在第一個場景的第一幀上 stop();
trace("Welcome to firstScene!");
Mouse.addListener(this);
this.onMouseDown = function(){
if(Scene.currentScene != "lastScene"){
nextScene();
} else {
gotoAndPlay("firstScene", 1);
}
}
在第二個場景的第一幀上 trace("Welcome to secondScene!")
在第三個場景的第一幀上 trace("Welcome to lastScene!")
|
|
不幸的是,Scene.currentScene 在較舊的 Macromedia 版本的 Flash 中不可用。因此,您可能需要想出一些巧妙的方法來解決這個問題。例如,您可以在最後一幕的舞臺外放置一個帶有奇怪名稱的影片剪輯。如果該影片剪輯已定義,那麼滑鼠點選應導致移動到第一幕。
我可以命名幀嗎?
[edit | edit source]幀號通常很難記住。為最重要的幀命名通常是個好主意。幀名稱為幀標籤。要標記幀,請在屬性面板中鍵入名稱。然後,標籤可以替換 gotoAndPlay 函式中的幀號(影片剪輯和全域性)。
| 程式碼 | 結果 |
|---|---|
//Assume that the fps is 20 and someImportantFrame is frame 5.
var timePassed:Number = 0;
onEnterFrame = function(){
if(_currentframe == 1){
timePassed++;
if(timePassed >= 20){
gotoAndPlay("someImportantFrame");
}
} else if(_currentframe == 5){
trace("Welcome to Frame 5!");
}
}
|
|
如何更改影片剪輯的外觀和位置?
[edit | edit source]影片剪輯和座標
[edit | edit source]正如我們已經討論過的,_x 和 _y 是影片剪輯在其父級中(左上角)的 x 和 y 座標。這很好,但我們如何在影片剪輯在主時間軸上方兩級時找到它在舞臺上的座標?反過來呢?我們如何根據舞臺上的另一個影片剪輯找到影片剪輯在舞臺上的座標?
區域性座標是另一個影片剪輯內部的點的座標,而全域性座標(也稱為舞臺座標)是舞臺上點的座標。MovieClip.localToGlobal() 和 MovieClip.globalToLocal() 函式在區域性座標和區域性座標之間進行轉換。讓我們一一嘗試。將一個蘋果影片剪輯例項放置在舞臺上,然後在它裡面放置一個蠕蟲影片剪輯例項。我們的任務是找到蠕蟲相對於舞臺的座標。將以下程式碼放在主時間軸的第一幀上
| 程式碼 | 結果 |
|---|---|
var someCoordinates:Object = {x:apple.worm._x, y:apple.worm._y};
apple.worm.localToGlobal(someCoordinates);
trace("Global coordinates: (" + someCoordinates.x + ", " + someCoordintes.y));
|
|
_xscale 和 _yscale
[edit | edit source]_xscale 是影片剪輯在庫中的原始寬度與縮放後當前寬度之比。_yscale 是影片剪輯在庫中的原始高度與縮放後當前高度之比。它們與 _x 和 _y 屬性無關!如果 _xscale 和 _yscale 相等,那麼影片剪輯的縱橫比將保持不變。
| 程式碼 | 結果 |
|---|---|
apple._width = 10;
apple._height = 10;
if(apple._xscale == apple._yscale){
trace("Same aspect ratio!");
} else {
trace("Different aspect ratio!");
}
trace("Global coordinates: (" + someCoordinates.x + ", " + someCoordintes.y));
|
|
不透明度
[edit | edit source]_alpha 是影片剪輯不透明度的度量(從 0 到 100)。如果影片剪輯的 _alpha 值為 0,則它完全透明;如果它的 _alpha 為 100,則它完全不透明。嘗試使用 _alpha!
| 程式碼 | 結果 |
|---|---|
apple._alpha = 0;
|
|
什麼是焦點?
[edit | edit source]您是否曾經在螢幕上同時開啟兩個視窗?當您例如輸入時,文字只會影響其中一個視窗。受影響的視窗具有焦點,而另一個視窗則沒有。
影片剪輯也有焦點。
影片剪輯如何響應滑鼠操作?
[edit | edit source]與滑鼠相關的事件有哪些?
[edit | edit source]使用者如何拖動影片剪輯?
[edit | edit source]如何檢測碰撞?
[edit | edit source]要檢測影片剪輯之間的碰撞,其實很簡單,
有兩種方法
if(MovieClip1.hitTest(MovieClip2)) 將檢測 MovieClip1 和 2 的碰撞框是否接觸。
和
if(MovieClip1.hitText(x,y,flag)) 將檢測 MovieClip1 的碰撞框是否接觸 x 和 y 位置。
如何動態建立影片剪輯?
[edit | edit source]什麼是深度?
[edit | edit source]如何使用庫中的影片剪輯?
[edit | edit source]如何建立空影片剪輯?
[edit | edit source]如何複製影片剪輯?
[edit | edit source]如何銷燬影片剪輯?
[edit | edit source]- _quality
- getSWFVersion