国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
flahs as 無(wú)基礎(chǔ)入門(mén)經(jīng)典教程
flahs as 無(wú)基礎(chǔ)入門(mén)經(jīng)典教程
 
做過(guò)Flash動(dòng)畫(huà)的Flash愛(ài)好者們都知道,要做好一個(gè)Flash動(dòng)畫(huà),AS是必不可少的,即使只是很簡(jiǎn)單的幾句代碼也能起到整個(gè)Flash畫(huà)龍點(diǎn)睛的作用。這里我只簡(jiǎn)單的介紹一下AS的基本常識(shí)。
首先我們要了解AS要寫(xiě)在什么地方,什么時(shí)候AS會(huì)被觸發(fā)執(zhí)行。
1、幀:
寫(xiě)在關(guān)鍵幀上面的AS,當(dāng)時(shí)間軸上的指針走到這個(gè)關(guān)鍵幀的時(shí)候,就寫(xiě)在這個(gè)幀上面的AS就被觸發(fā)執(zhí)行了。常見(jiàn)的例子有在影片結(jié)尾的幀寫(xiě)上 stop() 等。操作方法就是點(diǎn)選關(guān)鍵幀,然后打開(kāi)AS面板。
2、按鈕:
不同于幀上面的AS,按鈕上面的AS是要有觸發(fā)條件的。要把AS寫(xiě)在按鈕上,操作方法是點(diǎn)選目標(biāo)按鈕,然后打開(kāi)AS面板。舉個(gè)例子能說(shuō)的更明白。
假設(shè)有一個(gè)動(dòng)畫(huà),要讓它在播放完同時(shí)停止,那么,你要做的就是在這個(gè)動(dòng)畫(huà)的最后一幀寫(xiě)AS
stop();
再假設(shè)有個(gè)按鈕,效果是按下按鈕后停止播放,那么步驟如下。
做一個(gè)按鈕,放到主場(chǎng)景,點(diǎn)選按鈕,然后打開(kāi)AS面板?,F(xiàn)在如果也在按鈕上寫(xiě)
stop();
那么,輸出的時(shí)候就會(huì)提示錯(cuò)誤。正確的應(yīng)該這樣寫(xiě)
on(release){
stop();
}
這里要比幀的動(dòng)畫(huà)多這些代碼: on(release){} , 整個(gè)代碼翻譯過(guò)來(lái)就是:
當(dāng)(松開(kāi)){
停止
}
紅色的代碼表示鼠標(biāo)的觸發(fā)事件事件之一,這里用的是 release 松開(kāi),按鈕的常用事件:
release 松開(kāi)
releaseOutside 在按鈕外面松開(kāi)
press 按下
rollOver 鼠標(biāo)進(jìn)入按鈕的感應(yīng)區(qū)
rollOut 鼠標(biāo)離開(kāi)按鈕的感應(yīng)區(qū)
現(xiàn)在很明確了:寫(xiě)在按鈕上面的AS一定就是這種格式的:
on(事件){要執(zhí)行的代碼}
3、MC(電影剪輯)
如果你看懂了上面的內(nèi)容,那么寫(xiě)在MC上面的AS和寫(xiě)在按鈕上的大同小異。操作方法就是點(diǎn)選MC,然后打開(kāi)AS面板。看個(gè)例子
onClipEvent(load){
stop();
}
同樣,MC需要一個(gè)事件來(lái)觸發(fā)AS的執(zhí)行。翻譯這段代碼就是
當(dāng)剪輯(載入){
停止
}
紅色代碼同樣表示一個(gè)事件。MC的事件有下面這些:
load 載入,當(dāng)MC出現(xiàn)的時(shí)候執(zhí)行。也就是除非卸載這個(gè)MC,否則load事件內(nèi)的代碼只執(zhí)行一次
unload 卸載,當(dāng)MC卸載的時(shí)候執(zhí)行
enterFrame 存在的每個(gè)幀。在MC存在的每個(gè)幀都要執(zhí)行一次代碼。如果你的場(chǎng)景有100個(gè)幀,有個(gè)MC從41幀開(kāi)始出現(xiàn)到100幀才消失,那么這個(gè)MC上面的代碼執(zhí)行了60次
mouseDown 按下鼠標(biāo),在場(chǎng)景內(nèi)任何地方都算。和按鈕不一樣的地方
mouseMove 移動(dòng)鼠標(biāo),只要移動(dòng)鼠標(biāo)就執(zhí)行代碼
mouseUp 松開(kāi)鼠標(biāo)
同樣你要明確:寫(xiě)在MC上的代碼一定總是這種格式:
onClipEvent(事件){代碼}
看到這里,如果你明白的寫(xiě)在 幀、按鈕、MC上的代碼有什么不一樣,任務(wù)就算完成了

AS 對(duì)象篇
重點(diǎn) :點(diǎn)語(yǔ)法學(xué)會(huì)表達(dá)對(duì)象
學(xué)會(huì)用絕對(duì)路徑和相對(duì)路徑表達(dá)對(duì)象
雖然AS不是真正的面向?qū)ο蟮木幊蹋撬灿袑?duì)象的概念。這個(gè)概念貫穿整個(gè)AS的始終,所以,對(duì)對(duì)象的理解,比對(duì)語(yǔ)法或者其他的理解更為重要?,F(xiàn)在開(kāi)始吧:
首先,我們來(lái)了解一下路徑,路徑分兩種:絕對(duì)路徑和相對(duì)路徑。做過(guò)html的朋友應(yīng)該知道這個(gè)概念。但這里我還是要詳細(xì)解釋一下,我認(rèn)為對(duì)路徑的理解要深入,我初學(xué)的時(shí)候就是磕在路徑上。
在講路徑之前,有必要先講一下 .語(yǔ)法 : 舉例說(shuō)明,這里要表示房間里的桌子上的一本
書(shū),用 .語(yǔ)法這么表示:
房間.桌子.書(shū)
如果要再細(xì)到書(shū)上的頁(yè)上面的字,很顯然
房間.桌子.書(shū).頁(yè)面.字
看明白了吧?我也不懂得怎么說(shuō), .語(yǔ)法就是這樣表示對(duì)象的,點(diǎn)的前面是其后面的父級(jí)。如房間是桌子的父級(jí),桌子的子級(jí)就是書(shū)。
還是不明白?這樣吧,你把 . 里寫(xiě)成“里面的”就可以了,這樣就是
房間(里面的)桌子(里面的)書(shū)(里面的)頁(yè)面(里面的)字
這樣容易多了吧?
現(xiàn)在我開(kāi)始說(shuō)路徑了,其中也要夾雜的對(duì)象的說(shuō)明,看:
從例子入手。新建一個(gè)Flash文件,然后創(chuàng)建一個(gè)MovieClip,MC命名為“MC”,放在主場(chǎng)景里面,然后再創(chuàng)建一個(gè)按鈕,放在“MC”里面,然后從庫(kù)里面拖一個(gè)出來(lái)放在主場(chǎng)景,分別給這兩個(gè)元素實(shí)例命名(Instance Name , 注意是實(shí)例名不是MC的名字):MC->myMC button->myBtn
現(xiàn)在我們假設(shè)主場(chǎng)景是房子,MC是桌子,按鈕是書(shū),那么分別怎么表達(dá)房子,桌子,書(shū)呢?如下
_root 房子
_root.myMc 房子.桌子
_root.myMc.myBtn 房子.桌子.書(shū)
這里的 _root 是Flash的關(guān)鍵字,表示主場(chǎng)景的 Timeline (時(shí)間線)。
很容易理解對(duì)不。這里的 房子,桌子,書(shū) 都是我們要理解的“對(duì)象”。
當(dāng)你找到這個(gè)對(duì)象后,才能對(duì)對(duì)象進(jìn)行操作,才能給對(duì)象施加方法。比如,我現(xiàn)在要打掃房子,打掃是方法,但對(duì)象是房子,表達(dá)式是這樣 :
房子.打掃()
如果你不能正確的表達(dá)房子這個(gè)對(duì)象,你的打掃也就不能正確的實(shí)施了。
*說(shuō)明:這里為什么要在打掃后面加()呢?因?yàn)榇驋呤欠椒ú皇菍?duì)象,為了讓Flash知道這是個(gè)方法,我們必須加上(),要不然它會(huì)以為房子里面有“打掃”這個(gè)東西。
現(xiàn)在,我們可以很容易的對(duì)房間里面的各個(gè)東西進(jìn)行操作,如
房子.打掃();
房子.木桌子.整理();
房子.玻璃桌子.打碎();
房子.書(shū)桌.書(shū).看();
等等,相信你把它們"翻譯"成AS代碼沒(méi)什么問(wèn)題吧

比如要主場(chǎng)景停止播放,就是
_root.stop();
要MC停止播放,就是
_root.myMc.stop();
現(xiàn)在說(shuō)說(shuō)相對(duì)路徑。還是上面的例子。假如給你下了一個(gè)命令:修理房子里面的紅色的椅子。那么怎么表達(dá)呢?就是:
房子.紅色椅子.修理()
無(wú)論給你下命令的人在哪里告訴你的,你都會(huì)知道要修理的椅子是哪一張。但是他如果這么說(shuō):修理你現(xiàn)在坐的這張椅子。紅色的?還是藍(lán)色的?這就要取決于你坐在哪個(gè)椅子上了。那么相對(duì)的表達(dá)式就是
我坐的椅子.修理();
這里為什么不這么寫(xiě)呢:
房子.我坐的椅子.修理()
這么寫(xiě)是錯(cuò)的,因?yàn)槲易囊巫邮遣还潭ǖ?,我說(shuō)不定把椅子搬到房子外面去坐,那這個(gè)表達(dá)式就錯(cuò)了,因?yàn)橐巫痈揪筒辉诜孔永锩妗?br>換過(guò)來(lái)用Flash實(shí)例說(shuō)明?,F(xiàn)在我想讓主場(chǎng)景下的 myMC 在一開(kāi)始就不要播放,而是先停止。那么你有什么辦法呢?
我你猜想到的辦法可能就是在主場(chǎng)景放入這個(gè)MC的那個(gè)幀寫(xiě)上:
_root.myMc.stop();
這個(gè)是對(duì)的。但是一旦 myMc 的名字一變,你就得跟著改這句話(huà)了。
有沒(méi)有辦法不管這個(gè)“MC”的實(shí)例名不管怎么改,都會(huì)被我們同樣一句的AS找到?當(dāng)然可以,前提是你的AS必須“坐在這個(gè)MC上”。
進(jìn)入Mc的編輯狀態(tài) , 在 Mc 的 Timeline 的第一幀寫(xiě)上
this.stop();
這里的this也是Flash的關(guān)鍵字 , 這個(gè) this 指AS所在的這條 Timeline .
現(xiàn)在不管你這個(gè)MC放在哪里,命名是什么,我都不管,反正肯定會(huì)停下來(lái)。為什么,因?yàn)锳S正“坐在MC上”。
如果你在這里寫(xiě)上
_root.stop();
那就錯(cuò)了。為什么?仔細(xì)想想。
這個(gè) this 就是相對(duì)路徑的關(guān)鍵字之一。你必須要仔細(xì)理解它。
另外的一個(gè)關(guān)鍵字就是 _parent 。如果你理解了 this , 那么 _parent 并不難理解。舉例:
還是哪個(gè)假設(shè) 房子(_root) , 桌子( mc_zhuozi ) , 書(shū) (mc_shu) 他們的關(guān)系是(括號(hào)內(nèi)為mc實(shí)例名)
房子.桌子.書(shū)
_root.mc_zhuozi.mc_shu
在 mc_zhuozi 的 timeline 里面寫(xiě)
_parent.打掃();
意思就是打掃房間;
在 mc_shu 的 timeline 里面寫(xiě)
_parent.打掃();
意思就是打掃桌子。
_parent 也就是父級(jí)。桌子的 _parent 就是房子的 timeline , 書(shū)的 _parent 也就是 桌子的 timeline。點(diǎn)的后面的對(duì)象 的 _parent 就是點(diǎn)前面的對(duì)象。

AS 語(yǔ)法篇
首先要讓大家明白的是:AS 語(yǔ)法的大小寫(xiě)是敏感的。
如: gotoAndPlay() 正確 gotoAndplay() 錯(cuò)誤 。
關(guān)鍵字的拼寫(xiě)必須和語(yǔ)法一致,要做到很容易,因?yàn)樵贔lash的AS面板里面,關(guān)鍵字會(huì)有不一樣的顏色顯示。
很多Flash小鳥(niǎo)們也許要開(kāi)始埋怨,記不住咋辦?我這里有個(gè)辦法,就是背。不要流下委屈的淚水,俺們都是這么走過(guò)來(lái)的。多用兩次你就記住了。
這里說(shuō)一下,我們要從開(kāi)始就養(yǎng)成編程的好習(xí)慣,如在每個(gè)語(yǔ)句后面都加上分號(hào),有可能的話(huà),盡量給復(fù)雜的語(yǔ)句加上注釋。注釋的例子
//這個(gè)是注釋?zhuān)侵荒苡幸恍?br>/* 這個(gè)也是注釋?zhuān)梢詫?xiě)很多行 */
接下來(lái),介紹幾個(gè)類(lèi)型的語(yǔ)法。
1、幾個(gè)常用的控制場(chǎng)景的方法,如
play(); //讓時(shí)間軸的指針播放
stop(); //停止時(shí)間軸的指針在程序觸發(fā)時(shí)候的那個(gè)幀
gotoAndPlay(); //讓指針跳轉(zhuǎn)到某個(gè)幀,然后繼續(xù)播放
gotoAndStop(); //讓指針跳轉(zhuǎn)到某個(gè)幀,停止在那個(gè)幀
nextFrame(); //往下走一幀
prevFrame(); //往前走一幀
上面的都是方法。
方法?解:打個(gè)比方,我們管吃飯叫作一種方法,用來(lái)解決肚子餓這個(gè)問(wèn)題。我們管stop()叫做一種方法,用來(lái)解決時(shí)間軸指針停下來(lái)的問(wèn)題。我們管上面的幾個(gè)東西叫方法,用來(lái)解決時(shí)間軸指針運(yùn)動(dòng)的問(wèn)題。
2、控制屬性的語(yǔ)法。有很多,我列幾個(gè)
_x
_y
_alpha
_width
_name
.....等等屬性
上面的都是屬性
屬性?解:打個(gè)比方。我們管你的身高叫做屬性,用來(lái)標(biāo)識(shí)你的高度。我們管你的體重叫屬性,用來(lái)標(biāo)識(shí)你的質(zhì)量。我們管 _x 叫屬性,用來(lái)標(biāo)識(shí)目標(biāo)的X軸坐標(biāo)。我們管_alpha叫屬性,用來(lái)標(biāo)識(shí)目標(biāo)的透明度.......我真羅嗦啊,唉。
3、控制語(yǔ)句流程的語(yǔ)法,如
if (條件){
//條件滿(mǎn)足執(zhí)行這里的代碼
}else{
//條件不滿(mǎn)足執(zhí)行這里的代碼
}
for(i=0;i<N;i++){
//執(zhí)行這里的代碼N次
}
while(條件){
//當(dāng)條件滿(mǎn)足時(shí)一直執(zhí)行這里的代碼
}
等等。這些都是基本的語(yǔ)法,也是AS的基礎(chǔ)。
4、其他方法和自己定義的方法。
這里我不能把所有的語(yǔ)法都一一列出來(lái)介紹,因?yàn)閷?shí)在是太多了,具體可以參考Flash自帶的幫助手冊(cè)。我們只能在以后的應(yīng)用中慢慢熟悉。這里,你有個(gè)基本概念就行了。到后面我會(huì)給每句話(huà)都加上注釋。
回顧一下,今次要大家記住的東西:
AS 語(yǔ)法的大小寫(xiě)是敏感的。
方法的概念。
屬性的概念。

[轉(zhuǎn)帖]AS基礎(chǔ)精典教程
作者和出處俱不詳,版權(quán)歸原作者所有
次給大家?guī)?lái)MOOCK在世界性FLASH大會(huì):FF2K1大會(huì)上的演說(shuō),要說(shuō)到Action的權(quán)威,當(dāng)然要數(shù)MOOCK,他寫(xiě)的ASDG(一本書(shū))是可以和FLASH自帶的AS字典相提并論的寶貝。雖然他是這樣一個(gè)高高手,但是他的這個(gè)演講卻是非常的淺顯,如果你某處讀起來(lái)覺(jué)得難,那也一定是chocobo翻譯得不好。(有些地方實(shí)在是太淺,我受不了就改了 )
這篇文章預(yù)算的演講時(shí)間很長(zhǎng),所以讀起來(lái)也會(huì)覺(jué)得較長(zhǎng),你可以分開(kāi)來(lái)讀。
還有,本文是關(guān)于FLASH5的AS的,畢竟FLASH4的AS已經(jīng)淘汰。
第一章:由O開(kāi)始
為了示范,MOOCK將會(huì)做一個(gè)多選題問(wèn)答的動(dòng)畫(huà)來(lái)做為例子。
這個(gè)例子以4種不同版本的方法來(lái)實(shí)現(xiàn)。
對(duì)于用戶(hù)來(lái)說(shuō),4種版本使用起來(lái)將沒(méi)有區(qū)別,只是對(duì)于我們開(kāi)發(fā)者來(lái)說(shuō),研究的就是如何改進(jìn)這些FLASH代碼的結(jié)構(gòu)與組織。
改進(jìn)的重點(diǎn)在于:
*更便易的維護(hù)
*更便易的擴(kuò)展
*更快捷的建設(shè)
要牢記的是,學(xué)習(xí)編程是一個(gè)過(guò)程(process)而不是一個(gè)事件(event)。
如果你第一次學(xué)習(xí)到的時(shí)候不能照著完成也不必?fù)?dān)心。
接下來(lái),MOOCK說(shuō)到為了照顧沒(méi)有多少編程經(jīng)驗(yàn)的菜鳥(niǎo),會(huì)由最最最簡(jiǎn)單的開(kāi)始。
關(guān)于計(jì)算機(jī)語(yǔ)言:
編程語(yǔ)言是用來(lái)發(fā)信息給電腦,從電腦接受信息的
編程語(yǔ)言也有詞匯表和文法,如人類(lèi)的語(yǔ)言類(lèi)似
通過(guò)編程語(yǔ)言我們可以告訴電腦去做什么,也可以從他那獲得信息
關(guān)于語(yǔ)法和邏輯
學(xué)習(xí)編程的思想比學(xué)習(xí)一種語(yǔ)言的語(yǔ)法重要
假設(shè)FLASH是懂我們語(yǔ)言的單詞的,我們對(duì)FLASH說(shuō):“Flash, 讓一個(gè)球在屏幕里面彈來(lái)彈去吧”
FLASH會(huì)什么都做不了,F(xiàn)LASH要我們用他的世界懂的東西,例如:movie clips, buttons, frames,來(lái)描述它要做的事
那我們?cè)僬f(shuō)一次:“Flash, 讓一個(gè)名字叫ball_one的movie clip在屏幕里面彈來(lái)彈去吧”
我們已經(jīng)用MC這個(gè)FLASH懂的東西來(lái)描述了,但FLASH還是什么都不做,因?yàn)樗枰嗟男畔ⅲ?br>*這個(gè)球有多大
*它放在哪里?
*一開(kāi)始它首先往哪個(gè)方向運(yùn)動(dòng)?
*它初始的速度是多少
*它在屏幕的那一個(gè)范圍之內(nèi)彈來(lái)彈去呢?
*彈來(lái)彈去要持續(xù)多久呢?
看來(lái)我們需要有邏輯結(jié)構(gòu)地告訴FLASH它應(yīng)該怎么去做
1、一個(gè)球指的是一個(gè)叫ball_one的圓形MC,直徑50像素
2、還有一個(gè)方形MC叫square,邊長(zhǎng)300像素
3、將ball_one放在square上某處
4、以一個(gè)隨機(jī)的角度,75像素每秒的速度開(kāi)始移動(dòng)ball_one
5、如果ball_one接觸到square的某邊,就彈回
6、一直不停地運(yùn)動(dòng)下去,知道我們讓它停
如果FLASH真的懂我們語(yǔ)言的單詞,他應(yīng)該知道如何開(kāi)始做了
總結(jié)一下關(guān)鍵點(diǎn):
無(wú)論是使用什么語(yǔ)言,編程思想的藝術(shù)都在于用如何將邏輯步驟列出
在你開(kāi)始將要做的事用計(jì)算機(jī)語(yǔ)言描述之前,用我們?nèi)祟?lèi)的語(yǔ)言描述一次會(huì)很有幫助
即使你將他們翻譯成任何的計(jì)算機(jī)語(yǔ)言,他們的邏輯步驟應(yīng)該是一樣的
電腦不懂用假設(shè)完成去你的想法,他們沒(méi)有思考能力(chocobo:就是你要把要求完全無(wú)遺漏地寫(xiě)出來(lái)讓它運(yùn)行)

第二章:基礎(chǔ)
首先了解如何在FLASH輸入程序
在FLASH菜單Window里面Actions可打開(kāi)ACTION面板,ACTION面板分右面的腳本窗,和左面的工具窗
腳本窗就是放腳本的地方,而工具窗用于快速地輸入各種ACTION,運(yùn)算符,函數(shù),屬性,對(duì)象
MOOCK建議大家使用專(zhuān)家模式,在FLASH菜單的Edit的Preferences的Actions panel里面選Expert Mode,以后每次打開(kāi)ACTION面板都會(huì)自動(dòng)設(shè)置為專(zhuān)家模式(專(zhuān)家模式可直接輸入代碼,初學(xué)者學(xué)下去就會(huì)知道,很多代碼無(wú)法在普通模式里輸入)
AS的一些概念
所有代碼都需存于某個(gè)地方,可以是frame(幀), button(按鈕), or movie clip(電影夾子)。
只要你選擇了某按鈕或MC,你之后輸入的代碼就存放在它的上面了,注意此時(shí)ACTION面板上方提示為Object Actions。同理你也可以將代碼存放于幀,不過(guò)此時(shí)提示為Frame Actions。
當(dāng)你在專(zhuān)家模式的時(shí)候仍無(wú)法輸入代碼,你首先要檢查你是否選擇了frame, button, 或MC來(lái)存放代碼。
然后我們象學(xué)所有語(yǔ)言一樣吧,來(lái)個(gè)HELLO WORLD吧
在ACTION面板輸入
var message = "HELLO WORLD";
trace (message);
然后我們按CTRL和ENTER鍵,看到結(jié)果了嗎?
以下兩章比較基礎(chǔ)。MOOCK是騙演講費(fèi)嗎?
第三章:解讀
第一行代碼:var message = "HELLO WORLD";
告訴FLASH記住一個(gè)名字叫message的容器(通常在計(jì)算機(jī)里稱(chēng)為變量(variable),在FLASH里面,變量可以裝文字,和可以裝數(shù)字)里面裝了這樣的數(shù)據(jù)(datum),內(nèi)容為:"HELLO WORLD"
“=”等號(hào)是一個(gè)常用的運(yùn)算符號(hào)(operators),在FLASH里面它不是代表相等,而是代表賦值
var 命令的含義是宣布給整個(gè)電影,此變量的內(nèi)容是什么。
第二行代碼:trace (message);
就是要FLASH顯示message里面的內(nèi)容,為什么FLASH能輸出內(nèi)容呢,因?yàn)楫?dāng)你按CTRL+ENTER又或者在網(wǎng)上打開(kāi)這個(gè)電影的時(shí)候,你輸入的每一段Action Scrpit代碼,都會(huì)通過(guò)FLASH的解釋器(interpreter)來(lái)解讀然后執(zhí)行
如果解釋器能解釋你的代碼,他會(huì)運(yùn)行它,并返回你要返回的結(jié)果,如果解釋器看不懂你的代碼,他也會(huì)返回錯(cuò)誤代碼——告訴你錯(cuò)誤的原因
通常,我們發(fā)給解釋器的命令不只命令這么簡(jiǎn)單,還包括命令的內(nèi)容例如trace (message); 這個(gè)trace輸出命令的內(nèi)容就是message,計(jì)算機(jī)里就稱(chēng)為參數(shù)(argument或parameter),如果一個(gè)命令支持多個(gè)參數(shù),參數(shù)之間一般用“,”來(lái)分割
第四章 還有一些概念
表達(dá)式(expression):(2 + 3) * (4 / 2.5) - 1可稱(chēng)為一個(gè)表達(dá)式,"a"+"b"也是表達(dá)式,需要解釋器運(yùn)算才得到結(jié)果的值,一個(gè)相反的概念,不需要運(yùn)算的直接引用的,稱(chēng)為literal
條件(conditionals):(look at a series of options and make a decision about what to do based on the circumstances)
不翻譯了,大概意思就是美女穿著新衣上街,會(huì)先看看外面會(huì)否下雨,這就叫條件判斷啦
if(天氣=="下雨"){trace("還是帶把雨傘吧")}
循環(huán)(loop):如果要輸出5個(gè)數(shù)字,你是寫(xiě)5遍trace命令嗎?更多的就不行了吧
你可以用while和for命令來(lái)完成重復(fù)的動(dòng)作
事件(events):放在frame里面的代碼只要電影播放到就會(huì)執(zhí)行,放在MC、button的代碼則只在解釋器發(fā)現(xiàn)預(yù)先設(shè)置好的事件被觸動(dòng)的時(shí)候執(zhí)行。最典型的就是一下鼠標(biāo)點(diǎn)擊按鈕造成press時(shí)間啦。
函數(shù)(functions):將一組程序打包成一句命令來(lái)調(diào)用他,其實(shí)FLASH里面的很多命令就是函數(shù):trace、play、gotoAndStop等等都是。
第五章 開(kāi)始第一個(gè)版本的選擇題的制作
多選題共有兩道
如圖,大家應(yīng)該養(yǎng)成一個(gè)好習(xí)慣,用一個(gè)獨(dú)立的層來(lái)放置代碼,并把該層放到最上面會(huì)更便于修改。
第二層則獨(dú)立放置Label。不要覺(jué)得麻煩,只要你想到世界上大部分好的閃客都是如此做的,你就不會(huì)嫌麻煩了。
以下的層放的是選擇題的內(nèi)容,如上圖
開(kāi)始創(chuàng)建題目
在question 1層的第一幀,寫(xiě)上題目"When were movie clips introduced into Flash?" (什么時(shí)候FLASH開(kāi)始引入電影夾子的概念?)
再寫(xiě)上三個(gè)選項(xiàng):Version 1, Version 2, Version 3
跟著我們?cè)僮鲆粋€(gè)用來(lái)選擇的方框按鈕,從Library里面拖出這樣的三個(gè)按鈕,分別放到各個(gè)選項(xiàng)的前面。
第二題的創(chuàng)建我們用第一題來(lái)做個(gè)模版,選擇question 1層的第一幀,選擇菜單上的Edit>>Copy Frames
再選擇question 2的第十幀,Edit>>Paste Frames 將第一題復(fù)制過(guò)來(lái)了
當(dāng)然問(wèn)題要改成"When was MP3 audio support added to Flash?" (什么時(shí)候FLASH開(kāi)始支持MP3格式導(dǎo)入?),答案也要改成Version 3, Version 4, Version 5
數(shù)據(jù)初試化
雖然是個(gè)很簡(jiǎn)單的FLASH,但是象其他復(fù)雜的FLASH一樣,先告訴FLASH要用到的數(shù)據(jù),例如題目的答案等,這是個(gè)好習(xí)慣,越復(fù)雜的FLASH,受惠越多
正常來(lái)說(shuō)定義數(shù)據(jù)應(yīng)該LOADING結(jié)束之后的。
為了把題目定在第一題,ACTION還需要一句stop();
選擇第一幀,在ACTION面板里面輸入代碼
// init main timeline variables
var q1answer; // user‘s answer for question 1 第一題用戶(hù)的答案
var q2answer; // user‘s answer for question 2 第二題用戶(hù)的答案
var totalCorrect = 0; // counts number of correct answers 答對(duì)的題數(shù)
var displayTotal; // text field for displaying user‘s score 顯示用戶(hù)分?jǐn)?shù)的變量
// stop the movie at the first question
stop();
你會(huì)發(fā)現(xiàn)//開(kāi)頭的那一行代碼都變了色,//代表的是注釋?zhuān)怯脕?lái)輔助閱讀代碼用的,對(duì)代碼執(zhí)行沒(méi)有影響(是的,你在里面寫(xiě)笑話(huà),寫(xiě)小說(shuō)都可以,不會(huì)影響你的FLASH的^-^)
我們定義了四個(gè)將要用到的變量,用途已經(jīng)在注釋里面寫(xiě)了,寫(xiě)注釋也是一個(gè)好習(xí)慣
關(guān)于命名變量名
變量起名displayTotal,意思是 display total,因變量名不能使用空格和破折號(hào),所以用第二個(gè)單詞的開(kāi)始字母大寫(xiě),以此分隔單詞
一些程序員也喜歡用下劃線:display_total
記住一定要給你的變量起一個(gè)一眼就能識(shí)別意義的名字
添加label
我們知道第二題是在第10幀的,我們只需要一句AS:gotoAndStop(10); 就可以執(zhí)行第二個(gè)問(wèn)題了
不過(guò)MOOCK告訴你這不是好習(xí)慣,因?yàn)閯?dòng)畫(huà)的內(nèi)容是不斷改變的,所以我們應(yīng)當(dāng)習(xí)慣使用label,即使幀數(shù)如何變化,只要label指向正確,不需要修改ACTION都可以繼續(xù)運(yùn)行(chocobo再提醒你吧,不要使用相同的label,即使在不同是Scene當(dāng)中)
好了,我們?cè)趌abel層的第1、10、20分別F6創(chuàng)建關(guān)鍵幀,給他們寫(xiě)上init、q2、quizEnd
要給按鈕寫(xiě)上代碼了
在三個(gè)按鈕里面分別寫(xiě)入代碼,大同小異的:
按鈕一:
on (release) {
q1answer = 1;
gotoAndStop ("q2");
}
按鈕二:
on (release) {
q1answer = 2;
gotoAndStop ("q2");
}
按鈕三
on (release) {
q1answer = 3;
gotoAndStop ("q2");
}
這三段代碼用人類(lèi)的語(yǔ)言描述,就是:當(dāng)用戶(hù)點(diǎn)擊某個(gè)按鈕選擇答案后,把他選擇的答案記錄到q1answer變量中去,然后進(jìn)入下一題。
on這個(gè)單詞代表隨后的就是一個(gè)要觸發(fā)的事件
release是指在按鈕上松開(kāi)鼠標(biāo)這樣一個(gè)事件
當(dāng)動(dòng)畫(huà)執(zhí)行到這里的時(shí)候,三個(gè)按鈕都會(huì)分別監(jiān)聽(tīng)用戶(hù)有沒(méi)有做在按鈕上放開(kāi)鼠標(biāo)這個(gè)動(dòng)作,一旦發(fā)生,按鈕就會(huì)自動(dòng)執(zhí)行大括號(hào){}里面的代碼了
若用戶(hù)選第一個(gè),{}中是:
q1answer = 1; //用q1answer變量記住用戶(hù)選擇的是第一個(gè)答案
gotoAndStop ("q2"); //進(jìn)入下一題
上面我用了注釋的方法來(lái)解釋兩句代碼,你必須習(xí)慣,因?yàn)椴皇撬性闯绦蚨加薪坛?,但是好的源程序都?huì)有注釋
第二題的按鈕與前面相似,只是變量換為q2answer,選擇完進(jìn)入結(jié)束的畫(huà)面,例如第一個(gè),改為:
on (release) {
q2answer = 1;
gotoAndStop ("quizEnd");
}
結(jié)束的畫(huà)面
結(jié)束應(yīng)該做什么,當(dāng)然是告訴用戶(hù)分?jǐn)?shù)啦,寫(xiě)在第20幀,就是label為quizEnd的那幀的代碼:
// tally up the user‘s correct answers
if (q1answer == 3){
totalCorrect = totalCorrect + 1;
}
if (q2answer == 2){
totalCorrect++; //totalCorrect++其實(shí)是totalCorrect = totalCorrect + 1;一個(gè)更簡(jiǎn)潔的寫(xiě)法,幾乎少打了一半的字母啊。
}
// show the user‘s score in an on-screen text field
displayTotal = totalCorrect;
用人的語(yǔ)言描述:如果第一題選3,答對(duì)數(shù)加一,如果第二題選2,答對(duì)數(shù)加一,把答對(duì)題目數(shù)賦予另一變量
現(xiàn)在答對(duì)的題數(shù)是放到變量displayTotal中了,怎么顯示?
在quiz end第20幀處建關(guān)鍵幀,鍵入"Thank you for taking the quiz! Your score final score is: /2"(謝謝回答問(wèn)題,你最后成績(jī)是答對(duì)了 /2道題)
在"/2"之前那個(gè)空白的地方放上一個(gè)文本框,菜單Text>>Options顯示文本面板,把Static Text下拉改為Dynamic Text,順便把Border/Bg的鉤去掉,最后在Variable那一欄填上要顯示的變量名displayTotal
你是不是和chocobo一樣不耐煩了?快下載http://www.moock.org/webdesign/lect...oockQuizzes.zip ;吧,里面的quiz.fla就是本章的內(nèi)容,其他的fla的內(nèi)容也將會(huì)在后面講到

[nextpage]

第六章 再來(lái)補(bǔ)充一點(diǎn)AS知識(shí)
數(shù)據(jù)分類(lèi)是很有必要的,象8005154556這樣的一個(gè)數(shù)字是沒(méi)有多大意義的,但是如果將他歸類(lèi)到電話(huà)號(hào)碼:800-515-4556,那就有意義了。(這是WHO的電話(huà)???是不是MOOCK的?呵呵)
AS里面數(shù)據(jù)的類(lèi)型相對(duì)其他語(yǔ)言已經(jīng)算少的,有:
* 字符串String 由一系列的characters組成,可以包含字母,數(shù)字和符號(hào),一般用雙引號(hào)""擴(kuò)?。ㄓ涀〔灰獙?xiě)了全角的“”)
* 數(shù)字Number
* 布爾值Boolean 用于條件判斷的時(shí)候,只有兩個(gè)值true和false
* Null and Undefined 這也是數(shù)據(jù)的類(lèi)型之一,Null代表變量還沒(méi)有內(nèi)容,Undefined是連變量都未定義
* 數(shù)組Array 用來(lái)按順序地存放一組數(shù)據(jù)
* MovieClip 這也是數(shù)據(jù)的一種嗎?你就當(dāng)它是FLASH特有的一種數(shù)據(jù)吧,裝的就是一個(gè)個(gè)MC INSTANCE(解釋一下吧,MC從library拖到場(chǎng)景中就是一個(gè)獨(dú)立的instance,一個(gè)MC可以創(chuàng)立多個(gè)instance),還有MC里面的其他數(shù)據(jù)
* Object 可以是FLASH已經(jīng)內(nèi)部定義的,或者是用戶(hù)寫(xiě)程序時(shí)自定義的一類(lèi)數(shù)據(jù)
再分類(lèi)一下
number, string, boolean, undefined, and null,這些屬于簡(jiǎn)單的數(shù)據(jù)類(lèi)型,特征是只有一個(gè)值
array, object, movieclip. 就可以包含不止一個(gè)值
chocobo:其實(shí)array也應(yīng)該算是object,上面這些概念的東西總是有些沉悶,沒(méi)關(guān)系,留下印象,以后用到了,自然會(huì)回過(guò)來(lái)真正了解一遍的
第七章 可以重復(fù)的函數(shù)(function)
不是用幾個(gè)例子來(lái)示范嗎?怎么還不講例子???是的,下一個(gè)例子要用到函數(shù),所以再補(bǔ)充點(diǎn)函數(shù)知識(shí)。(上當(dāng)了吧?chocobo也上當(dāng)了,開(kāi)始翻譯的時(shí)候沒(méi)想到這篇東西這么長(zhǎng)的,這才講完第一個(gè)例子呢 55~)
一個(gè)函數(shù)是下面這個(gè)樣子的:
function funcName () {
statements
}
在ACTION面板里面,function這個(gè)單詞是變色的,F(xiàn)LASH認(rèn)識(shí)這個(gè)單詞,它代表后面的就是描述函數(shù)的內(nèi)容
funcName是函數(shù)的名字,當(dāng)你以后要用這函數(shù)的時(shí)候,就要敲這個(gè)名字了(是的,建函數(shù)就是為了以后反復(fù)調(diào)用它)
()小括號(hào)里面是參數(shù),什么是參數(shù)一會(huì)再講
{}大括號(hào)里面的就是函數(shù)所要完成功能的一句句代碼。
當(dāng)我們建立函數(shù)之后,函數(shù)并不運(yùn)行,只在你用函數(shù)的名字調(diào)用它出來(lái),才正式開(kāi)始運(yùn)行
例如我們有這樣一個(gè)函數(shù)
function sayHi () {
trace("Hi!");
}
當(dāng)我們?cè)贔LASH某幀需要sayHi的時(shí)候,輸入AS:
sayHi();
是不是和最常見(jiàn)的stop();還有play();一樣???因?yàn)樗鼈兌际呛瘮?shù)嘛
sayHi函數(shù)真是智,來(lái)個(gè)有意義的函數(shù)吧。先在場(chǎng)景里放好一個(gè)名字叫ball的instance(千萬(wàn)記得要給instance輸入名字,否則函數(shù)運(yùn)行沒(méi)結(jié)果別找我)
在第一幀輸入這樣一個(gè)函數(shù):
function moveBall () {
ball._x += 10; // 怕有人不懂,解釋一下,_x代表ball的橫坐標(biāo),ball._x +=10 的意思是ball._x = ball._x + 10 ,這樣省略的寫(xiě)法還有 -= *= /= 等等
ball._y += 10;
}
再做一個(gè)按鈕,按鈕的AS:
on (release) {
moveBall();
}
好的,運(yùn)行,從AS你可以看到,每點(diǎn)一下按鈕,執(zhí)行一次函數(shù),而函數(shù)讓小球下斜下移動(dòng)。(FLASH的坐標(biāo)軸,原點(diǎn)在左上角)
為什么要建立函數(shù)呢,就是想更有效率,現(xiàn)在有這個(gè)函數(shù)已經(jīng)不用每移動(dòng)一下寫(xiě)一次AS了,但還是不夠,我們需要更有擴(kuò)展性(flexibility)的函數(shù)
這個(gè)函數(shù)只能移動(dòng)叫ball的MC,只能向固定的方向移動(dòng)固定的距離,我們需要可以移動(dòng)任何MC,向任何方向移動(dòng)任何距離的函數(shù),這樣可以省卻很多輸入AS的工夫(這就叫一勞永逸,呵呵)
我們的新函數(shù)有三個(gè)地方是每次調(diào)用都不一樣的
1、移動(dòng)的那個(gè)MC的名字
2、水平移動(dòng)的距離
3、垂直移動(dòng)的距離(呵呵,用極坐標(biāo),也可以把2、3說(shuō)成移動(dòng)的距離,和移動(dòng)的角度,不過(guò)大家都不習(xí)慣極坐標(biāo))
為了告訴函數(shù)這些變化的地方,我們需要參數(shù)(parameters),參數(shù)在定義函數(shù)的時(shí)候就要輸入,我們的函數(shù)改寫(xiě)好了:
function moveClip (theClip, xDist, yDist) {
theClip._x += xDist;
theClip._y += yDist;
}
當(dāng)我們要實(shí)現(xiàn)原來(lái)函數(shù)功能的時(shí)候,現(xiàn)在調(diào)用新函數(shù)就變成
moveClip (ball, 10, 10);
定義函數(shù)的時(shí)候function moveClip (theClip, xDist, yDist) {
這里的theClip等參數(shù)(parameters)只是定義,本質(zhì)上說(shuō)是不存在的,因?yàn)闆](méi)有內(nèi)容嘛
當(dāng)我們用moveClip (ball, 10, 10);調(diào)用的時(shí)候,ball就輸入到theClip中去了,這里的ball稱(chēng)為arguments(偶讀得書(shū)少,不會(huì)翻譯)
arguments可以是一個(gè)變量,也可以是一個(gè)表達(dá)式(例如"a"+"b",先得出結(jié)果再傳輸給函數(shù))只要用逗號(hào)隔開(kāi)各個(gè)參數(shù)就行
函數(shù)如何結(jié)束呢
正常來(lái)說(shuō),函數(shù)運(yùn)行完 {}里所有語(yǔ)句結(jié)束,我們也可以用一句AS:return; 讓它中途結(jié)束,例如:
function say(msg) {
return;
trace(msg);
}
這個(gè)函數(shù)被調(diào)用的時(shí)候?qū)⑹裁炊疾蛔鼍徒Y(jié)束
return還有更重要的用途:
function sqr

{ // Squares a number 平方
return x * x;
}
a=sqr(2); //a將會(huì)被賦予2的平方 4
return更重要的用途就是返回?cái)?shù)據(jù)
在AS里面,有個(gè)內(nèi)建的函數(shù)Math.sqrt(就是說(shuō)你敲入的時(shí)候會(huì)變色),其功能和我們剛才做的sqr函數(shù)是一樣的,現(xiàn)在你該知道內(nèi)建函數(shù)也沒(méi)什么神秘的,我們一樣可以做出相同功能的來(lái)。
第八章 第二個(gè)版本選擇題的制作
讀到這你發(fā)現(xiàn)什么,我是發(fā)現(xiàn)了,MOOCK不是在教AS,他簡(jiǎn)直是在上編程課。
在第一個(gè)版本的制作里你發(fā)現(xiàn)了什么缺點(diǎn)?是的,輸入了很多次AS,很麻煩。
我們要做的是用函數(shù)來(lái)集中我們的代碼,只有集中了才好修改,越復(fù)雜的程序越是如此(想象一下在很多個(gè)MC之間查代碼,真是頭痛,當(dāng)然是集中一塊好)
這個(gè)多選題,我們就歸結(jié)成兩個(gè)函數(shù)吧answer和gradeUser
代碼(可以直接看源程序,在上面地址那個(gè)ZIP里面的quiz-version2.fla):
大部分的代碼都被集中到第一幀了,千萬(wàn)不要被一大堆代碼嚇著了,代碼這么長(zhǎng),只是為了讓閱讀者看得更清楚而已。(其實(shí)越短的代碼才越可怕呢,呵呵)
// Stop the movie at the first question
stop ();
// Initialize main timeline variables 定義變量
var displayTotal; // Textfield for displaying user‘s score
var numQuestions = 2; // Number of quiz questions
var q1answer; // User‘s answer for question1
var q2answer; // User‘s answer for question2
var totalCorrect = 0; // Number of questions answered correctly 以上和例一一樣
var correctAnswer1 = 3; // The correct choice for question 1 第一題的正確答案
var correctAnswer2 = 2; // The correct choice for question 2 第二題的正確答案
// Function to register user‘s answers 這個(gè)函數(shù)的功能是提交答題者的答案
function answer (choice) {
answer.currentAnswer++;
//現(xiàn)在answer.currentAnswer是1,正在提交的是第一題,下一次answer.currentAnswer就變成2,代表提交的是第二題
set ("q" + answer.currentAnswer + "answer", choice);
// 不復(fù)雜不復(fù)雜,"q" + answer.currentAnswer + "answer"第一題的時(shí)候就是q1answer,第二題是q2answer,把參數(shù)choice傳過(guò)來(lái)的值放到兩個(gè)變量里面而已
if (answer.currentAnswer == numQuestions) {
// 判斷是不是兩題都答完了,是就轉(zhuǎn)到問(wèn)題結(jié)束幀
gotoAndStop ("quizEnd");
} else {
gotoAndStop ("q" + (answer.currentAnswer + 1));
}
}
// Function to tally user‘s score 這個(gè)函數(shù)是改題的
function gradeUser() {
// Count how many questions user answered correctly 將兩個(gè)答案和正確答案比較,對(duì)就totalCorrect加一
//此處用了一個(gè)for循環(huán),大家如有疑問(wèn)的,可以查AS字典,在帝國(guó)就有中文版
for (i = 1; i <= numQuestions; i++) {
// 下面用的eval有必要說(shuō)一下,它的作用是將字符串和變量組成一個(gè)新的變量名,是個(gè)很方便的功能
if (eval("q" + i + "answer") == eval("correctAnswer" + i)) {
totalCorrect++;
}
}
// Show user‘s score in an on-screen text field 將答案顯示出來(lái),與第一個(gè)例子同
displayTotal = totalCorrect;
}
好了,第一幀的函數(shù)寫(xiě)好了,之后每個(gè)答案的選擇按鈕就簡(jiǎn)單了
例如第一題的選項(xiàng)一,就寫(xiě):
on (release) {
answer(1);
}
第二題的寫(xiě)法同上(如果你的選擇題有很多道,做法都是一樣的,只要復(fù)制第一題,然后把題目改了就行)
最后在quizEnd幀里面調(diào)用改題的函數(shù)gradeUser();
分析第二個(gè)例子是代碼,你會(huì)發(fā)現(xiàn)比第一個(gè)例子精簡(jiǎn)了很多。
而集中在同一幀的代碼,將:
* 更容易修改
* 更容易升級(jí)
* 更少的出錯(cuò)機(jī)會(huì)
* 更容易查錯(cuò)
* 更精簡(jiǎn)(更少的字節(jié)數(shù))
第九章 數(shù)組(arrays)
在下一個(gè)新版本的多選題里,我們將使用什么AS的特性,來(lái)讓它更好呢?
那就是數(shù)組。
數(shù)組就是一系列的數(shù)據(jù)(MOOCK又開(kāi)始上課了,chocobo的英文和計(jì)算機(jī)都不算好,為免誤人子弟,概念性的東西盡量精簡(jiǎn))
例如這樣兩個(gè)變量?jī)?chǔ)存的數(shù)據(jù):
fruit1 = "oranges";
fruit2 = "apples";
它們是互相獨(dú)立的,使用起來(lái)很不方便,我們需要的是數(shù)組,以下是數(shù)組的定義方法,用“&#;”框住,用“,”分隔開(kāi)每個(gè)元素:
fruitList = ["oranges", "apples"];
現(xiàn)在兩個(gè)數(shù)據(jù)是放到同一個(gè)數(shù)組里面了,我們開(kāi)始詳細(xì)解說(shuō)數(shù)組
數(shù)組里面每一個(gè)數(shù)據(jù)稱(chēng)為元素(element)。
而每一個(gè)元素都有個(gè)獨(dú)立數(shù)字代表所處的位置,數(shù)字叫索引(index),注意! 第一個(gè)數(shù)據(jù)的索引是0,第二個(gè)才是1
要按索引來(lái)提出數(shù)據(jù),我們要用一個(gè)運(yùn)算符&#;,例如使用fruitList第一個(gè)元素賦值給a:
a=fruitList�;
又例如將a的值賦給fruitList第一個(gè)元素:
fruitList�=a;
當(dāng)然&#;里面也可以放表達(dá)式、變量:
var index = 3;
// Set numApples to 2
var a = fruitList[index];
下面是個(gè)使用表達(dá)式的例子:
// Create a myFrames array. Note the legal formatting. 建立一個(gè)記錄LABEL的數(shù)組
var myFrames = ["storyEnding1",
"storyEnding2",
"storyEnding3",
"storyEnding4"];
// Set randomFrame to a randomly picked element of myFrames
// by calculating a random number between 0 and 3
// 隨機(jī)從數(shù)組中提取一個(gè)LABEL
var randomFrame = myFrames[Math.floor(Math.random() * 4)];
// Now go to the random frame
// 然后跳到該LABEL播放
gotoAndStop(randomFrame);
而數(shù)組包含數(shù)據(jù)的個(gè)數(shù)稱(chēng)為長(zhǎng)度(length),例如fruitList.length 就等于2
對(duì)數(shù)組最常用的處理就是從數(shù)組中選出有用的數(shù)據(jù)了,來(lái)看一個(gè)運(yùn)用循環(huán)的例子:
// Create an array 建立數(shù)組,里面放了一些歌的類(lèi)型
var soundtracks = ["electronic",
"hip hop",
"pop",
"alternative",
"classical"];
// Check each element to see if it contains "hip hop"
// 一個(gè)循環(huán),檢查每一個(gè)元素是否等于"hip hop"這個(gè)類(lèi)型
// 另外,請(qǐng)留意此處MOOCK對(duì)FOR的寫(xiě)法,J=0之前有一個(gè)VAR,這好象可有可無(wú),其實(shí)是一個(gè)好習(xí)慣!
for (var j = 0; j < soundtracks.length; j++) {
trace("now examining element: " + j);
if (soundtracks[j] == "hip hop") {
trace("the location of ‘hip hop‘ is index: " + j);
break; // 跳出循環(huán),找到了就不用再找了
}
}
關(guān)于數(shù)組的方法(method)
方法就是從屬于某一對(duì)象(object)的函數(shù),通常都是對(duì)該對(duì)象進(jìn)行處理的函數(shù)
好象太抽象了?我們還沒(méi)講到什么是對(duì)象,其實(shí)數(shù)組是對(duì)象的一種,我們就暫且將數(shù)組的方法理解為一個(gè)專(zhuān)門(mén)處理數(shù)組內(nèi)數(shù)據(jù)的結(jié)構(gòu)和內(nèi)容的工具吧
例如一個(gè)叫push()的方法就是一個(gè)工具,用于為數(shù)組添加一個(gè)元素,并且加在該數(shù)組的最后
使用起來(lái)并不復(fù)雜,看例子就知:
// Create an array with 2 elements
var menuItems = ["home", "quit"];
// Add an element 加一個(gè)元素
// menuItems becomes ["home", "quit", "products"]
// 現(xiàn)在數(shù)組的結(jié)構(gòu)變成["home", "quit", "products"]
menuItems.push("products");
// Add two more elements 這次是加兩個(gè)
// menuItems becomes ["home", "quit", "products", "services", "contact"]
menuItems.push("services", "contact");
跟push()相反從最后彈出一個(gè)元素的方法是pop()
而跟push()類(lèi)似,但是是將一個(gè)元素加到數(shù)組的開(kāi)頭的方法是unshift(),與之相反的是shift()
方法sort和reverse,用于重新排列數(shù)組的元素
方法splice用于從數(shù)組中間刪除某元素
方法slice和concat可以在某些數(shù)組的基礎(chǔ)上生成另一個(gè)新的數(shù)組
方法toString和join可以將整個(gè)數(shù)組變成單一個(gè)字符串
以上方法都可以從AS字典里面查到

[nextpage}

第十章 第三個(gè)版本的選擇題
首先,此版本沿用了上一版本的函數(shù)answer和gradeUser
在這一版本中,用戶(hù)的答案與正確答案將使用數(shù)組來(lái)存放
看看我們的新代碼:
stop();
// *** Init main timeline variables
var displayTotal; // Text field for displaying user‘s final score
var numQuestions = 2; // Number of questions in the quiz
var totalCorrect = 0; // Number of correct answers
// 上一版本中,用戶(hù)答案使用了兩個(gè)變量來(lái)存放,但是試想如果是10題、100題呢?使用數(shù)組將更容易管理,也更容易處理
var userAnswers = new Array(); // Array containing user‘s guesses 這是定義數(shù)組的語(yǔ)句,但是還未輸入數(shù)據(jù)
var correctAnswers = [3, 2]; // Array containing each correct answer 這一句既定義數(shù)組,同時(shí)輸入數(shù)據(jù),因?yàn)檎_答案是已知的
// *** Function to register the user‘s answers
function answer (choice) {
// Tack the user‘s answer onto our array 將數(shù)據(jù)PUSH進(jìn)數(shù)組,因?yàn)槭琼樞虼痤},所以用方法PUSH
userAnswers.push(choice);
// Do a little navigation, baby
// 如果答案數(shù)超過(guò)題目總數(shù),自然就跳到quizEnd幀了
// 注意在本例中,已經(jīng)不用上例的answer.currentAnswer而是使用userAnswers.length來(lái)控制問(wèn)題是否結(jié)束
// 我們甚至可以用correctAnswers.length來(lái)代替numQuestions,記錄正確答案數(shù)組的長(zhǎng)度,不就是題目總數(shù)嗎?
if (userAnswers.length == numQuestions) {
gotoAndStop ("quizEnd");
} else {
gotoAndStop ("q"+ (userAnswers.length + 1));
}
}
// *** Function to tally the user‘s score
function gradeUser() {
// Count how many questions were answered correctly.
// 開(kāi)始改題,這里就不用再用上個(gè)版本的eval啦,那個(gè)東東實(shí)在是難懂兼難用,這個(gè)版本相對(duì)就很清晰明快
for (var j = 0; j < userAnswers.length; j++) {
if (userAnswers[j] == correctAnswers[j]) {
totalCorrect++;
}
}
// Show the user‘s score in a dynamic text field
displayTotal = totalCorrect;
}
電影的其他部分不用改動(dòng)(這就是使用FUNTION的好處啦,升級(jí)多快~)
OK,進(jìn)入下一章之前想想目前版本的點(diǎn)
* 題目,每次修改題目都要進(jìn)入FLASH的場(chǎng)景修改,麻煩
* 按鈕,每題就要做三個(gè)按鈕
這都是麻煩的地方,我們要更精益求精地修改,讓我們的多選題,輕易地從兩題變成10題、100題
接下來(lái)我們要做的是
* 進(jìn)一步改進(jìn)我們存放數(shù)據(jù)的結(jié)構(gòu)
* 讓我們可以動(dòng)態(tài)地生成每一道題目,只需輸入數(shù)據(jù),而不需要在FLASH里面作就可以自動(dòng)生成
所以——我們需要面向?qū)ο缶幊蹋?object oriented programming)
chocobo:嘻嘻,眾菜鳥(niǎo)是不是都倒了,AS基礎(chǔ)教程竟然開(kāi)始講OOP了,呵呵,沒(méi)關(guān)系啊,上面的教程一直都這么淺,以后也深不了
第十一章 一點(diǎn)面向?qū)ο缶幊讨R(shí)
At is heart, OOP simply means that you treat portions of your program as self-contained, but interrelating modules called objects.
這是什么呀?我不翻譯了,概念的我們就先不懂吧,對(duì)象主要構(gòu)成包括屬性(properties)和方法(methods)
一個(gè)對(duì)象通常都以現(xiàn)實(shí)世界里的某個(gè)東東做藍(lán)本
例如我們可以定義一個(gè)對(duì)象叫球
那么這個(gè)球?qū)?huì)有這樣的屬性:半徑、X坐標(biāo)、Y坐標(biāo)、顏色
同時(shí),也會(huì)用屬于球自己的方法例如:移動(dòng)球、計(jì)算球的面積
當(dāng)然,我們還可以定義一些相對(duì)抽象的對(duì)象,例如我們要做的多選題
所有的對(duì)象都屬于某類(lèi)(class),類(lèi)的意思其實(shí)是用于創(chuàng)建對(duì)象的模版
一個(gè)實(shí)例(instance)就是某一個(gè)類(lèi)的特定某一個(gè)case(好復(fù)雜,概念性的東西我翻不過(guò)來(lái)啦,反正實(shí)例就類(lèi)創(chuàng)建出來(lái)的某一個(gè)對(duì)象)
還是再舉例吧
* 例如我們有個(gè)一個(gè)叫Chair的類(lèi)
* 這個(gè)類(lèi)定義了一個(gè)東西需要它有四條腿,一個(gè)坐墊
* 然后我們就可以用Chair這個(gè)類(lèi)來(lái)定義我們的不同對(duì)象(可理解為椅子的款式),每個(gè)對(duì)象就有它特有的高、寬、材料、重量、顏色,正是這些屬性使每個(gè)對(duì)象互相區(qū)別。
所有的椅子互相區(qū)別,有自己的屬性,但是他們又有同樣的結(jié)構(gòu):四條腿、一個(gè)坐墊
OK,那AS里面的類(lèi)和對(duì)象呢?
是的,AS里我們可以自己創(chuàng)建對(duì)象,也有可以使用的內(nèi)建對(duì)象
內(nèi)建的類(lèi)(你可以用它來(lái)創(chuàng)建對(duì)象)包括:Array, Boolean, Color, Date, MovieClip, Number, Object, Sound, String, XML, XMLSocket
內(nèi)建的對(duì)象(已經(jīng)可以直接使用的對(duì)象)包括:Arguments, Key, Math, Mouse, Selection
內(nèi)建的類(lèi)、對(duì)象當(dāng)然都是在FLASH里面有自己功能的東西。而正是這些功能非常常用,F(xiàn)LASH才內(nèi)建了這些類(lèi)和對(duì)象,例如:
Mouse.hide(); // Hide the mouse pointer 將鼠標(biāo)隱藏,你經(jīng)常用吧?現(xiàn)在才知道其實(shí)是內(nèi)建的Mouse對(duì)象的一個(gè)hide()方法吧?
在學(xué)習(xí)如何創(chuàng)建自己的類(lèi)和對(duì)象之前,先來(lái)了解一下內(nèi)建類(lèi)和對(duì)象是怎樣工作的吧
與數(shù)組的結(jié)構(gòu)類(lèi)似,對(duì)象是容器們(containers)的容器(container)
一個(gè)對(duì)象,用各個(gè)獨(dú)立的屬性來(lái)存放數(shù)據(jù),只不過(guò)數(shù)組區(qū)分每個(gè)容器是用數(shù)字,而對(duì)象則是用屬性名,要調(diào)用一個(gè)數(shù)組里面某個(gè)數(shù)據(jù),我們需要它是索引值,而要調(diào)用對(duì)象的屬性,則要知道屬性名
看看以下這個(gè)例子,這是個(gè)叫BALL的對(duì)象“
BALL對(duì)象有兩個(gè)屬性:radius 和 color
而兩個(gè)屬性分別賦值為:50 和 0xFF0000 (這是AS里面表達(dá)16進(jìn)制的方法)
概念清楚了,說(shuō)一AS里面使用對(duì)象要注意的地方
首先,對(duì)象的屬性很靈活,它儲(chǔ)存的數(shù)據(jù)可以是strings(字符串), numbers(數(shù)字), booleans(布爾值), null(空), undefined(未定義), functions(函數(shù)), arrays(數(shù)組), movie clips(電影夾子), or even other objects(甚至是其他的對(duì)象,包括自定義的).
調(diào)用屬性,可用點(diǎn)語(yǔ)法:objectName.propertyName
例如我們賦值給BALL里面的屬性radius:
ball.radius = 100;
我們也可以用符號(hào)&#;來(lái)訪問(wèn)屬性,但是&#;里面的屬性名需用雙引號(hào)擴(kuò)住,同上例:
ball["radius"] = 100; (所以說(shuō)數(shù)組也是對(duì)象一種,訪問(wèn)方法也一樣,并沒(méi)有搞特殊化)
與點(diǎn)語(yǔ)法比較,&#;更靈活,可以動(dòng)態(tài)地改變屬性的名字,里面可以是變量或表達(dá)式,例如:
var propName = "radius";
ball[propName] = 100;
這點(diǎn)是點(diǎn)語(yǔ)法無(wú)法辦到的
純粹的OOP中,我們幾乎不會(huì)直接訪問(wèn)對(duì)象的屬性
我們一般都使用方法(methods) ,來(lái)改變屬性
例如改變mySound這個(gè)聲音對(duì)象的音量屬性
AS的用法應(yīng)該是mySound.getVolume(100);
而不是mySound.volume=100;
但是為了簡(jiǎn)單,多選題這個(gè)例子里不一定遵循這個(gè)原則,事實(shí)上AS里面很多對(duì)象都不可以辦到這點(diǎn),所以有人說(shuō)AS不是面向?qū)ο笳Z(yǔ)言。
關(guān)于對(duì)象的方法
方法method其實(shí)是一些附屬于對(duì)象的函數(shù),其作用主要是訪問(wèn)對(duì)象中的數(shù)據(jù),或完成某種功能
所以調(diào)用方法和調(diào)用普通函數(shù)類(lèi)似:objectName.methodName() 只是前面加上了對(duì)象的名字
例如上面的BALL對(duì)象,我們需要它的面積,使用 getArea 這個(gè)方法:
ball.getArea();
預(yù)習(xí)一下,在下一個(gè)例子中,雖然MOOCK不打算建立自己的方法,但是將使用內(nèi)建于MovieClip對(duì)象的兩個(gè)方法:
*MovieClip.attachMovie()
此方法是將Library(CTRL+L按出來(lái)的那個(gè))里面的symbol復(fù)制一個(gè)instance到場(chǎng)景中
(chocobo:給不懂概念的人緊急補(bǔ)習(xí),放在庫(kù)(Library)里面的叫符號(hào)(symbol),拉到場(chǎng)景中就叫實(shí)例(instance),一個(gè)符號(hào)可創(chuàng)建多個(gè)實(shí)例,符號(hào)改變則實(shí)例隨之改變)
與之類(lèi)似的是MovieClip.duplicateMovieClip(),但是該方法需要事先在場(chǎng)景里已經(jīng)有一個(gè)實(shí)例
*MovieClip.removeMovieClip()
此方法與上面相反,是刪除場(chǎng)景里面的instance的
大家看到了,在下一例中,我們將使用MovieClip這個(gè)內(nèi)建對(duì)象,因?yàn)樗涂梢詽M(mǎn)足我們的需要,不必新類(lèi)型的對(duì)象了
我們先來(lái)熟悉一下MC這種對(duì)象
它有很多屬性_height(高度)、 _alpha (透明度),MC的屬性大家可以在AS字典里面查到,在AS面板里這寫(xiě)屬性也是變色顯示的
同時(shí)MC的方法,例如 MC.play(); 等也可以查到
當(dāng)我們?cè)贛C里面的時(shí)間線使用這些屬性、方法的時(shí)候,可以省略不寫(xiě)前面部分,直接寫(xiě)play();
MC可以互相嵌套,MC當(dāng)中又有MC,就出現(xiàn)類(lèi)似: mc1.mc2.play(); 的情況
為了調(diào)用包含自己的上一級(jí)MC的方法、屬性,AS里面用_parent,例如:
在mc1包含mc2 ,在mc2中想使mc1播放:_parent.play();
還有另一個(gè)保留字:_root指代該電影的主時(shí)間線
例如想在某個(gè)mc里面讓整個(gè)電影播放:_root.play();
想在某個(gè)MC中讓另一mc1播放:_root.mc1.play();
還有,MC中定義的變量,將作為MC的一個(gè)屬性可被訪問(wèn)
在mc1里面寫(xiě)了一句 var a=1;
我們將可使用 mc1.var來(lái)調(diào)用它
關(guān)于類(lèi)(class)
這個(gè)概念大家還是不大懂吧?類(lèi)就是定義一個(gè)對(duì)象將擁有什么的方法跟屬性的東東,類(lèi)似MC里instance與symbol的關(guān)系,instance的結(jié)構(gòu)就是由symbol決定的,每個(gè)instance又可以不一樣
AS里面沒(méi)有專(zhuān)門(mén)定義類(lèi)的例如class這樣的關(guān)鍵字,我們使用函數(shù)來(lái)定義類(lèi),這種函數(shù)稱(chēng)構(gòu)造函數(shù)constructor function,函數(shù)的作用就是產(chǎn)生我們定義好的類(lèi)的實(shí)例(就是對(duì)象)
舉例最實(shí)在:
// make a Ball constructor 最簡(jiǎn)單的構(gòu)造函數(shù)
function Ball () {
// do nothing 里面是空的
}
現(xiàn)在我們可以定義新類(lèi)型Ball的對(duì)象了
myBall = new Ball();
語(yǔ)法就是前面是新對(duì)象實(shí)例名,等號(hào)后是new加構(gòu)造函數(shù)名
myBall就擁有了Ball定義的一切結(jié)構(gòu)了(雖然Ball里面是空的,嘻嘻)
不過(guò)不是所有對(duì)象創(chuàng)建都用new,例如mc創(chuàng)建就用的是attachMovie()或duplicateMovieClip()
好了,我們的構(gòu)造函數(shù)總不能空的,如何定義類(lèi),讓新對(duì)象有自己的屬性呢?
使用this這個(gè)關(guān)鍵字,看例子,新的構(gòu)造函數(shù):
function Ball () {
this.radius = 10;
this.color = 0xFF0000;
this.xPosition = 35;
this.yPosition = -4;
}
以后我們定義出來(lái)的新對(duì)象,都擁有半徑,顏色、XY坐標(biāo)屬性啦
慢著,怎么每個(gè)新對(duì)象都一模一樣???
再改,用函數(shù)的參數(shù)來(lái)定義動(dòng)態(tài)的屬性:
// Make the Ball constructor accept
// property values as arguments.
function Ball (radius, color, xPosition, yPosition) {
this.radius = radius;
this.color = color;
this.xPosition = xPosition;
this.yPosition = yPosition;
}
我們可以定義不同屬性的對(duì)象了
myBall = new Ball(6, 0x00FF00, 145, 200);
本教程關(guān)于還有創(chuàng)建方法以及如何在類(lèi)之間繼承方法和屬性沒(méi)講,
無(wú)論如何,OOP都不可能在這么短時(shí)間之內(nèi)說(shuō)清楚,
但這不妨礙我們做下一個(gè)例子了。

第十二章 第四個(gè)版本的選擇題
第三個(gè)版本的時(shí)候我們已經(jīng)設(shè)想好,新版本中題目將是動(dòng)態(tài)生成的,不用我們?cè)贔LASH的場(chǎng)景里面一題一題輸入了,我們要做的只是輸入題目和題目答案的數(shù)據(jù)就夠了。
很明顯,每一條題目都將是一個(gè)對(duì)象(不然我們學(xué)這么多對(duì)象的知識(shí)干嘛?),而這些所有的題目,會(huì)用一個(gè)數(shù)組來(lái)存放
再重提一下,可配合源程序?qū)W習(xí) http://www.moock.org/webdesign/lect...oockQuizzes.zip ;
好,開(kāi)始設(shè)計(jì)題目的模版
模版就是一個(gè)MC,包含兩個(gè)TEXT FIELD,里面不用填東西,分別起變量名為:(FOR小鳥(niǎo):TEXT FIELD就是按工具條里T按鈕拉出來(lái)的文本框,同時(shí)還要在文本面板(ctrl+t)里將其改為Dynamic Text,變量名則在面板的Variable處改)
* qNum (以后將顯示題目的編號(hào))
* qText (以后將顯示題目的正文)
我們還要在庫(kù)里面做標(biāo)識(shí),點(diǎn)一庫(kù)面板(ctrl+l)右上的Options>> Linkage ,選第二個(gè)Expert this symbol,identifier填上questionTemplate,至此,題目模版完成
再制作選項(xiàng)的模版
選項(xiàng)模版應(yīng)包括一個(gè)選擇用的按鈕
還有該選項(xiàng)的內(nèi)容,一個(gè)起名為answerText的TEXT FIELD
在本例的后面,將為每一個(gè)動(dòng)態(tài)生成的選項(xiàng)一個(gè)唯一的名字,譬如: "answer0", "answer1",..."answern".
答題者所選定的答案將由這個(gè)名字來(lái)決定,調(diào)用一個(gè)MC的名字,用的是_name這個(gè)屬性
所以答題的按鈕上面的AS為:
on (release) {
// Trim the prefix "answer" off this clip‘s name
// 下面使用了String.slice()方法,例如_name為answer0,它將被處理成0,slice的具體語(yǔ)法請(qǐng)查閱AS字典
// 按鈕提交什么由該MC的名字決定的,我作個(gè)標(biāo)記 @@ ,記得一會(huì)看回來(lái)
choice = _name.slice(6, _name.length);
// 與前面的例子一樣,最后將答案提交給answer函數(shù)處理,不過(guò)現(xiàn)在我們是在某一MC里面用外面主時(shí)間線的函數(shù)了,所以得加上_root
_root.answer(choice);
}
最后,Options>> Linkage,標(biāo)識(shí)名:answerTemplate,制作模版的工作就完成了
下面將是放在第一幀的程序主體,可要打起精神來(lái)了:
// Stop the movie
stop();
// Init main timeline variables
var displayTotal; // Text field for user‘s final score
var totalCorrect = 0; // Number of questions answered correctly
// Array containing the user‘s guesses 記錄作答答案的數(shù)組
var userAnswers = new Array();
// Number of the question the user is on 記錄正在作答中題目的編號(hào)
// 要注意的是,它是由0開(kāi)始的,第一題的編號(hào)是0,因?yàn)槲覀円玫綌?shù)組,數(shù)組的第一個(gè)編號(hào)是0,所以這里我們也用0
var currentQuestion = 0;
// The Question constructor
// 以下是新類(lèi)型對(duì)象question的構(gòu)造函數(shù),包含三個(gè)屬性:正確答案,題目正文,各個(gè)選項(xiàng)
function Question (correctAnswer, questionText, answers) {
this.correctAnswer = correctAnswer;
this.questionText = questionText;
this.answers = answers;
}
// Import the source file containing our array of question objects
// 咦?應(yīng)該是輸入各條題目的數(shù)據(jù)先啊,放哪去了?因?yàn)槁?,?shù)據(jù)輸入是個(gè)與編程無(wú)關(guān)的過(guò)程,為了讓代碼更優(yōu)雅,這些繁瑣的東西扔別地方去了,AS太長(zhǎng),會(huì)使查閱相當(dāng)麻煩,分開(kāi)存放也是好習(xí)慣!
// #include是引用外部AS命令,可以將AS分開(kāi)儲(chǔ)存于各個(gè)后綴名為AS的文件中,輸入題目的代碼就是放到了questionsArray.as中(記得和FLA放在同一目錄下喔)
#include "questionsArray.as"
//// 我改變了一下教程的結(jié)構(gòu),把questionsArray.as的內(nèi)容也插入進(jìn)來(lái)了,因?yàn)樘^(guò)這段的話(huà),看起來(lái)會(huì)有疑問(wèn)
//// 以下內(nèi)容系存放questionsArray.as中的
// 輸入數(shù)據(jù)其實(shí)是建立對(duì)象
// MOOCK用一個(gè)數(shù)組還存放這些對(duì)象,這樣對(duì)象才更易于管理
// 不要被括號(hào)給弄昏了,輸入對(duì)象參數(shù)的中間還有中括號(hào),是因?yàn)檩斎腩}目的參數(shù)“各個(gè)選項(xiàng)”是一個(gè)數(shù)組
// 因?yàn)槭谴娣庞跀?shù)組中,每個(gè)對(duì)象之間記得應(yīng)有逗號(hào)分隔
// Remember to place a comma after each object
// in the array except the last
questionsArray = [new Question (2,
"Which version of Flash first introduced movie clips?",
["version 1", "version 2", "version 3",
"version 4", "version 5", "version 6"]),
new Question (2,
"When was Action formally declared a ing language?",
["version 3", "version 4", "version 5"]),
new Question (1,
"Are regular expressions supported by Flash 5 Action?",
["yes", "no"]),
new Question (0,
"Which sound format offers the best compression?",
["mp3","aiff", "wav"]),
new Question (1,
"True or False: The post-increment operator (++) returns the
value of its operand + 1.",
["true", "false"]),
new Question (3,
"Action is based on...",
["Java", "Java", "C++", "ECMA-262", "Perl"])];
//// 離開(kāi)questionsArray.as部分,我們繼續(xù)
// Begin the quiz 出題目!調(diào)用makeQuestion函數(shù)來(lái)完成,我們只需要給這個(gè)函數(shù)一個(gè)參數(shù):題目的編號(hào),函數(shù)就會(huì)按編號(hào)提取數(shù)據(jù),結(jié)合我們剛才做的模版生成題目。
makeQuestion(currentQuestion);
// Function to render each question to the screen
// 下面就是makeQuestion函數(shù)
function makeQuestion (currentQuestion) {
// Clear the Stage of the last question
//這句是清理上一題生成的MC,這句從第二題開(kāi)始生效,questionClip就是題目的MC名,MC從哪來(lái)的?看下面就知道了
questionClip.removeMovieClip();
// Create and place the main question clip
// 利用模版questionTemplate生成一個(gè)叫questionClip的MC,這個(gè)MC就是我們的問(wèn)題
attachMovie("questionTemplate", "questionClip", 0);
// 設(shè)定MC的位置
questionClip._x = 277;
questionClip._y = 205;
// 把題目編號(hào)輸入MC的qNum文本框中
questionClip.qNum = currentQuestion + 1;
// questionsArray[currentQuestion]就是數(shù)組questionsArray里的第currentQuestion個(gè)對(duì)象,例如currentQuestion是0,那么就是我們的第一條題目
// questionsArray�.questionText就是第一條題目對(duì)象的問(wèn)題屬性
// 然后問(wèn)題輸入MC的qText文本框中
questionClip.qText = questionsArray[currentQuestion].questionText;
// Create the individual answer clips in the question clip
// 以下循環(huán)將結(jié)合選項(xiàng)模版生成這一條題目的各個(gè)選項(xiàng)的MC
// questionsArray[currentQuestion].answers記得嗎?選項(xiàng)這個(gè)屬性可是個(gè)數(shù)組,所以我們把它的長(zhǎng)度作為循環(huán)的次數(shù),這個(gè)數(shù)組有多大,我們就生成多少個(gè)選項(xiàng)
for (var j = 0; j < questionsArray[currentQuestion].answers.length; j++) {
// Attach our linked answerTemplate clip from the Library.
// It contains a generalized button and a text field for the question.
// 用answerTemplate做模版生成MC,MC名為"answer" + j ,即第一個(gè)選項(xiàng)MC名為answer0,第二個(gè)為answer1,選項(xiàng)的名字可是關(guān)系到按鈕選什么的,如果你忘了,看看上面有 @@ 標(biāo)記的地方
// 同時(shí)它們的深度為j,每次不同
// 但和上面不同的是,我們要把選項(xiàng)MC生成到題目MC里,這樣我們清除題目MC的同時(shí)也清除了選項(xiàng)
// 所以寫(xiě)成questionClip.attachMovie
questionClip.attachMovie("answerTemplate", "answer" + j, j);
// Place this answer clip in line below the question.
// 設(shè)定MC的位置,第一個(gè)高度為70,之后順序加15
questionClip["answer" + j]._y += 70 + (j * 15);
questionClip["answer" + j]._x -= 100;
// Set the text field in the answer clip to the appropriate
// element of this question‘s answer array.
// 下面語(yǔ)句的:questionClip["answer" + j]可不是指數(shù)組,j=0的時(shí)候,它代表questionClip.answer0,具體解釋可見(jiàn)上一章。
// 這句語(yǔ)句的作用是把questionsArray[currentQuestion]這個(gè)對(duì)象數(shù)組里面的answers[j]數(shù)組,輸入到對(duì)應(yīng)的選項(xiàng)MC的answerText文本框中,就是該選項(xiàng)的內(nèi)容
questionClip["answer" + j].answerText = questionsArray[currentQuestion].answers[j];
}
//生成選項(xiàng)的循環(huán)結(jié)束
}
// Function to register the user‘s answers
// 以下是記錄答題者答案的函數(shù),記錄在數(shù)組userAnswers中,和上一例同
// 每一個(gè)選項(xiàng)如果被選都會(huì)調(diào)用此函數(shù),并用參數(shù)choice傳來(lái)作答的答案
function answer (choice) {
userAnswers.push(choice);
// 判斷是否題目全部完成,是的話(huà)清楚掉題目MC,并跳轉(zhuǎn)到quizEnd幀
if (currentQuestion + 1 == questionsArray.length) {
questionClip.removeMovieClip();
gotoAndStop ("quizEnd");
} else {
// 在這里改變題目的編號(hào),然后調(diào)用makeQuestion函數(shù)再次生成新的題目
currentQuestion++;
makeQuestion(currentQuestion);
}
}
// Function to tally the user‘s score
// 改題的函數(shù)
function gradeUser() {
// Count how many questions the user answered correctly
for (var j = 0; j < questionsArray.length; j++) {
// 將答題數(shù)組userAnswers[j]與問(wèn)題數(shù)組questionsArray[j]的屬性correctAnswer逐個(gè)比較
if (userAnswers[j] == questionsArray[j].correctAnswer) {
totalCorrect++;
}
}
// Show the user‘s score in an onscreen text field
// 顯示答對(duì)與題目數(shù)比
displayTotal = totalCorrect + "/" + questionsArray.length;
}
好了,我們來(lái)總結(jié)一下這個(gè)例子吧
我們已經(jīng)完成了第三個(gè)版本結(jié)束時(shí)候定下來(lái)目標(biāo),更快捷的建設(shè),更便易的擴(kuò)展
我們的題目跟選項(xiàng)都是動(dòng)態(tài)生成的,也就是說(shuō)生成10、100題或更多題目也只需要修改questionsArray.as這個(gè)文件就可以了
如果說(shuō)生成兩題這個(gè)例子用時(shí)要長(zhǎng)于上面的例子,那么生成100題,你會(huì)發(fā)現(xiàn)用這個(gè)例子將是最快的。還有,在100題里面修改其中一題,也是最快的。
看完了例子,希望大家不是只明白了代碼的含義,最重要是理解運(yùn)用對(duì)象來(lái)編程的方法
同樣的例子,其實(shí)還可以用其他的對(duì)象結(jié)構(gòu)來(lái)完成的
更有效地組織數(shù)據(jù)也是編程藝術(shù)的一部分
為了更進(jìn)一步改進(jìn)我們的例子,最后一個(gè),就是第五個(gè)版本,將用XML代替那個(gè)存放對(duì)象的數(shù)組(也就是在questionsArray.as里那個(gè)),它實(shí)在太難懂了,是不是?。亢呛?br>XML,名字是不是很COOL啊,其實(shí),F(xiàn)LASH里面用XML不難(其他地方的應(yīng)用就……所以千萬(wàn)別說(shuō)XML不難,是FLASH里面用不難),呵呵,好吧,開(kāi)始吧。

[nextpage]

第十三章 XML
XML是一種標(biāo)記語(yǔ)言,通常用于儲(chǔ)存,組織和傳輸數(shù)據(jù)
XML文檔主要由一系列的元素(elements)和屬性(attributes)組成,看下面一個(gè)XML的例子:
Colin Moock
O‘Reilly
這個(gè)例子就是由元素 BOOK, TITLE, AUTHOR, PUBLISHER 組成的
在元素里就包含了一個(gè)屬性:SALUTATION
這些元素怎么讓瀏覽器解釋是什么意思呢?它需要DTD,一套決定這些標(biāo)記的意義的規(guī)則。(例如我們常聽(tīng)說(shuō)的WML、SVG,它們都是XML,但對(duì)應(yīng)不同的DTD)
XML與HTML想比要求格式更嚴(yán)格,格式要求:
* tags 一定要嵌套 (就是說(shuō)有就一定要有)
* 一定要有一個(gè)根元素 (例如例子中的 BOOK)
* 開(kāi)始部分要用XML聲明標(biāo)記 :
但是AS里面的XML不需要DTD(這就是我說(shuō)FLASH里面用XML不難的原因,哈哈)
從我們面向?qū)ο蟮慕嵌葋?lái)看,我們XML的內(nèi)容可以當(dāng)做為對(duì)象,下圖就是我們建立XML對(duì)象的層次結(jié)構(gòu)
FLASH已經(jīng)內(nèi)建有XML類(lèi)讓我們可以定義自己的XML對(duì)象,同時(shí)XML對(duì)象還有很多方法。
我們還是更進(jìn)一步用例子分析吧,如果我們建立了如上圖的XML對(duì)象,那么FLASH首先會(huì)自動(dòng)建立一個(gè)元素document.下面才是我們自己的元素。
本來(lái)是第一個(gè)元素的BOOK成為了document.第一個(gè)節(jié)點(diǎn)(node),不過(guò)我們把它繼續(xù)當(dāng)我們XML數(shù)據(jù)的根也無(wú)妨
當(dāng)一個(gè)節(jié)點(diǎn)包含于另一個(gè)節(jié)點(diǎn)時(shí),這個(gè)節(jié)點(diǎn)稱(chēng)為另一節(jié)點(diǎn)的子節(jié)點(diǎn)(child),反之另一節(jié)點(diǎn)稱(chēng)為其的父節(jié)點(diǎn)(parent)
例子中BOOK就是document.child,document.是BOOK的parent
再看圖,BOOK有7個(gè)子節(jié)點(diǎn),是不是和你想象不同?多了四個(gè)節(jié)點(diǎn)#text,因?yàn)镕LASH把標(biāo)記之間的空格和回車(chē)也讀成一個(gè)節(jié)點(diǎn)了。
幾個(gè)子節(jié)點(diǎn)的關(guān)系成為兄弟(siblings),如果要找AUTHOR的下一個(gè)兄弟(next sibling),F(xiàn)LASH就會(huì)給你找來(lái)#text
這可不是我們想要的,解決的方法
* 直接在XML里面把空格回車(chē)都刪除掉,就是說(shuō)一個(gè)TAG緊挨著一個(gè)
* 用AS把無(wú)用的子節(jié)點(diǎn)刪除
* 在FLASH讀入XML源數(shù)據(jù)之前,將該XML對(duì)象的一個(gè)屬性ignoreWhite設(shè)置為true,但是該屬性只在R41版本的PLAYER生效(注:網(wǎng)上可以更新的版本為R41,但是隨FLASH附帶的FLASHPLAYER的版本是R30)
再回到我們的例圖,三個(gè)子節(jié)點(diǎn)下面還有子節(jié)點(diǎn),最尾的節(jié)點(diǎn)也可以叫葉節(jié)點(diǎn)。
但是圖里面還有個(gè)東西我們沒(méi)找到,就是AUTHOR的屬性SALUTATION,屬性不是該節(jié)點(diǎn)的子節(jié)點(diǎn),要訪問(wèn)我們屬性,要用XML.attributes
概念先說(shuō)這么多,現(xiàn)在看看我們?cè)趺窗裍ML源程序輸入進(jìn)FLASH
首先定義一個(gè)新的XML對(duì)象了:
mydocument.nbsp= new XML();
這個(gè)對(duì)象是空的,我們通過(guò)appendChild, par***ML, 和 load 三種方法來(lái)輸入數(shù)據(jù)
當(dāng)然我們也可以在定義的時(shí)候就輸入數(shù)據(jù):mydocument.nbsp= new XML(‘
hello world!
‘);
這時(shí)候我們的mydocument.有了一個(gè)叫P的子節(jié)點(diǎn),P的葉節(jié)點(diǎn)是hello world!
之后我們就可以訪問(wèn)這個(gè)XML對(duì)象了,firstChild這個(gè)XML屬性指向第一個(gè)子節(jié)點(diǎn),childNodes是XML對(duì)象的子對(duì)象,指向所有的子節(jié)點(diǎn)
mydocument.firstChild // Accesses P
mydocument.childNodes� // Also accesses P 兩個(gè)AS語(yǔ)句指向的都是節(jié)點(diǎn)P
要訪問(wèn)葉節(jié)點(diǎn)的內(nèi)容需要屬性nodevalue
我們要顯示P節(jié)點(diǎn)的子節(jié)點(diǎn)的內(nèi)容,就要寫(xiě)成:trace(mydocument.firstChild.firstChild.nodevalue);
要給它賦值:
mydocument.firstChild.firstChild.nodevalue = "goodbye cruel world";
要?jiǎng)h除P節(jié)點(diǎn),用方法removeNode:
mydocument.firstChild.removeNode();
新建一個(gè)節(jié)點(diǎn)叫P,用方法createElement創(chuàng)建元素:
newElement = mydocument.createElement("P");
再將該元素加進(jìn)去作為一個(gè)節(jié)點(diǎn),用方法appendChild:
mydocument.a(chǎn)ppendChild(newElement);
做一個(gè)葉節(jié)點(diǎn)方法類(lèi)似:
newText = mydocument.createTextNode("XML is fun");
mydocument.firstChild.appendChild(newText);
更詳盡的方法還是查閱AS字典吧.
第十四章 最后一個(gè)版本選擇題
上一個(gè)版本面向?qū)ο蟮拇a對(duì)我們這個(gè)基于XML的版本很有幫助,上一個(gè)版本我們是用對(duì)象的數(shù)組來(lái)存我們的數(shù)據(jù),這個(gè)版本里面,我們使用外部的XML文件
下面先看看XML文件的結(jié)構(gòu):
version 1
version 2
version 3
version 4
version 5
version 6
version 3
version 4
version 5
yes
no
mp3
aiff
wav
true
false
java
java
c++
ecma-262
perl
這個(gè)XML里面,QUIZ是我們的根元素
每一題都放在QUESTION元素內(nèi),題目正文為其屬性TEXT,正確答案為其屬性ANSWER(ANSWER=1代表選第二個(gè)答案)
每一題的選項(xiàng)則是QUESTION的子節(jié)點(diǎn)CHOICE
其實(shí)根本就不用解釋?zhuān)蠹抑苯涌炊寄芸炊?br>使用了外部XML之后,我們升級(jí)題目只需改動(dòng)XML文件即可,而上一個(gè)版本,修改外部AS文件之后還是需要EXPORT一次。
這個(gè)版本里面,將保留上個(gè)版本大部分的代碼,除了輸入題目數(shù)據(jù)的部分,將用XML來(lái)代替。
以下代碼寫(xiě)到questionsArray.as中覆蓋其原來(lái)內(nèi)容
首先仍然定義一個(gè)數(shù)組來(lái)存放數(shù)據(jù)
var questionsArray = new Array();
然后我們定義一個(gè)XML對(duì)象來(lái)存放XML數(shù)據(jù)
var quizDoc = new XML();
之后是建立將XML解釋為我們存放題目的對(duì)象格式的函數(shù)buildQuestionsArray(),同時(shí)將它連接到新建的XML對(duì)象的onLoad函數(shù),讓XML下載完成之后執(zhí)行這個(gè)函數(shù)
quizDoc.onLoad = buildQuestionsArray
然后是執(zhí)行下載XML的AS
quizDoc.load("quiz.xml");
最后我們?cè)敿?xì)解說(shuō)一下解釋XML的函數(shù)
// *** builds an array of question objects based on the dom tree in quizDoc
function buildQuestionsArray () {
// first, strip unwanted whitespace nodes from the tree.
// 除去無(wú)用的節(jié)點(diǎn),上一章已經(jīng)有介紹無(wú)用節(jié)點(diǎn)是如何出現(xiàn)的
stripWhitespaceDoublePass(quizDoc);
// now assign a convenient reference to the root QUIZ node
// XML文件的根節(jié)點(diǎn)QUIZ節(jié)點(diǎn)就是 quizDoc.childNodes ,這里將其指名為quizNode,以便運(yùn)用
var quizNode = quizDoc.childNodes
// for each question node that is a child of the QUIZ node...
// 下面的循環(huán)將逐個(gè)提取QUIZ節(jié)點(diǎn)的子節(jié)點(diǎn),即每條題目
for(var k = 0; k < quizNode.childNodes.length; k++) {
// make an array of the text nodes from each CHOICE node
// 為每條題目建立一個(gè)選項(xiàng)數(shù)組
var choicesArray = new Array();
// 下面的循環(huán)則是將題目的子節(jié)點(diǎn),即各選項(xiàng)的nodevalue輸入到choicesArray數(shù)組中
for(var j = 0; j < quizNode.childNodes[k].childNodes.length; j++) {
choicesArray[j] = quizNode.childNodes[k].childNodes[j].firstChild.nodevalue;
}
// construct a question object for each QUESTION node,
// and store it in questionsArray
// 用題目正文、選項(xiàng)數(shù)組、正確答案(正確答案目前還是字符串,所以用Number函數(shù)將之轉(zhuǎn)為數(shù)字)作為參數(shù),建立Question對(duì)象(定義Question對(duì)象的代碼已經(jīng)在上個(gè)例子中解釋了)
// 將新建的Question對(duì)象作為questionsArray數(shù)組的一個(gè)元素
questionsArray[k] = new Question (
Number(quizNode.childNodes[k].attributes.answer),
quizNode.childNodes[k].attributes.text,
choicesArray);
}
// done loading and processing the quiz questions
loadMsg = "";
// begin the quiz
// 調(diào)用函數(shù)makeQuestion,之后的進(jìn)度就同上一個(gè)例子了
makeQuestion(currentQuestion);
}
// *** Strips whitespace nodes from an XML document. // *** by passing twice through each level in the tree
// 下面函數(shù)用于除去無(wú)用的空白節(jié)點(diǎn),參數(shù)是需要處理的XML的根元素(我們已經(jīng)將其指名為XMLnode了)
function stripWhitespaceDoublePass(XMLnode) {
// Loop through all the children of XMLnode
// 循環(huán)依次將根元素的子元素提取出來(lái)
for (var k = 0; k < XMLnode.childNodes.length; k++) {
// If the current node is a text node...
// 如果該節(jié)點(diǎn)是一個(gè)文本節(jié)點(diǎn),就開(kāi)始以下檢查 ...
if(XMLnode.childNodes[k].nodeType == 3) {
// ...check for any useful characters in the node.
var j = 0;
var emptyNode = true;
for(j = 0;j < XMLnode.childNodes[k].nodevalue.length; j++) {
// A useful character is anything over 32 (space, tab,
// new line, etc are all below).
// 因?yàn)榭崭?、TAB或換行等空白無(wú)意義字符的ASCII碼都小于32,檢查若大于32,即為有數(shù)據(jù)的節(jié)點(diǎn),同時(shí)用break;跳出檢查的循環(huán)
if(XMLnode.childNodes[k].nodevalue.charCodeAt(j) > 32) {
emptyNode = false;
break;
}
}
// If no useful charaters were found, delete the node.
// 若該節(jié)點(diǎn)沒(méi)有數(shù)據(jù),就是解釋時(shí)的錯(cuò)誤,將其刪除
if(emptyNode) {
XMLnode.childNodes[k].removeNode();
}
}
}
// Now that all the whitespace nodes have been removed from XMLnode,
// call stripWhitespaceDoublePass on its remaining children.
// 但是還沒(méi)完,我們只檢查了所有子節(jié)點(diǎn),而沒(méi)有檢查子節(jié)點(diǎn)的子節(jié)點(diǎn),所以以下的循環(huán)將所有子節(jié)點(diǎn)也送到本函數(shù)再繼續(xù)檢查
// 這種函數(shù)自己調(diào)用自己的方法,稱(chēng)為遞歸,它將一直檢查子節(jié)點(diǎn)的子節(jié)點(diǎn)的子節(jié)點(diǎn)的……一直到該節(jié)點(diǎn)沒(méi)有子節(jié)點(diǎn)為止
for(var k = 0; k < XMLnode.childNodes.length; k++) {
stripWhitespaceDoublePass(XMLnode.childNodes[k]);
}
}
現(xiàn)在,我們可以把SWF和XML組成的題目交給一個(gè)不會(huì)編FLASH的老師了,他只要就會(huì)用記事本修改XML文件就行了。

 
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
flash+xml教程(初級(jí)數(shù)據(jù)調(diào)用教程)
as3.0常識(shí)
追求簡(jiǎn)約而且簡(jiǎn)單的AJAX封裝:Prototype
json-rpc-java (一)
JavaScript權(quán)威指南 第11章 樣章
NirvanaStudio--如何優(yōu)化JavaScript腳本的性能
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服