又複習Lingo中關於Script的各種概念。
Behavior:"Behavior是一組Handler的集合"。
Handler:"是處理Event的方法/函數"。
Event:"系統或使用者定義的特定情況。"嗯,沒錯,這裡的Event確實分為system和user-defined兩類。就system而言,又分成兩類,一類是會自動發生的,一類是需要人為觸發的(mouseUp..)。這個區分沒多大意思,這麼分只是為了下面的"自動發生的system Event的執行順序"。
自動發生的System Event的順序
movie開始幀:prepareMovie à beginSprite(開始幀的) à prepareFrame à startMovie
註:director11.5 的script dictionary文檔中,這裡beginSprite和prepareFrame的順序弄反了。
中間幀內:beginSprite(本幀) à stepFrame àprepareFrame à enterFrame à exitFrame à endSprite(本幀)
註:stepFrame是parent script的system event。寫在frame behavior中的on stepFrame是沒有用的。
movie結束幀:endSprite(結束幀的) à stopMovie
而也是一個錯誤(或過時)的圖示。幀內的事件,xxxFrame這樣的都是位於beginSprite和endSprite之間。
Handler如何能得知Event
如果Handler有手機那Director可以在Event發生是打電話給它。但它沒有,所以Director就發Message給Handler。
Message:Event發生時Director通知Handler的通訊方式。
問題來了,如果Handler很多呢?譬如,一個按鈕,它的cast script有翻轉效果,mouseUp背影色會變;它的sprite的按一下滑鼠會停止播放;同時該幀上單擊事件發生時會重新整理螢幕某個位置的一個顯示幀數的數字;再同時整個movie會記錄整部影片中按一下滑鼠了多少次。以上四個功能分別對應的指令碼是:
cast member script: 按鈕翻轉效果
sprite behavior: stop功能
frame behavior: 返回 frameNum
movie script: 重新整理clickNum
(為了把四種指令碼弄出來,這個例子必須彆扭。)
當這個按鈕被單擊時,以上四種指令碼中的mouseUp Event的Handler接收到mouseUp Message的順序是:(廣告後馬上回來..)
Director向不同指令碼中的Handler發Message的順序
sprite behavior à cast member script à frame behavior à movie script
嗯,想必馬上就注意到了,像sprite behavior這樣的,一個sprite會有很多behavior,對它們的順序又是怎樣的?
答案很有邏輯,就是按照添加的順序。也就是behavior在sprite(num).scriptInstanceList中的順序。
為啥movie script的mouseUp就是不響應?
在前述4類Handler之前還有一個類似預設Handler的東東,形如on mouseUpScript,它和上邊四類的Handler的有點不一樣,它在執行完自己之後,會繼續依次向後轉寄訊息,當然也可以關閉,dontPassEvent。而上述4類的Event Handler,必須手動在最末添加pass()。譬如sprite 的on mouseUP最後如果不寫上pass()語句,那麼在處理結束之後,這個Event就算到底為止了。
因此,在各層級的Handler尤其是system event handler,尤其要確認到底要不要pass()。
回頭再看Handler
Handler是響應Event的代碼,事件處理器 Event Handler,就是個函數。
這個函數當然是寫在一個script中,但這個script的類型和_________就有點意思了。
空白處一會兒再來補充。(script附著的對象)
再複習script的類型
director中script有兩種,lingo和javascript。——不是這個意思!
director中script有三種:behavior,movie和parent。——對了,就是這個意思。
這三種也就是建立一個script時,在它的property Inspector視窗中看到的3個可選Type。
(友情放送捷徑:script window Ctrl+0零,property Inspector Ctrl+Alt+S;)
(再友情放送當前movie屬性的捷徑Ctrl+Shift+D,這個捷徑其實也是開啟property Inspector,只是馬上定位到movie標籤。)
這三種類型比較明顯的區別就是,behavior可以附著(拖到score中)在Frame/Sprite上,而movie和parent不能。
另外behavior和parent有me的概念,即是說他們的存在方式就是1.behavior的附著;2.parent的child化。
movie這類script就相當於當前項目中全域可以訪問的地區,除了全域的System Event Handler寫在這裡,也可以寫一些全域訪問的函數在此。它雖然也是一個單獨的script member的形式,但它的存在更像c++中的只有static方法的abstract,沒有me一說。
接著Handler,根據需要把函數放在不同類型和附著於不同位置的script中。
關於如何建立和使用某類型的script,俺還是想把你和N天后的俺都當成純智障來解釋一下。它是這樣的(廣告後馬上回來…)
如何建立script
建立script的方式很多,你可以:
sprite右鍵選擇script
這時script window會topset並且自動建立一個已經attach到sprite的behavior。
單擊發生的事情包括:1建立了一個script member,類型是behavior;2這個behavior已經attach到sprite,也就是在sprite的scriptInstanceList中你能找到了。
雙擊script channel的某一幀
這是在script window中自動建立的仍然是一個behavior,但它attach到的是Frame,是一個frame behavior。
在behavior script中,都有me。這個必須有。
在script window中點+
此時建立script的Type貌似是用上一次的script的Type。
如果想建立的是一個movie,那麼property window中保證Type對了以後就可以直接type script。
如果想建立的是behavior,那除了以上操作,在敲完鍵盤以後,你還得讓它attach到frame或prite上。attach的方式也有很多,GUI的方式就有:1,拖動script member到score;2,拖動script member 到stage;3,選中sprite或frame在behavior inspector中點+添加。(behavior inspector 快速鍵Ctrl+Alt+;)
如果想建立的parent,跟movie一樣。只是使用時,必須要new出一個child才行。
cast member右鍵選擇 cast member script
這種比較奇怪,你甚至在property inspector中看不到它到底是什麼Type。同時也只有這種script,它不會在cast中添加一個新的script member。
這兩點邏輯上很一致,但總讓然感覺不和諧的地方是,cast member script明明是script,卻沒有被納入script member麾下。
其他方面,比如它內部的handler如何處理Event,前面已經提過,Director還是拿它和其他的script一起系統管理的。
還有一點要注意,一個cast member有script,並不代表師從它的sprite一定會執行。需要在behavior inspector中手動添加,仍然是按那個+。(behavior inspector 快速鍵Ctrl+Alt+;)
另外,別忘記向後轉寄Event Message的命令pass()。