幀循環(huán)
幀循環(huán)的理念,存在于 Flash 最早的版本中,那時 ActionScript 還不像今天那么強(qiáng)大。把代碼寫入關(guān)鍵幀,并在下一幀中寫入像 gotoAndPlay 這樣的語句,使播放頭(playhead)回到前一幀。這樣兩幀之間就形成了一個無限循環(huán),每當(dāng)播放頭到了代碼幀上時,就會執(zhí)行那些代碼。例如,在舞臺上有一個實例名為 ball 的影片剪輯。 第一幀的代碼就像這樣:
ball.x ++;
第二幀的代碼如下:
gotoAndPlay(1);
實際上第二幀不需要做任何事,只是讓時間軸自動回到第一幀而以。另一個版本是建立三個幀,第一幀進(jìn)行初始化,寫入只執(zhí)行一次的代碼,不進(jìn)行循環(huán)。第二幀才是主要的執(zhí)行代碼,第三幀只寫 gotoAndPlay(2); 這個方法在早期 Flash 版本中常被使用,雖然有點(diǎn)過時,但是同樣可以出色地完成任務(wù)。馬上我們還要學(xué)到更靈活更強(qiáng)大的設(shè)置方法,但今后你會發(fā)現(xiàn)其實原理上是一樣的。
影片事件
影片事件在 AS 3 中徹底的消失了,這真是件好事。但還要捎帶提一下,回顧 Flash 5 的時代,只有幀循環(huán)和影片剪輯事件兩種選擇。影片事件指代碼直接寫在影片剪輯上,而不是幀上。如何實現(xiàn)影片事件,首先選擇舞臺上的影片剪輯,然后打開動作面板并將代碼寫在上面,這些代碼只對該影片剪輯有效。所有代碼必需寫在事件塊中,比如:
onClipEvent(eventName){ // code goes here }
對于 onClipEvent(eventName),作用于 eventName(某種事件)。對于"on"類型事件則必需指定鼠標(biāo)或鍵盤事件,如按下(press)和釋放(release)。
事件名稱(eventName)是指許多Flash 影片事件之一,所謂事件就是在影片中發(fā)生的事。事件分為兩種:系統(tǒng)事件和用戶事件。系統(tǒng)事件指發(fā)生在如計算機(jī),F(xiàn)lash,或影片上的事件,比如調(diào)取數(shù)據(jù),調(diào)取信息,或播放幀等。用戶事件是指用戶所做的一些事,基本上就是鼠標(biāo)和鍵盤兩種。影片事件使用得最多的就是 load 和 enterFrame 這兩個。 Load 事件會在影片第一次出現(xiàn)在舞臺上時才執(zhí)行,且只執(zhí)行一次。所以說非常適合在這里面寫入初始化代碼。只要把代碼寫在大括號間即可:
onClipEvent(load){ // initialization code }
我們可以把帶有如下代碼的影片剪輯放入時間軸上(注意:此處為 AS 1 寫法):
onClipEvent (load) { this._x = 100; this._y = 100; } onClipEvent (enterFrame) { this._x += 5; }
本書示例中的代碼不使用這種寫法(因為它已經(jīng)不是一種語言了),但不論使用何種方法,初始化(initialization),重復(fù)動作(repeating actions)和屏幕刷新(screen refresh)都是非常重要的。
事件及事件處理
Flash MX 的 ActionScrpt 發(fā)生了重要的改變,這些轉(zhuǎn)變與革新為 Flash 成為真正的富客戶端程序(RIA)奠定了基礎(chǔ)。其中一個就是全新的事件結(jié)構(gòu),在編寫非常復(fù)雜的行為時比之前的版本好用很多。 Flash MX 之前的版本,只能把代碼放在影片和按鈕的 onClipEvent(eventName) 或 on(eventName) 這兩種事件處理方法中。這就意味著,在設(shè)計的時候就要把影片剪輯放到舞臺上,并把代碼寫入影片剪輯中。MX 的事件結(jié)構(gòu)并不完美,但與之前版本來說已經(jīng)有了長足的進(jìn)步,并允許我們在任何時候訪問任何事件,或是停止處理任何事件,或是動態(tài)改變某個事件的行為,可以想象這有多么的強(qiáng)大和靈活。
要想了解事件,就要明白下面幾條概念:偵聽器(lintener)與處理函數(shù)(handler),這兩個名字很貼切,偵聽器就是偵聽事件的對象,處理函數(shù)是一個用于處理所要發(fā)生的事件的函數(shù)。偵聽與處理在 ActionScript 的發(fā)展過程中進(jìn)行過很多次演變,在 AS 2 中就有很多不同的實現(xiàn)方法。為了避免混亂,我很推崇 AS 3,因為它簡化了這個過程,使事件處理變得更方便更一致。
事件偵聽器與處理函數(shù)
前面說過,偵聽器是一個用于偵聽事件的對象。我們可以設(shè)計一個類,通過調(diào)用addEventListener 函數(shù)為某事件指定一個偵聽器。輸入要偵聽的事件名稱以及要執(zhí)行處理的函數(shù)名稱?匆粋例子:
addEventListener("enterFrame", onEnterFrame);
在加入事件偵聽器時,可使用可選參數(shù),本書中不會用到;對于大多數(shù)的應(yīng)用程序來說,會使用以上這種寫法就夠用了。請注意事件名"enterFrame"為字符串型,戲稱它為“魔力字符串”(Magic String)。為什么這么叫?如果你誤輸入成了"entorFrame",盡管沒有這個事件名稱,編譯器也會編譯執(zhí)行它,會發(fā)現(xiàn)事件處理函數(shù)沒有執(zhí)行。但 AS 3 仍會對其進(jìn)行處理,除了使用“魔力字符串”以外,還可以使用事件類(Event Class)的屬性。例如:
addEventListener(Event.ENTER_FRAME, onEnterFrame);
實際上 Event.ENTER_FRAME 的值就是”enterFrame”這個字符串。那么這個屬性也可能輸錯就像 Event.ENTOR_FRAME ,但這種方法好在,如果輸入錯誤了,程序會拒絕編譯,并提示你在事件類中不存在該屬性。編譯器會提示發(fā)生錯誤的行及確切的字符。所以,最好使用這種方法,除非編譯器會幫我們修正錯誤或編寫代碼。 除此之外,還有其它的事件類型如:MouseEvent.MOUSE_DOWN,KeyboardEvent.KEY_DOWN,TimerEvent.TIMER 等。這些都由 "mouseDown" , "keyDown" , "timer" 這樣的簡單字符串來表示,如果你記不住這些字符串,那么最好就去使用事件類的屬性。
另一個重點(diǎn)是,使用 addEventListener 函數(shù)直接調(diào)用類中的函數(shù)。有時,需要偵聽另一個對象產(chǎn)生的事件,例如,有一個名為 mySpriteButton 的 Sprite 影片(Sprite):影片或按鈕,能完成按鈕的動作。當(dāng)用戶點(diǎn)擊它的時候就會產(chǎn)生 mouseDown(鼠標(biāo)按下)事件。偵聽該 Sprite 影片的 mouseDown 事件,就要調(diào)用該對象的 addEventListener 方法,如下:
mySpriteButton.addEventListener(MouseEvent.MOUSE_DOWN, onSpritePress);
最后一點(diǎn),必需要有事件處理函數(shù)如 onEnterFrame,在 AS 3 中,可以任意地為事件處理函數(shù)命名,這點(diǎn)與以前的 ActionScript 不同。在 enterFrame 示例中,使用 onEnterFrame 做事件處理函數(shù),是因為我們習(xí)慣使用這個名稱。在 AS 3 中,onEnterFrame 已不再是關(guān)鍵字,當(dāng)然也可以為這個處理函數(shù)命名為 move,run,或是 doSomethingCool。然而,我們已經(jīng)習(xí)慣使用”on”表示事件開始,后面跟一些描述詞如 onStartButtonClick,onConfigXMLLoad 或 onRoketCrash。有些朋友喜歡在事件名后面加上 "Handler" 作為后綴,如: enterFrameHandler,這只是個人偏好問題。
偵聽器用于偵聽事件,但對于一個偵聽器來說,也許會同時偵聽很多事件。在系統(tǒng)內(nèi)部,一個事件對象擁有一個包括了所有對象及自身的偵聽器的列表。如果一個對象能夠產(chǎn)生多種不同類型的事件,如 mouseDown,mouseUp,mouseMove 等,那么它就擁有一個偵聽器列表,其中包括它所涉及的所有類型的事件。無論觸發(fā)何種事件,都會檢索一遍列表,然后使列表中的每個對象都知道所發(fā)生的事件。 另一種對事件的描述是,將其看作一個加入到事件行列的偵聽器成員。產(chǎn)生事件的對象將它所產(chǎn)生的事件公布給所有成員,當(dāng)你不再需要這個對象進(jìn)行偵聽時,可以令其停止偵聽或使用 removeEventListener 方法解除該成員;就是告訴對象從偵聽器列表中刪除該偵聽器,這樣一來,他就不會再接收信息了。
讓我們看看這段代碼,下面是一段在舞臺中創(chuàng)建 Sprite 影片,并進(jìn)行繪圖,然后再為其添加偵聽器的代碼:
package { import flash.display.Sprite; import flash.events.MouseEvent; public class EventDemo extends Sprite { private var eventSprite:Sprite; public function EventDemo() { init(); } private function init():void { eventSprite = new Sprite(); addChild(eventSprite); eventSprite.graphics.beginFill(0xff0000); eventSprite.graphics.drawCircle(0, 0, 100); eventSprite.graphics.endFill(); eventSprite.x = stage.stageWidth / 2; eventSprite.y = stage.stageHeight / 2; eventSprite.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown); eventSprite.addEventListener(MouseEvent.MOUSE_UP,onMouseUp); } private function onMouseDown(event:MouseEvent):void { trace("mouse down"); } private function onMouseUp(event:MouseEvent):void { trace("mouse up"); } } }
在初始化函數(shù)(init)中創(chuàng)建一個 Sprite 影片,并在里面畫圓,置于舞臺中心,最后兩句是為它添加兩個偵聽器,偵聽鼠標(biāo)按下(MOUSE_DOWN)和鼠標(biāo)彈起(MOUSE_UP)這兩個事件。它們是MouseEvent 類的兩個屬性,而這個類必需要導(dǎo)入。最后定義兩個處理函數(shù) onMouseDown 和 onMouseUp。
由事件對象調(diào)用事件處理函數(shù),通常還會包括一些事件信息。在處理鼠標(biāo)事件時,就包括觸發(fā)該事件時鼠標(biāo)位置的信息如:鼠標(biāo)點(diǎn)擊在按鈕上。對于鍵盤事件,就要包括按下鍵時的信息如 Ctrl,Alt,Shift等。把上述示例保存為 EventDemo.as 文件,并選擇一種前面講過的編譯方式。當(dāng)運(yùn)行 SWF 時,就會看到每次點(diǎn)擊或圖形時,都會輸出 pressed 或 released。
出處:藍(lán)色理想
責(zé)任編輯:bluehearts
上一頁 ActionScript 3.0 動畫基礎(chǔ) [3] 下一頁 ActionScript 3.0 動畫基礎(chǔ) [5]
◎進(jìn)入論壇RIA設(shè)計與應(yīng)用版塊參加討論
|