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