Flash AS 教程:動畫事件
2020-07-17 13:19:29
供稿:網友
動畫事件
我們希望能夠使用代碼讓物體動起來,并允許屏幕反復地刷新。前面看過一個使用 enterFrame 影片事件的示例。現在把這種方法運用到 AS 3 中,只需要增加一個 enterFrame 事件的偵聽器即可:
addEventListener(Event.ENTER_FRAME, onEnterFrame);
別忘了導入 Event 類,并創建一個名為 onEnterFrame 的方法。人們常常迷惑,只有一幀怎么能執行 enterFrame(進入幀) 事件呢?事實上,播放頭并非真正地在進入下一幀,它只停留在第一幀上,并不是把播放頭移動到下一幀才形成了 enterFrame 事件,而是用另一種方法:Flash 告訴播放頭何時進行移動,可以把 enterFrame 看成一個定時器,只是有些不精確。
下面我們看看第一個 AS 3 動畫:
package {
import flash.display.Sprite;
import flash.events.Event;
public class FirstAnimation extends Sprite {
private var ball:Sprite;
public function FirstAnimation() {
init();
}
private function init():void {
ball = new Sprite();
addChild(ball);
ball.graphics.beginFill(0xff0000);
ball.graphics.drawCircle(0, 0, 40);
ball.graphics.endFill();
ball.x = 20;
ball.y = stage.stageHeight / 2;
ball.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void {
ball.x ;
}
}
}
init 函數創建了一個名為 ball 的 Sprite 影片,并為其建立事件偵聽。 onEnterFrame 函數負責 ball 的運動及屏幕刷新工作。這是學習本書內容的基礎,也是使用 ActionScript 創建動畫的基礎,所以務必要掌握。
顯示列表
在 AS 3 之前,人們可以創建多個不同類型的可視化對象,包括影片剪輯,圖形,按鈕,文本框,位圖,組件和基本形狀。這些對象沒有真正的層次結構,它們的創建、刪除、操作方法也均不相同。比如,在 IDE 中,可以使用 attachMovie ,duplicateMovieClip 或 createEmptyMovieClip 的方法將影片剪輯放置于舞臺上,文本框可以在開發環境中創建也可以用代碼創建。而在使用位圖(bitmap),視頻(video)及組件(component)時,它們就像是來自于別的星球,最終被強硬地放在一起。
對于 AS 3 來說,這些對象都有了統一的歸屬。在舞臺上所有可見的對象都繼承自 DisplayObject 類。換句話講,這些對象都是一個大家庭的成員,并以相同的形式工作,使用同樣的方式進行創建,置入,刪除,操作。無論創建 Sprite 影片,影片剪輯或文本框的方法都非常相近,我們需要使用 new 關鍵字來完成,創建任意類型的對象。為了證明這一點,請看下面三條示例:
var myTextfield:TextField = new TextField();
var myMovieClip:MovieClip = new MovieClip();
var mySprite:Sprite = new Sprite();
如果我們創建的是一個影片剪輯或 Sprite 影片的話,就可以直接里面進行繪制,如:
mySprite.graphics.beginFill(0xff0000);
mySprite.graphics.drawCircle(0, 0, 40);
mySprite.graphics.endFill();
但只有這些代碼,還不能看到效果,這就引發了接下來要討論的顯示列表。“顯示列表”是個新名詞,可以理解為一顆由可視對象構成的樹。舞臺就是樹根,默認為可見的,在舞臺上,我們可以有很多影片剪輯或可視對象(文本框,圖形等),把它們加入舞臺后,也就成為可見的了。
這些影片中也許還嵌套著很多層的可視對象,這就是我們所謂的顯示列表。 AS 2 與 AS 3 顯示列表最大的不同在于,AS 2 中,當使用 attach 或 createEmptyMovieClip 方法創建影片剪輯時,必須指定它位于樹的哪個位置。這樣一來,影片剪輯要放置在列表的指定位置。當刪除該影片時,同樣也無法改變它在列表中的位置或在列表中移除它。
在 AS 3 中,創建了一些 Sprite 影片后,不會自動被加入顯示列表。在上面的示例中我們發現,創建一個 Sprite 后,并不涉及父級影片(parent)或深度(depth)的問題,這樣就可以在它沒有加入視覺列表之前就對其進行操作了。說到舞臺(Stage),可以把這些顯示對象看作是幕后的演員,雖然看不到,但確實存在,并時刻準備著亮相的一刻,我們使用 addChild 方法把對象加入顯示列表。將文檔類作為樹根,向里面加入孩子時,會自己被設置為可見的。
現在,在前面的例子中再加入創建 Sprite 對象以及 addChild 方法,如下:
var mySprite:Sprite = new Sprite();
mySprite.graphics.beginFill(0xff0000);
mySprite.graphics.drawCircle(0, 0, 40);
mySprite.graphics.endFill();
addChild(mySprite);
如果大家有興趣試一下這段代碼的話,請把它們寫入前面所給的類框架的 init 函數中。請注意,繪制出的圓默認位置是0,0點,可以改變其 x 和 y 屬性。還要注意,創建新影片時不再需要像 AS 2 那樣去設置深度(depth)。雖然深度管理為自動執行,但我們還有指定深度或改變深度的方法,這部分等將來用到時再講。
使用 removeChild 方法,從顯示列表中刪除一個對象,并以該對象的名字作為參數。第一,刪除一個對象,不是去毀滅它,對象依然保持原樣,只是暫時被移除,當再次被加入到顯示列表中,對象仍保持原來的狀態。換句話講,如果顯示對象里面繪制了圖形,或是已加載了一些外部信息,那么將它重新加入顯示列表后,就不必再去重繪或重載這些信息。第二,把該對象重新加入顯示列表后,還可以為它指定處在顯示列表中的位置,這就是我們所熟知的重定父級。
從一個影片剪輯中刪除一個對象,再把它加載到另一個影片中剪輯中,并保持剛剛被刪除時的狀態,在以前是不可能完成的。事實上,有時并不需要去刪除影片,因為,一個子對象只能有一個父級,把它加入到另一個父級中,就會自動從原來的父級中刪除。請看下面示例:
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
public class Reparenting extends Sprite {
private var parent1:Sprite;
private var parent2:Sprite;
private var ball:Sprite;
public function Reparenting() {
init();
}
private function init():void {
parent1 = new Sprite();
addChild(parent1);
parent1.graphics.lineStyle(1, 0);
parent1.graphics.drawRect(-50, -50, 100, 100);
parent1.x = 60;
parent1.y = 60;
parent2 = new Sprite();
addChild(parent2);
parent2.graphics.lineStyle(1, 0);
parent2.graphics.drawRect(-50, -50, 100, 100);
parent2.x = 170;
parent2.y = 60;
ball = new Sprite();
parent1.addChild(ball);
ball.graphics.beginFill(0xff0000);
ball.graphics.drawCircle(0, 0, 40);
ball.graphics.endFill();
ball.addEventListener(MouseEvent.CLICK, onBallClick);
}
public function onBallClick(event:MouseEvent):void {
parent2.addChild(ball);
}
}
}
該類中有三個 Sprite 對象:parent1, parent2, ball。 parent1, parent2 影片直接加入顯示列表,并在影片中繪制了正方形。 Ball 影片被加入到 parent1,就相當于加入了顯示列表并可見。當小球被點擊時,它將被加入 parent2 影片中。請注意,沒有改變 Ball 的 x,y 坐標的代碼,之所以產生移動是因為 Ball 被加載到了不同位置的 Sprite 影片中。 Sprite 影片被刪除后再被加入顯示列表,Ball 仍會出現。