欧美三区四区_av先锋影音资源站_亚洲第一论坛sis_影音先锋2020色资源网_亚洲精品社区_在线免费观看av网站_国产一区二区伦理_亚洲欧美视频一区二区_99视频精品全部免费在线_精精国产xxxx视频在线

新手來看:Flahs as入門教程_Flash教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:Flash簡單制作光暈動畫效果
下面我們來做一個模擬光斑的效果,效果如上圖,這一課主要學習色彩的調節變換,因為調節出好的色彩才會使圖像更加亮麗,增加層次感和視覺效果。調出好的色彩誰

這里我只簡單的介紹一下AS的基本常識。
首先我們要了解AS要寫在什么地方,什么時候AS會被觸發執行。
1、幀:
寫在要害幀上面的AS,當時間軸上的指針走到這個要害幀的時候,就寫在這個幀上面的AS就被觸發執行了。常見的例子有在影片結尾的幀寫上 stop() 等。操作方法就是點選要害幀,然后打開AS面板。
2、按鈕:
不同于幀上面的AS,按鈕上面的AS是要有觸發條件的。要把AS寫在按鈕上,操作方法是點選目標按鈕,然后打開AS面板。舉個例子能說的更明白。
假設有一個動畫,要讓它在播放完同時停止,那么,你要做的就是在這個動畫的最后一幀寫AS
stop();
再假設有個按鈕,效果是按下按鈕后停止播放,那么步驟如下。
做一個按鈕,放到主場景,點選按鈕,然后打開AS面板。現在假如也在按鈕上寫
stop();
那么,輸出的時候就會提示錯誤。正確的應該這樣寫
on(release){
stop();
}
這里要比幀的動畫多這些代碼: on(release){} , 整個代碼翻譯過來就是:
當(松開){
停止
}
紅色的代碼表示鼠標的觸發事件事件之一,這里用的是 release 松開,按鈕的常用事件:
release 松開
releaseOutside 在按鈕外面松開
press 按下
rollOver 鼠標進入按鈕的感應區
rollOut 鼠標離開按鈕的感應區
現在很明確了:寫在按鈕上面的AS一定就是這種格式的:
on(事件){要執行的代碼}
3、MC(電影剪輯)
假如你看懂了上面的內容,那么寫在MC上面的AS和寫在按鈕上的大同小異。操作方法就是點選MC,然后打開AS面板。看個例子
onClipEvent(load){
stop();
}
同樣,MC需要一個事件來觸發AS的執行。翻譯這段代碼就是
當剪輯(載入){
停止
}
紅色代碼同樣表示一個事件。MC的事件有下面這些:
load 載入,當MC出現的時候執行。也就是除非卸載這個MC,否則load事件內的代碼只執行一次
unload 卸載,當MC卸載的時候執行
enterFrame 存在的每個幀。在MC存在的每個幀都要執行一次代碼。假如你的場景有100個幀,有個MC從41幀開始出現到100幀才消失,那么這個MC上面的代碼執行了60次
mouseDown 按下鼠標,在場景內任何地方都算。和按鈕不一樣的地方
mouseMove 移動鼠標,只要移動鼠標就執行代碼
mouseUp 松開鼠標
同樣你要明確:寫在MC上的代碼一定總是這種格式:
onClipEvent(事件){代碼}
看到這里,假如你明白的寫在 幀、按鈕、MC上的代碼有什么不一樣,任務就算完成了

AS 對象篇
重點 :點語法學會表達對象
學會用絕對路徑和相對路徑表達對象
雖然AS不是真正的面向對象的編程,但是它也有對象的概念。這個概念貫穿整個AS的始終,所以,對對象的理解,比對語法或者其他的理解更為重要。現在開始吧:
首先,我們來了解一下路徑,路徑分兩種:絕對路徑和相對路徑。做過html的朋友應該知道這個概念。但這里我還是要具體解釋一下,我認為對路徑的理解要深入,我初學的時候就是磕在路徑上。
在講路徑之前,有必要先講一下 .語法 : 舉例說明,這里要表示房間里的桌子上的一本
書,用 .語法這么表示:
房間.桌子.書
假如要再細到書上的頁上面的字,很顯然
房間.桌子.書.頁面.字
看明白了吧?我也不懂得怎么說, .語法就是這樣表示對象的,點的前面是其后面的父級。如房間是桌子的父級,桌子的子級就是書。
還是不明白?這樣吧,你把 . 里寫成“里面的”就可以了,這樣就是
房間(里面的)桌子(里面的)書(里面的)頁面(里面的)字
這樣輕易多了吧?
現在我開始說路徑了,其中也要夾雜的對象的說明,看:
從例子入手。新建一個Flash文件,然后創建一個MovieClip,MC命名為“MC”,放在主場景里面,然后再創建一個按鈕,放在“MC”里面,然后從庫里面拖一個出來放在主場景,分別給這兩個元素實例命名(Instance Name , 注重是實例名不是MC的名字):MC->myMC button->myBtn
現在我們假設主場景是房子,MC是桌子,按鈕是書,那么分別怎么表達房子,桌子,書呢?如下
_root 房子
_root.myMc 房子.桌子
_root.myMc.myBtn 房子.桌子.書
這里的 _root 是Flash的要害字,表示主場景的 Timeline (時間線)。
很輕易理解對不。這里的 房子,桌子,書 都是我們要理解的“對象”。
當你找到這個對象后,才能對對象進行操作,才能給對象施加方法。比如,我現在要打掃房子,打掃是方法,但對象是房子,表達式是這樣 :
房子.打掃()
假如你不能正確的表達房子這個對象,你的打掃也就不能正確的實施了。
*說明:這里為什么要在打掃后面加()呢?因為打掃是方法不是對象,為了讓Flash知道這是個方法,我們必須加上(),要不然它會以為房子里面有“打掃”這個東西。
現在,我們可以很輕易的對房間里面的各個東西進行操作,如
房子.打掃();
房子.木桌子.整理();
房子.玻璃桌子.打壞();
房子.書桌.書.看();
等等,相信你把它們"翻譯"成AS代碼沒什么問題吧 比如要主場景停止播放,就是
_root.stop();
要MC停止播放,就是
_root.myMc.stop();
現在說說相對路徑。還是上面的例子。假如給你下了一個命令:修理房子里面的紅色的椅子。那么怎么表達呢?就是:
房子.紅色椅子.修理()
無論給你下命令的人在哪里告訴你的,你都會知道要修理的椅子是哪一張。但是他假如這么說:修理你現在坐的這張椅子。紅色的?還是藍色的?這就要取決于你坐在哪個椅子上了。那么相對的表達式就是
我坐的椅子.修理();
這里為什么不這么寫呢:
房子.我坐的椅子.修理()
這么寫是錯的,因為我坐的椅子是不固定的,我說不定把椅子搬到房子外面去坐,那這個表達式就錯了,因為椅子根本就不在房子里面。
換過來用Flash實例說明。現在我想讓主場景下的 myMC 在一開始就不要播放,而是先停止。那么你有什么辦法呢?
我你猜想到的辦法可能就是在主場景放入這個MC的那個幀寫上:
_root.myMc.stop();
這個是對的。但是一旦 myMc 的名字一變,你就得跟著改這句話了。
有沒有辦法不管這個“MC”的實例名不管怎么改,都會被我們同樣一句的AS找到?當然可以,前提是你的AS必須“坐在這個MC上”。
進入Mc的編輯狀態 , 在 Mc 的 Timeline 的第一幀寫上
this.stop();
這里的this也是Flash的要害字 , 這個 this 指AS所在的這條 Timeline .
現在不管你這個MC放在哪里,命名是什么,我都不管,反正肯定會停下來。為什么,因為AS正“坐在MC上”。
假如你在這里寫上
_root.stop();
那就錯了。為什么?仔細想想。
這個 this 就是相對路徑的要害字之一。你必須要仔細理解它。
另外的一個要害字就是 _parent 。假如你理解了 this , 那么 _parent 并不難理解。舉例:
還是哪個假設 房子(_root) , 桌子( mc_zhuozi ) , 書 (mc_shu) 他們的關系是(括號內為mc實例名)
房子.桌子.書
_root.mc_zhuozi.mc_shu
在 mc_zhuozi 的 timeline 里面寫
_parent.打掃();
意思就是打掃房間;
在 mc_shu 的 timeline 里面寫
_parent.打掃();
意思就是打掃桌子。
_parent 也就是父級。桌子的 _parent 就是房子的 timeline , 書的 _parent 也就是 桌子的 timeline。點的后面的對象 的 _parent 就是點前面的對象。

AS 語法篇

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

AS基礎精典教程

作者和出處俱不詳,版權歸原作者所有
次給大家帶來MOOCK在世界性FLASH大會:FF2K1大會上的演說,要說到Action的權威,當然要數MOOCK,他寫的ASDG(一本書)是可以和FLASH自帶的AS字典相提并論的寶貝。雖然他是這樣一個高高手,但是他的這個演講卻是非常的淺顯,假如你某處讀起來覺得難,那也一定是chocobo翻譯得不好。(有些地方實在是太淺,我受不了就改了 )
這篇文章預算的演講時間很長,所以讀起來也會覺得較長,你可以分開來讀。
還有,本文是關于FLASH5的AS的,究竟FLASH4的AS已經淘汰。
第一章:由O開始
為了示范,MOOCK將會做一個多選題問答的動畫來做為例子。
這個例子以4種不同版本的方法來實現。
對于用戶來說,4種版本使用起來將沒有區別,只是對于我們開發者來說,研究的就是如何改進這些FLASH代碼的結構與組織。
改進的重點在于:
*更便易的維護
*更便易的擴展
*更快捷的建設
要牢記的是,學習編程是一個過程(process)而不是一個事件(event)。
假如你第一次學習到的時候不能照著完成也不必擔心。
接下來,MOOCK說到為了照顧沒有多少編程經驗的菜鳥,會由最最最簡單的開始。


關于計算機語言:
編程語言是用來發信息給電腦,從電腦接受信息的
編程語言也有詞匯表和文法,如人類的語言類似
通過編程語言我們可以告訴電腦去做什么,也可以從他那獲得信息
關于語法和邏輯
學習編程的思想比學習一種語言的語法重要
假設FLASH是懂我們語言的單詞的,我們對FLASH說:“Flash, 讓一個球在屏幕里面彈來彈去吧”
FLASH會什么都做不了,FLASH要我們用他的世界懂的東西,例如:movie clips, buttons, frames,來描述它要做的事
那我們再說一次:“Flash, 讓一個名字叫ball_one的movie clip在屏幕里面彈來彈去吧”
我們已經用MC這個FLASH懂的東西來描述了,但FLASH還是什么都不做,因為它需要更多的信息:
*這個球有多大
*它放在哪里?
*一開始它首先往哪個方向運動?
*它初始的速度是多少
*它在屏幕的那一個范圍之內彈來彈去呢?
*彈來彈去要持續多久呢?
看來我們需要有邏輯結構地告訴FLASH它應該怎么去做
1、一個球指的是一個叫ball_one的圓形MC,直徑50像素
2、還有一個方形MC叫square,邊長300像素
3、將ball_one放在square上某處
4、以一個隨機的角度,75像素每秒的速度開始移動ball_one


5、假如ball_one接觸到square的某邊,就彈回
6、一直不停地運動下去,知道我們讓它停
假如FLASH真的懂我們語言的單詞,他應該知道如何開始做了
總結一下要害點:
無論是使用什么語言,編程思想的藝術都在于用如何將邏輯步驟列出
在你開始將要做的事用計算機語言描述之前,用我們人類的語言描述一次會很有幫助
即使你將他們翻譯成任何的計算機語言,他們的邏輯步驟應該是一樣的
電腦不懂用假設完成去你的想法,他們沒有思考能力(chocobo:就是你要把要求完全無遺漏地寫出來讓它運行)

第二章:基礎
首先了解如何在FLASH輸入程序
在FLASH菜單Window里面Actions可打開ACTION面板,ACTION面板分右面的腳本窗,和左面的工具窗
腳本窗就是放腳本的地方,而工具窗用于快速地輸入各種ACTION,運算符,函數,屬性,對象
MOOCK建議大家使用專家模式,在FLASH菜單的Edit的Preferences的Actions panel里面選Expert Mode,以后每次打開ACTION面板都會自動設置為專家模式(專家模式可直接輸入代碼,初學者學下去就會知道,很多代碼無法在普通模式里輸入)
AS的一些概念
所有代碼都需存于某個地方,可以是frame(幀), button(按鈕), or movie clip(電影夾子)。
只要你選擇了某按鈕或MC,你之后輸入的代碼就存放在它的上面了,注重此時ACTION面板上方提示為Object Actions。同理你也可以將代碼存放于幀,不過此時提示為Frame Actions。
當你在專家模式的時候仍無法輸入代碼,你首先要檢查你是否選擇了frame, button, 或MC來存放代碼。
然后我們象學所有語言一樣吧,來個HELLO WORLD吧
在ACTION面板輸入
var message = "HELLO WORLD";
trace (message);
然后我們按CTRL和ENTER鍵,看到結果了嗎?
以下兩章比較基礎。MOOCK是騙演講費嗎?
第三章:解讀
第一行代碼:var message = "HELLO WORLD";
告訴FLASH記住一個名字叫message的容器(通常在計算機里稱為變量(variable),在FLASH里面,變量可以裝文字,和可以裝數字)里面裝了這樣的數據(datum),內容為:"HELLO WORLD"
“=”等號是一個常用的運算符號(operators),在FLASH里面它不是代表相等,而是代表賦值
var 命令的含義是公布給整個電影,此變量的內容是什么。
第二行代碼:trace (message);
就是要FLASH顯示message里面的內容,為什么FLASH能輸出內容呢,因為當你按CTRL ENTER又或者在網上打開這個電影的時候,你輸入的每一段Action Scrpit代碼,都會通過FLASH的解釋器(interpreter)來解讀然后執行
假如解釋器能解釋你的代碼,他會運行它,并返回你要返回的結果,假如解釋器看不懂你的代碼,他也會返回錯誤代碼——告訴你錯誤的原因
通常,我們發給解釋器的命令不只命令這么簡單,還包括命令的內容例如trace (message); 這個trace輸出命令的內容就是message,計算機里就稱為參數(argument或parameter),假如一個命令支持多個參數,參數之間一般用“,”來分割
第四章 還有一些概念
表達式(expression):(2 3) * (4 / 2.5) - 1可稱為一個表達式,"a" "b"也是表達式,需要解釋器運算才得到結果的值,一個相反的概念,不需要運算的直接引用的,稱為literal
條件(conditionals):(look at a series of options and make a decision about what to do based on the circumstances)
不翻譯了,大概意思就是美女穿著新衣上街,會先看看外面會否下雨,這就叫條件判定啦
if(天氣=="下雨"){trace("還是帶把雨傘吧")}
循環(loop):假如要輸出5個數字,你是寫5遍trace命令嗎?更多的就不行了吧
你可以用while和for命令來完成重復的動作
事件(events):放在frame里面的代碼只要電影播放到就會執行,放在MC、button的代碼則只在解釋器發現預先設置好的事件被觸動的時候執行。最典型的就是一下鼠標點擊按鈕造成press時間啦。
函數(functions):將一組程序打包成一句命令來調用他,其實FLASH里面的很多命令就是函數:trace、play、gotoAndStop等等都是。

第五章 開始第一個版本的選擇題的制作
多選題共有兩道
如圖,大家應該養成一個好習慣,用一個獨立的層來放置代碼,并把該層放到最上面會更便于修改。
第二層則獨立放置Label。不要覺得麻煩,只要你想到世界上大部分好的閃客都是如此做的,你就不會嫌麻煩了。
以下的層放的是選擇題的內容,如上圖
開始創建題目
在question 1層的第一幀,寫上題目"When were movie clips introduced into Flash?" (什么時候FLASH開始引入電影夾子的概念?)
再寫上三個選項:Version 1, Version 2, Version 3
跟著我們再做一個用來選擇的方框按鈕,從Library里面拖出這樣的三個按鈕,分別放到各個選項的前面。
第二題的創建我們用第一題來做個模版,選擇question 1層的第一幀,選擇菜單上的Edit>>Copy Frames
再選擇question 2的第十幀,Edit>>Paste Frames 將第一題復制過來了
當然問題要改成"When was MP3 audio support added to Flash?" (什么時候FLASH開始支持MP3格式導入?),答案也要改成Version 3, Version 4, Version 5
數據初試化
雖然是個很簡單的FLASH,但是象其他復雜的FLASH一樣,先告訴FLASH要用到的數據,例如題目的答案等,這是個好習慣,越復雜的FLASH,受惠越多
正常來說定義數據應該LOADING結束之后的。
為了把題目定在第一題,ACTION還需要一句stop();
選擇第一幀,在ACTION面板里面輸入代碼
// init main timeline variables
var q1answer; // user's answer for question 1 第一題用戶的答案
var q2answer; // user's answer for question 2 第二題用戶的答案
var totalCorrect = 0; // counts number of correct answers 答對的題數
var displayTotal; // text field for displaying user's score 顯示用戶分數的變量
// stop the movie at the first question
stop();
你會發現//開頭的那一行代碼都變了色,//代表的是注釋,是用來輔助閱讀代碼用的,對代碼執行沒有影響(是的,你在里面寫笑話,寫小說都可以,不會影響你的FLASH的^-^)
我們定義了四個將要用到的變量,用途已經在注釋里面寫了,寫注釋也是一個好習慣
關于命名變量名
變量起名displayTotal,意思是 display total,因變量名不能使用空格和破折號,所以用第二個單詞的開始字母大寫,以此分隔單詞
一些程序員也喜歡用下劃線:display_total
記住一定要給你的變量起一個一眼就能識別意義的名字
添加label
我們知道第二題是在第10幀的,我們只需要一句AS:gotoAndStop(10); 就可以執行第二個問題了
不過MOOCK告訴你這不是好習慣,因為動畫的內容是不斷改變的,所以我們應當習慣使用label,即使幀數如何變化,只要label指向正確,不需要修改ACTION都可以繼續運行(chocobo再提醒你吧,不要使用相同的label,即使在不同是Scene當中)
好了,我們在label層的第1、10、20分別F6創建要害幀,給他們寫上init、q2、quizEnd
要給按鈕寫上代碼了
在三個按鈕里面分別寫入代碼,大同小異的:
按鈕一:
on (release) {
q1answer = 1;
gotoAndStop ("q2");
}
按鈕二:
on (release) {
q1answer = 2;
gotoAndStop ("q2");
}
按鈕三
on (release) {
q1answer = 3;
gotoAndStop ("q2");
}
這三段代碼用人類的語言描述,就是:當用戶點擊某個按鈕選擇答案后,把他選擇的答案記錄到q1answer變量中去,然后進入下一題。
on這個單詞代表隨后的就是一個要觸發的事件
release是指在按鈕上松開鼠標這樣一個事件
當動畫執行到這里的時候,三個按鈕都會分別監聽用戶有沒有做在按鈕上放開鼠標這個動作,一旦發生,按鈕就會自動執行大括號{}里面的代碼了
若用戶選第一個,{}中是:
q1answer = 1; //用q1answer變量記住用戶選擇的是第一個答案
gotoAndStop ("q2"); //進入下一題
上面我用了注釋的方法來解釋兩句代碼,你必須習慣,因為不是所有源程序都有教程,但是好的源程序都會有注釋
第二題的按鈕與前面相似,只是變量換為q2answer,選擇完進入結束的畫面,例如第一個,改為:
on (release) {
q2answer = 1;
gotoAndStop ("quizEnd");
}
結束的畫面
結束應該做什么,當然是告訴用戶分數啦,寫在第20幀,就是label為quizEnd的那幀的代碼:
// tally up the user's correct answers
if (q1answer == 3){
totalCorrect = totalCorrect 1;
}
if (q2answer == 2){
totalCorrect ; //totalCorrect 其實是totalCorrect = totalCorrect 1;一個更簡潔的寫法,幾乎少打了一半的字母啊。
}
// show the user's score in an on-screen text field
displayTotal = totalCorrect;
用人的語言描述:假如第一題選3,答對數加一,假如第二題選2,答對數加一,把答對題目數賦予另一變量
現在答對的題數是放到變量displayTotal中了,怎么顯示?
在quiz end第20幀處建要害幀,鍵入"Thank you for taking the quiz! Your score final score is: /2"(謝謝回答問題,你最后成績是答對了 /2道題)
在"/2"之前那個空白的地方放上一個文本框,菜單Text>>Options顯示文本面板,把Static Text下拉改為Dynamic Text,順便把Border/Bg的鉤去掉,最后在Variable那一欄填上要顯示的變量名displayTotal
你是不是和chocobo一樣不耐煩了?快下載http://www.moock.org/webdesign/lect...oockQuizzes.zip ;吧,里面的quiz.fla就是本章的內容,其他的fla的內容也將會在后面講到

第六章 再來補充一點AS知識
數據分類是很有必要的,象8005154556這樣的一個數字是沒有多大意義的,但是假如將他歸類到電話號碼:800-515-4556,那就有意義了。(這是WHO的電話啊?是不是MOOCK的?呵呵)
AS里面數據的類型相對其他語言已經算少的,有:
* 字符串String 由一系列的characters組成,可以包含字母,數字和符號,一般用雙引號""擴住(記住不要寫了全角的“”)
* 數字Number
* 布爾值Boolean 用于條件判定的時候,只有兩個值true和false
* Null and Undefined 這也是數據的類型之一,Null代表變量還沒有內容,Undefined是連變量都未定義
* 數組Array 用來按順序地存放一組數據
* MovieClip 這也是數據的一種嗎?你就當它是FLASH特有的一種數據吧,裝的就是一個個MC INSTANCE(解釋一下吧,MC從library拖到場景中就是一個獨立的instance,一個MC可以創立多個instance),還有MC里面的其他數據
* Object 可以是FLASH已經內部定義的,或者是用戶寫程序時自定義的一類數據
再分類一下
number, string, boolean, undefined, and null,這些屬于簡單的數據類型,特征是只有一個值
array, object, movieclip. 就可以包含不止一個值


chocobo:其實array也應該算是object,上面這些概念的東西總是有些沉悶,沒關系,留下印象,以后用到了,自然會回過來真正了解一遍的
第七章 可以重復的函數(function)
不是用幾個例子來示范嗎?怎么還不講例子啊?是的,下一個例子要用到函數,所以再補充點函數知識。(上當了吧?chocobo也上當了,開始翻譯的時候沒想到這篇東西這么長的,這才講完第一個例子呢 55~)
一個函數是下面這個樣子的:
function funcName () {
statements
}
在ACTION面板里面,function這個單詞是變色的,FLASH熟悉這個單詞,它代表后面的就是描述函數的內容
funcName是函數的名字,當你以后要用這函數的時候,就要敲這個名字了(是的,建函數就是為了以后反復調用它)
()小括號里面是參數,什么是參數一會再講
{}大括號里面的就是函數所要完成功能的一句句代碼。
當我們建立函數之后,函數并不運行,只在你用函數的名字調用它出來,才正式開始運行
例如我們有這樣一個函數
function sayHi () {
trace("Hi!");
}
當我們在FLASH某幀需要sayHi的時候,輸入AS:
sayHi();
是不是和最常見的stop();還有play();一樣啊?因為它們都是函數嘛
sayHi函數真是智,來個有意義的函數吧。先在場景里放好一個名字叫ball的instance(千萬記得要給instance輸入名字,否則函數運行沒結果別找我)
在第一幀輸入這樣一個函數:
function moveBall () {
ball._x = 10; // 怕有人不懂,解釋一下,_x代表ball的橫坐標,ball._x =10 的意思是ball._x = ball._x 10 ,這樣省略的寫法還有 -= *= /= 等等
ball._y = 10;
}
再做一個按鈕,按鈕的AS:
on (release) {
moveBall();
}
好的,運行,從AS你可以看到,每點一下按鈕,執行一次函數,而函數讓小球下斜下移動。(FLASH的坐標軸,原點在左上角)
為什么要建立函數呢,就是想更有效率,現在有這個函數已經不用每移動一下寫一次AS了,但還是不夠,我們需要更有擴展性(flexibility)的函數
這個函數只能移動叫ball的MC,只能向固定的方向移動固定的距離,我們需要可以移動任何MC,向任何方向移動任何距離的函數,這樣可以省卻很多輸入AS的工夫(這就叫一勞永逸,呵呵)
我們的新函數有三個地方是每次調用都不一樣的
1、移動的那個MC的名字
2、水平移動的距離
3、垂直移動的距離(呵呵,用極坐標,也可以把2、3說成移動的距離,和移動的角度,不過大家都不習慣極坐標)
為了告訴函數這些變化的地方,我們需要參數(parameters),參數在定義函數的時候就要輸入,我們的函數改寫好了:
function moveClip (theClip, xDist, yDist) {
theClip._x = xDist;
theClip._y = yDist;
}
當我們要實現原來函數功能的時候,現在調用新函數就變成
moveClip (ball, 10, 10);
定義函數的時候function moveClip (theClip, xDist, yDist) {
這里的theClip等參數(parameters)只是定義,本質上說是不存在的,因為沒有內容嘛
當我們用moveClip (ball, 10, 10);調用的時候,ball就輸入到theClip中去了,這里的ball稱為arguments(偶讀得書少,不會翻譯)
arguments可以是一個變量,也可以是一個表達式(例如"a" "b",先得出結果再傳輸給函數)只要用逗號隔開各個參數就行
函數如何結束呢
正常來說,函數運行完 {}里所有語句結束,我們也可以用一句AS:return; 讓它中途結束,例如:
function say(msg) {
return;
trace(msg);
}
這個函數被調用的時候將什么都不做就結束
return還有更重要的用途:
function sqr { // Squares a number 平方
return x * x;
}
a=sqr(2); //a將會被賦予2的平方 4
return更重要的用途就是返回數據
在AS里面,有個內建的函數Math.sqrt(就是說你敲入的時候會變色),其功能和我們剛才做的sqr函數是一樣的,現在你該知道內建函數也沒什么神秘的,我們一樣可以做出相同功能的來。
第八章 第二個版本選擇題的制作
讀到這你發現什么,我是發現了,MOOCK不是在教AS,他簡直是在上編程課。
在第一個版本的制作里你發現了什么缺點?是的,輸入了很多次AS,很麻煩。
我們要做的是用函數來集中我們的代碼,只有集中了才好修改,越復雜的程序越是如此(想象一下在很多個MC之間查代碼,真是頭痛,當然是集中一塊好)
這個多選題,我們就歸結成兩個函數吧answer和gradeUser
代碼(可以直接看源程序,在上面地址那個ZIP里面的quiz-version2.fla):
大部分的代碼都被集中到第一幀了,千萬不要被一大堆代碼嚇著了,代碼這么長,只是為了讓閱讀者看得更清楚而已。(其實越短的代碼才越可怕呢,呵呵)
// 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 這個函數的功能是提交答題者的答案
function answer (choice) {
answer.currentAnswer ;
//現在answer.currentAnswer是1,正在提交的是第一題,下一次answer.currentAnswer就變成2,代表提交的是第二題
set ("q" answer.currentAnswer "answer", choice);
// 不復雜不復雜,"q" answer.currentAnswer "answer"第一題的時候就是q1answer,第二題是q2answer,把參數choice傳過來的值放到兩個變量里面而已
if (answer.currentAnswer == numQuestions) {
// 判定是不是兩題都答完了,是就轉到問題結束幀
gotoAndStop ("quizEnd");
} else {
gotoAndStop ("q" (answer.currentAnswer 1));
}
}
// Function to tally user's score 這個函數是改題的
function gradeUser() {
// Count how many questions user answered correctly 將兩個答案和正確答案比較,對就totalCorrect加一
//此處用了一個for循環,大家如有疑問的,可以查AS字典,在帝國就有中文版
for (i = 1; i <= numQuestions; i ) {
// 下面用的eval有必要說一下,它的作用是將字符串和變量組成一個新的變量名,是個很方便的功能
if (eval("q" i "answer") == eval("correctAnswer" i)) {
totalCorrect ;
}
}
// Show user's score in an on-screen text field 將答案顯示出來,與第一個例子同
displayTotal = totalCorrect;
}
好了,第一幀的函數寫好了,之后每個答案的選擇按鈕就簡單了
例如第一題的選項一,就寫:
on (release) {
answer(1);
}
第二題的寫法同上(假如你的選擇題有很多道,做法都是一樣的,只要復制第一題,然后把題目改了就行)
最后在quizEnd幀里面調用改題的函數gradeUser();
分析第二個例子是代碼,你會發現比第一個例子精簡了很多。
而集中在同一幀的代碼,將:
* 更輕易修改
* 更輕易升級
* 更少的出錯機會
* 更輕易查錯
* 更精簡(更少的字節數)
第九章 數組(arrays)
在下一個新版本的多選題里,我們將使用什么AS的特性,來讓它更好呢?
那就是數組。
數組就是一系列的數據(MOOCK又開始上課了,chocobo的英文和計算機都不算好,為免誤人子弟,概念性的東西盡量精簡)
例如這樣兩個變量儲存的數據:
fruit1 = "oranges";
fruit2 = "apples";
它們是互相獨立的,使用起來很不方便,我們需要的是數組,以下是數組的定義方法,用“&#;”框住,用“,”分隔開每個元素:
fruitList = ["oranges", "apples"];
現在兩個數據是放到同一個數組里面了,我們開始具體解說數組
數組里面每一個數據稱為元素(element)。
而每一個元素都有個獨立數字代表所處的位置,數字叫索引(index),注重! 第一個數據的索引是0,第二個才是1
要按索引來提出數據,我們要用一個運算符&#;,例如使用fruitList第一個元素賦值給a:
a=fruitList&#0;;
又例如將a的值賦給fruitList第一個元素:
fruitList&#0;=a;
當然&#;里面也可以放表達式、變量:
var index = 3;
// Set numApples to 2
var a = fruitList[index];
下面是個使用表達式的例子:
// Create a myFrames array. Note the legal formatting. 建立一個記錄LABEL的數組
var myFrames = ["storyEnding1",
"storyEnding2",
"storyEnding3",
"storyEnding4"];
// Set randomFrame to a randomly picked element of myFrames
// by calculating a random number between 0 and 3
// 隨機從數組中提取一個LABEL
var randomFrame = myFrames[Math.floor(Math.random() * 4)];
// Now go to the random frame
// 然后跳到該LABEL播放
gotoAndStop(randomFrame);
而數組包含數據的個數稱為長度(length),例如fruitList.length 就等于2
對數組最常用的處理就是從數組中選出有用的數據了,來看一個運用循環的例子:
// Create an array 建立數組,里面放了一些歌的類型
var soundtracks = ["electronic",
"hip hop",
"pop",
"alternative",
"classical"];
// Check each element to see if it contains "hip hop"
// 一個循環,檢查每一個元素是否等于"hip hop"這個類型
// 另外,請留意此處MOOCK對FOR的寫法,J=0之前有一個VAR,這好象可有可無,其實是一個好習慣!
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; // 跳出循環,找到了就不用再找了
}
}

關于數組的方法(method)

方法就是從屬于某一對象(object)的函數,通常都是對該對象進行處理的函數
好象太抽象了?我們還沒講到什么是對象,其實數組是對象的一種,我們就暫且將數組的方法理解為一個專門處理數組內數據的結構和內容的工具吧
例如一個叫push()的方法就是一個工具,用于為數組添加一個元素,并且加在該數組的最后
使用起來并不復雜,看例子就知:
// Create an array with 2 elements
var menuItems = ["home", "quit"];
// Add an element 加一個元素
// menuItems becomes ["home", "quit", "products"]
// 現在數組的結構變成["home", "quit", "products"]
menuItems.push("products");
// Add two more elements 這次是加兩個
// menuItems becomes ["home", "quit", "products", "services", "contact"]
menuItems.push("services", "contact");
跟push()相反從最后彈出一個元素的方法是pop()
而跟push()類似,但是是將一個元素加到數組的開頭的方法是unshift(),與之相反的是shift()
方法sort和reverse,用于重新排列數組的元素
方法splice用于從數組中間刪除某元素
方法slice和concat可以在某些數組的基礎上生成另一個新的數組
方法toString和join可以將整個數組變成單一個字符串
以上方法都可以從AS字典里面查到

第十章 第三個版本的選擇題
首先,此版本沿用了上一版本的函數answer和gradeUser
在這一版本中,用戶的答案與正確答案將使用數組來存放
看看我們的新代碼:
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
// 上一版本中,用戶答案使用了兩個變量來存放,但是試想假如是10題、100題呢?使用數組將更輕易治理,也更輕易處理
var userAnswers = new Array(); // Array containing user's guesses 這是定義數組的語句,但是還未輸入數據
var correctAnswers = [3, 2]; // Array containing each correct answer 這一句既定義數組,同時輸入數據,因為正確答案是已知的
// *** Function to register the user's answers
function answer (choice) {
// Tack the user's answer onto our array 將數據PUSH進數組,因為是順序答題,所以用方法PUSH
userAnswers.push(choice);
// Do a little navigation, baby
// 假如答案數超過題目總數,自然就跳到quizEnd幀了
// 注重在本例中,已經不用上例的answer.currentAnswer而是使用userAnswers.length來控制問題是否結束
// 我們甚至可以用correctAnswers.length來代替numQuestions,記錄正確答案數組的長度,不就是題目總數嗎?
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.
// 開始改題,這里就不用再用上個版本的eval啦,那個東東實在是難懂兼難用,這個版本相對就很清楚明快
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;
}
電影的其他部分不用改動(這就是使用FUNTION的好處啦,升級多快~)
OK,進入下一章之前想想目前版本的點
* 題目,每次修改題目都要進入FLASH的場景修改,麻煩
* 按鈕,每題就要做三個按鈕
這都是麻煩的地方,我們要更精益求精地修改,讓我們的多選題,輕易地從兩題變成10題、100題
接下來我們要做的是
* 進一步改進我們存放數據的結構
* 讓我們可以動態地生成每一道題目,只需輸入數據,而不需要在FLASH里面作就可以自動生成
所以——我們需要面向對象編程!(object oriented programming)
chocobo:嘻嘻,眾菜鳥是不是都倒了,AS基礎教程竟然開始講OOP了,呵呵,沒關系啊,上面的教程一直都這么淺,以后也深不了
第十一章 一點面向對象編程知識
At is heart, OOP simply means that you treat portions of your program as self-contained, but interrelating modules called objects.
這是什么呀?我不翻譯了,概念的我們就先不懂吧,對象主要構成包括屬性(properties)和方法(methods)
一個對象通常都以現實世界里的某個東東做藍本
例如我們可以定義一個對象叫球
那么這個球將會有這樣的屬性:半徑、X坐標、Y坐標、顏色
同時,也會用屬于球自己的方法例如:移動球、計算球的面積
當然,我們還可以定義一些相對抽象的對象,例如我們要做的多選題
所有的對象都屬于某類(class),類的意思其實是用于創建對象的模版
一個實例(instance)就是某一個類的特定某一個case(好復雜,概念性的東西我翻不過來啦,反正實例就類創建出來的某一個對象)
還是再舉例吧
* 例如我們有個一個叫Chair的類
* 這個類定義了一個東西需要它有四條腿,一個坐墊
* 然后我們就可以用Chair這個類來定義我們的不同對象(可理解為椅子的款式),每個對象就有它特有的高、寬、材料、重量、顏色,正是這些屬性使每個對象互相區別。
所有的椅子互相區別,有自己的屬性,但是他們又有同樣的結構:四條腿、一個坐墊
OK,那AS里面的類和對象呢?
是的,AS里我們可以自己創建對象,也有可以使用的內建對象
內建的類(你可以用它來創建對象)包括:Array, Boolean, Color, Date, MovieClip, Number, Object, Sound, String, XML, XMLSocket
內建的對象(已經可以直接使用的對象)包括:Arguments, Key, Math, Mouse, Selection
內建的類、對象當然都是在FLASH里面有自己功能的東西。而正是這些功能非經常用,FLASH才內建了這些類和對象,例如:
Mouse.hide(); // Hide the mouse pointer 將鼠標隱藏,你經常用吧?現在才知道其實是內建的Mouse對象的一個hide()方法吧?
在學習如何創建自己的類和對象之前,先來了解一下內建類和對象是怎樣工作的吧
與數組的結構類似,對象是容器們(containers)的容器(container)
一個對象,用各個獨立的屬性來存放數據,只不過數組區分每個容器是用數字,而對象則是用屬性名,要調用一個數組里面某個數據,我們需要它是索引值,而要調用對象的屬性,則要知道屬性名
看看以下這個例子,這是個叫BALL的對象“
BALL對象有兩個屬性:radius 和 color
而兩個屬性分別賦值為:50 和 0xFF0000 (這是AS里面表達16進制的方法)
概念清楚了,說一AS里面使用對象要注重的地方
首先,對象的屬性很靈活,它儲存的數據可以是strings(字符串), numbers(數字), booleans(布爾值), null(空), undefined(未定義), functions(函數), arrays(數組), movie clips(電影夾子), or even other objects(甚至是其他的對象,包括自定義的).
調用屬性,可用點語法:objectName.propertyName
例如我們賦值給BALL里面的屬性radius:
ball.radius = 100;
我們也可以用符號&#;來訪問屬性,但是&#;里面的屬性名需用雙引號擴住,同上例:
ball["radius"] = 100; (所以說數組也是對象一種,訪問方法也一樣,并沒有搞非凡化)
與點語法比較,&#;更靈活,可以動態地改變屬性的名字,里面可以是變量或表達式,例如:
var propName = "radius";
ball[propName] = 100;
這點是點語法無法辦到的
純粹的OOP中,我們幾乎不會直接訪問對象的屬性
我們一般都使用方法(methods) ,來改變屬性
例如改變mySound這個聲音對象的音量屬性
AS的用法應該是mySound.getVolume(100);
而不是mySound.volume=100;
但是為了簡單,多選題這個例子里不一定遵循這個原則,事實上AS里面很多對象都不可以辦到這點,所以有人說AS不是面向對象語言。
關于對象的方法
方法method其實是一些附屬于對象的函數,其作用主要是訪問對象中的數據,或完成某種功能
所以調用方法和調用普通函數類似:objectName.methodName() 只是前面加上了對象的名字
例如上面的BALL對象,我們需要它的面積,使用 getArea 這個方法:
ball.getArea();
預習一下,在下一個例子中,雖然MOOCK不打算建立自己的方法,但是將使用內建于MovieClip對象的兩個方法:
*MovieClip.attachMovie()
此方法是將Library(CTRL L按出來的那個)里面的symbol復制一個instance到場景中
(chocobo:給不懂概念的人緊急補習,放在庫(Library)里面的叫符號(symbol),拉到場景中就叫實例(instance),一個符號可創建多個實例,符號改變則實例隨之改變)
與之類似的是MovieClip.duplicateMovieClip(),但是該方法需要事先在場景里已經有一個實例
*MovieClip.removeMovieClip()
此方法與上面相反,是刪除場景里面的instance的
大家看到了,在下一例中,我們將使用MovieClip這個內建對象,因為它就可以滿足我們的需要,不必新類型的對象了
我們先來熟悉一下MC這種對象
它有很多屬性_height(高度)、 _alpha (透明度),MC的屬性大家可以在AS字典里面查到,在AS面板里這寫屬性也是變色顯示的
同時MC的方法,例如 MC.play(); 等也可以查到
當我們在MC里面的時間線使用這些屬性、方法的時候,可以省略不寫前面部分,直接寫play();
MC可以互相嵌套,MC當中又有MC,就出現類似: mc1.mc2.play(); 的情況
為了調用包含自己的上一級MC的方法、屬性,AS里面用_parent,例如:
在mc1包含mc2 ,在mc2中想使mc1播放:_parent.play();
還有另一個保留字:_root指代該電影的主時間線
例如想在某個mc里面讓整個電影播放:_root.play();
想在某個MC中讓另一mc1播放:_root.mc1.play();
還有,MC中定義的變量,將作為MC的一個屬性可被訪問
在mc1里面寫了一句 var a=1;
我們將可使用 mc1.var來調用它


關于類(class)
這個概念大家還是不大懂吧?類就是定義一個對象將擁有什么的方法跟屬性的東東,類似MC里instance與symbol的關系,instance的結構就是由symbol決定的,每個instance又可以不一樣
AS里面沒有專門定義類的例如class這樣的要害字,我們使用函數來定義類,這種函數稱構造函數constructor function,函數的作用就是產生我們定義好的類的實例(就是對象)
舉例最實在:
// make a Ball constructor 最簡單的構造函數
function Ball () {
// do nothing 里面是空的
}
現在我們可以定義新類型Ball的對象了
myBall = new Ball();
語法就是前面是新對象實例名,等號后是new加構造函數名
myBall就擁有了Ball定義的一切結構了(雖然Ball里面是空的,嘻嘻)
不過不是所有對象創建都用new,例如mc創建就用的是attachMovie()或duplicateMovieClip()
好了,我們的構造函數總不能空的,如何定義類,讓新對象有自己的屬性呢?
使用this這個要害字,看例子,新的構造函數:
function Ball () {
this.radius = 10;
this.color = 0xFF0000;
this.xPosition = 35;
this.yPosition = -4;
}
以后我們定義出來的新對象,都擁有半徑,顏色、XY坐標屬性啦
慢著,怎么每個新對象都一模一樣啊?
再改,用函數的參數來定義動態的屬性:
// 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;
}
我們可以定義不同屬性的對象了
myBall = new Ball(6, 0x00FF00, 145, 200);
本教程關于還有創建方法以及如何在類之間繼續方法和屬性沒講,
無論如何,OOP都不可能在這么短時間之內說清楚,
但這不妨礙我們做下一個例子了。

第十二章 第四個版本的選擇題
第三個版本的時候我們已經設想好,新版本中題目將是動態生成的,不用我們在FLASH的場景里面一題一題輸入了,我們要做的只是輸入題目和題目答案的數據就夠了。
很明顯,每一條題目都將是一個對象(不然我們學這么多對象的知識干嘛?),而這些所有的題目,會用一個數組來存放
再重提一下,可配合源程序學習 http://www.moock.org/webdesign/lect...oockQuizzes.zip ;
好,開始設計題目的模版
模版就是一個MC,包含兩個TEXT FIELD,里面不用填東西,分別起變量名為:(FOR小鳥:TEXT FIELD就是按工具條里T按鈕拉出來的文本框,同時還要在文本面板(ctrl t)里將其改為Dynamic Text,變量名則在面板的Variable處改)
* qNum (以后將顯示題目的編號)
* qText (以后將顯示題目的正文)
我們還要在庫里面做標識,點一庫面板(ctrl l)右上的Options>> Linkage ,選第二個Expert this symbol,identifier填上questionTemplate,至此,題目模版完成
再制作選項的模版
選項模版應包括一個選擇用的按鈕
還有該選項的內容,一個起名為answerText的TEXT FIELD
在本例的后面,將為每一個動態生成的選項一個唯一的名字,譬如: "answer0", "answer1",..."answern".
答題者所選定的答案將由這個名字來決定,調用一個MC的名字,用的是_name這個屬性
所以答題的按鈕上面的AS為:
on (release) {
// Trim the prefix "answer" off this clip's name
// 下面使用了String.slice()方法,例如_name為answer0,它將被處理成0,slice的具體語法請查閱AS字典
// 按鈕提交什么由該MC的名字決定的,我作個標記 @@ ,記得一會看回來
choice = _name.slice(6, _name.length);
// 與前面的例子一樣,最后將答案提交給answer函數處理,不過現在我們是在某一MC里面用外面主時間線的函數了,所以得加上_root
_root.answer(choice);
}
最后,Options>> Linkage,標識名:answerTemplate,制作模版的工作就完成了
下面將是放在第一幀的程序主體,可要打起精神來了:
// 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 記錄作答答案的數組
var userAnswers = new Array();
// Number of the question the user is on 記錄正在作答中題目的編號
// 要注重的是,它是由0開始的,第一題的編號是0,因為我們要用到數組,數組的第一個編號是0,所以這里我們也用0
var currentQuestion = 0;
// The Question constructor
// 以下是新類型對象question的構造函數,包含三個屬性:正確答案,題目正文,各個選項
function Question (correctAnswer, questionText, answers) {
this.correctAnswer = correctAnswer;
this.questionText = questionText;
this.answers = answers;
}
// Import the source file containing our array of question objects
// 咦?應該是輸入各條題目的數據先啊,放哪去了?因為嘛,數據輸入是個與編程無關的過程,為了讓代碼更優雅,這些繁瑣的東西扔別地方去了,AS太長,會使查閱相當麻煩,分開存放也是好習慣!
// #include是引用外部AS命令,可以將AS分開儲存于各個后綴名為AS的文件中,輸入題目的代碼就是放到了questionsArray.as中(記得和FLA放在同一目錄下喔)
#include "questionsArray.as"


//// 我改變了一下教程的結構,把questionsArray.as的內容也插入進來了,因為跳過這段的話,看起來會有疑問
//// 以下內容系存放questionsArray.as中的
// 輸入數據其實是建立對象
// MOOCK用一個數組還存放這些對象,這樣對象才更易于治理
// 不要被括號給弄昏了,輸入對象參數的中間還有中括號,是因為輸入題目的參數“各個選項”是一個數組
// 因為是存放于數組中,每個對象之間記得應有逗號分隔
// 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"])];
//// 離開questionsArray.as部分,我們繼續
// Begin the quiz 出題目!調用makeQuestion函數來完成,我們只需要給這個函數一個參數:題目的編號,函數就會按編號提取數據,結合我們剛才做的模版生成題目。
makeQuestion(currentQuestion);
// Function to render each question to the screen
// 下面就是makeQuestion函數
function makeQuestion (currentQuestion) {
// Clear the Stage of the last question
//這句是清理上一題生成的MC,這句從第二題開始生效,questionClip就是題目的MC名,MC從哪來的?看下面就知道了


questionClip.removeMovieClip();
// Create and place the main question clip
// 利用模版questionTemplate生成一個叫questionClip的MC,這個MC就是我們的問題
attachMovie("questionTemplate", "questionClip", 0);
// 設定MC的位置
questionClip._x = 277;
questionClip._y = 205;
// 把題目編號輸入MC的qNum文本框中
questionClip.qNum = currentQuestion 1;
// questionsArray[currentQuestion]就是數組questionsArray里的第currentQuestion個對象,例如currentQuestion是0,那么就是我們的第一條題目
// questionsArray&#0;.questionText就是第一條題目對象的問題屬性
// 然后問題輸入MC的qText文本框中
questionClip.qText = questionsArray[currentQuestion].questionText;
// Create the individual answer clips in the question clip
// 以下循環將結合選項模版生成這一條題目的各個選項的MC
// questionsArray[currentQuestion].answers記得嗎?選項這個屬性可是個數組,所以我們把它的長度作為循環的次數,這個數組有多大,我們就生成多少個選項
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 ,即第一個選項MC名為answer0,第二個為answer1,選項的名字可是關系到按鈕選什么的,假如你忘了,看看上面有 @@ 標記的地方
// 同時它們的深度為j,每次不同
// 但和上面不同的是,我們要把選項MC生成到題目MC里,這樣我們清除題目MC的同時也清除了選項
// 所以寫成questionClip.attachMovie
questionClip.attachMovie("answerTemplate", "answer" j, j);
// Place this answer clip in line below the question.
// 設定MC的位置,第一個高度為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.
// 下面語句的:questionClip["answer" j]可不是指數組,j=0的時候,它代表questionClip.answer0,具體解釋可見上一章。
// 這句語句的作用是把questionsArray[currentQuestion]這個對象數組里面的answers[j]數組,輸入到對應的選項MC的answerText文本框中,就是該選項的內容
questionClip["answer" j].answerText = questionsArray[currentQuestion].answers[j];
}
//生成選項的循環結束
}
// Function to register the user's answers
// 以下是記錄答題者答案的函數,記錄在數組userAnswers中,和上一例同
// 每一個選項假如被選都會調用此函數,并用參數choice傳來作答的答案
function answer (choice) {
userAnswers.push(choice);
// 判定是否題目全部完成,是的話清楚掉題目MC,并跳轉到quizEnd幀
if (currentQuestion 1 == questionsArray.length) {
questionClip.removeMovieClip();
gotoAndStop ("quizEnd");
} else {
// 在這里改變題目的編號,然后調用makeQuestion函數再次生成新的題目
currentQuestion ;
makeQuestion(currentQuestion);
}
}
// Function to tally the user's score
// 改題的函數
function gradeUser() {
// Count how many questions the user answered correctly
for (var j = 0; j < questionsArray.length; j ) {
// 將答題數組userAnswers[j]與問題數組questionsArray[j]的屬性correctAnswer逐個比較
if (userAnswers[j] == questionsArray[j].correctAnswer) {
totalCorrect ;
}
}
// Show the user's score in an onscreen text field
// 顯示答對與題目數比
displayTotal = totalCorrect "/" questionsArray.length;
}
好了,我們來總結一下這個例子吧
我們已經完成了第三個版本結束時候定下來目標,更快捷的建設,更便易的擴展
我們的題目跟選項都是動態生成的,也就是說生成10、100題或更多題目也只需要修改questionsArray.as這個文件就可以了
假如說生成兩題這個例子用時要長于上面的例子,那么生成100題,你會發現用這個例子將是最快的。還有,在100題里面修改其中一題,也是最快的。
看完了例子,希望大家不是只明白了代碼的含義,最重要是理解運用對象來編程的方法
同樣的例子,其實還可以用其他的對象結構來完成的
更有效地組織數據也是編程藝術的一部分
為了更進一步改進我們的例子,最后一個,就是第五個版本,將用XML代替那個存放對象的數組(也就是在questionsArray.as里那個),它實在太難懂了,是不是啊?呵呵
XML,名字是不是很COOL啊,其實,FLASH里面用XML不難(其他地方的應用就……所以千萬別說XML不難,是FLASH里面用不難),呵呵,好吧,開始吧。

第十三章 XML
XML是一種標記語言,通常用于儲存,組織和傳輸數據
XML文檔主要由一系列的元素(elements)和屬性(attributes)組成,看下面一個XML的例子:
Colin Moock
O'Reilly
這個例子就是由元素 BOOK, TITLE, AUTHOR, PUBLISHER 組成的
在元素里就包含了一個屬性:SALUTATION
這些元素怎么讓瀏覽器解釋是什么意思呢?它需要DTD,一套決定這些標記的意義的規則。(例如我們常聽說的WML、SVG,它們都是XML,但對應不同的DTD)
XML與HTML想比要求格式更嚴格,格式要求:
* tags 一定要嵌套 (就是說有就一定要有)
* 一定要有一個根元素 (例如例子中的 BOOK)
* 開始部分要用XML聲明標記 :
但是AS里面的XML不需要DTD(這就是我說FLASH里面用XML不難的原因,哈哈)
從我們面向對象的角度來看,我們XML的內容可以當做為對象,下圖就是我們建立XML對象的層次結構
FLASH已經內建有XML類讓我們可以定義自己的XML對象,同時XML對象還有很多方法。
我們還是更進一步用例子分析吧,假如我們建立了如上圖的XML對象,那么FLASH首先會自動建立一個元素document.下面才是我們自己的元素。
本來是第一個元素的BOOK成為了document.第一個節點(node),不過我們把它繼續當我們XML數據的根也無妨
當一個節點包含于另一個節點時,這個節點稱為另一節點的子節點(child),反之另一節點稱為其的父節點(parent)
例子中BOOK就是document.child,document.是BOOK的parent
再看圖,BOOK有7個子節點,是不是和你想象不同?多了四個節點#text,因為FLASH把標記之間的空格和回車也讀成一個節點了。
幾個子節點的關系成為兄弟(siblings),假如要找AUTHOR的下一個兄弟(next sibling),FLASH就會給你找來#text
這可不是我們想要的,解決的方法
* 直接在XML里面把空格回車都刪除掉,就是說一個TAG緊挨著一個
* 用AS把無用的子節點刪除
* 在FLASH讀入XML源數據之前,將該XML對象的一個屬性ignoreWhite設置為true,但是該屬性只在R41版本的PLAYER生效(注:網上可以更新的版本為R41,但是隨FLASH附帶的FLASHPLAYER的版本是R30)
再回到我們的例圖,三個子節點下面還有子節點,最尾的節點也可以叫葉節點。
但是圖里面還有個東西我們沒找到,就是AUTHOR的屬性SALUTATION,屬性不是該節點的子節點,要訪問我們屬性,要用XML.attributes
概念先說這么多,現在看看我們怎么把XML源程序輸入進FLASH
首先定義一個新的XML對象了:
mydocument.nbsp= new XML();
這個對象是空的,我們通過appendChild, par***ML, 和 load 三種方法來輸入數據
當然我們也可以在定義的時候就輸入數據:mydocument.nbsp= new XML('
hello world!
');
這時候我們的mydocument.有了一個叫P的子節點,P的葉節點是hello world!
之后我們就可以訪問這個XML對象了,firstChild這個XML屬性指向第一個子節點,childNodes是XML對象的子對象,指向所有的子節點
mydocument.firstChild // Accesses P
mydocument.childNodes&#0; // Also accesses P 兩個AS語句指向的都是節點P
要訪問葉節點的內容需要屬性nodevalue
我們要顯示P節點的子節點的內容,就要寫成:trace(mydocument.firstChild.firstChild.nodevalue);
要給它賦值:
mydocument.firstChild.firstChild.nodevalue = "goodbye cruel world";
要刪除P節點,用方法removeNode:
mydocument.firstChild.removeNode();
新建一個節點叫P,用方法createElement創建元素:
newElement = mydocument.createElement("P");
再將該元素加進去作為一個節點,用方法appendChild:
mydocument.appendChild(newElement);
做一個葉節點方法類似:
newText = mydocument.createTextNode("XML is fun");
mydocument.firstChild.appendChild(newText);
更詳盡的方法還是查閱AS字典吧.
第十四章 最后一個版本選擇題
上一個版本面向對象的代碼對我們這個基于XML的版本很有幫助,上一個版本我們是用對象的數組來存我們的數據,這個版本里面,我們使用外部的XML文件
下面先看看XML文件的結構:
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
這個XML里面,QUIZ是我們的根元素
每一題都放在QUESTION元素內,題目正文為其屬性TEXT,正確答案為其屬性ANSWER(ANSWER=1代表選第二個答案)
每一題的選項則是QUESTION的子節點CHOICE
其實根本就不用解釋,大家直接看都能看懂
使用了外部XML之后,我們升級題目只需改動XML文件即可,而上一個版本,修改外部AS文件之后還是需要EXPORT一次。
這個版本里面,將保留上個版本大部分的代碼,除了輸入題目數據的部分,將用XML來代替。


以下代碼寫到questionsArray.as中覆蓋其原來內容
首先仍然定義一個數組來存放數據
var questionsArray = new Array();
然后我們定義一個XML對象來存放XML數據
var quizDoc = new XML();
之后是建立將XML解釋為我們存放題目的對象格式的函數buildQuestionsArray(),同時將它連接到新建的XML對象的onLoad函數,讓XML下載完成之后執行這個函數
quizDoc.onLoad = buildQuestionsArray
然后是執行下載XML的AS
quizDoc.load("quiz.xml");
最后我們具體解說一下解釋XML的函數
// *** builds an array of question objects based on the dom tree in quizDoc
function buildQuestionsArray () {
// first, strip unwanted whitespace nodes from the tree.
// 除去無用的節點,上一章已經有介紹無用節點是如何出現的
stripWhitespaceDoublePass(quizDoc);
// now assign a convenient reference to the root QUIZ node
// XML文件的根節點QUIZ節點就是 quizDoc.childNodes ,這里將其指名為quizNode,以便運用
var quizNode = quizDoc.childNodes
// for each question node that is a child of the QUIZ node...
// 下面的循環將逐個提取QUIZ節點的子節點,即每條題目
for(var k = 0; k < quizNode.childNodes.length; k ) {
// make an array of the text nodes from each CHOICE node
// 為每條題目建立一個選項數組
var choicesArray = new Array();
// 下面的循環則是將題目的子節點,即各選項的nodevalue輸入到choicesArray數組中
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
// 用題目正文、選項數組、正確答案(正確答案目前還是字符串,所以用Number函數將之轉為數字)作為參數,建立Question對象(定義Question對象的代碼已經在上個例子中解釋了)
// 將新建的Question對象作為questionsArray數組的一個元素
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
// 調用函數makeQuestion,之后的進度就同上一個例子了
makeQuestion(currentQuestion);
}
// *** Strips whitespace nodes from an XML document. // *** by passing twice through each level in the tree
// 下面函數用于除去無用的空白節點,參數是需要處理的XML的根元素(我們已經將其指名為XMLnode了)
function stripWhitespaceDoublePass(XMLnode) {
// Loop through all the children of XMLnode
// 循環依次將根元素的子元素提取出來
for (var k = 0; k < XMLnode.childNodes.length; k ) {
// If the current node is a text node...
// 假如該節點是一個文本節點,就開始以下檢查 ...
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).
// 因為空格、TAB或換行等空白無意義字符的ASCII碼都小于32,檢查若大于32,即為有數據的節點,同時用break;跳出檢查的循環
if(XMLnode.childNodes[k].nodevalue.charCodeAt(j) > 32) {
emptyNode = false;
break;
}
}
// If no useful charaters were found, delete the node.
// 若該節點沒有數據,就是解釋時的錯誤,將其刪除
if(emptyNode) {
XMLnode.childNodes[k].removeNode();
}
}
}
// Now that all the whitespace nodes have been removed from XMLnode,
// call stripWhitespaceDoublePass on its remaining children.
// 但是還沒完,我們只檢查了所有子節點,而沒有檢查子節點的子節點,所以以下的循環將所有子節點也送到本函數再繼續檢查
// 這種函數自己調用自己的方法,稱為遞歸,它將一直檢查子節點的子節點的子節點的……一直到該節點沒有子節點為止
for(var k = 0; k < XMLnode.childNodes.length; k ) {
stripWhitespaceDoublePass(XMLnode.childNodes[k]);
}
}
現在,我們可以把SWF和XML組成的題目交給一個不會編FLASH的老師了,他只要就會用記事本修改XML文件就行了。

分享:Flash關于格斗動畫的動作創作過程
第二課-動作制作-1由于內容較多,請靜下心來好好閱讀,并且結合操作,步驟緊湊一個都不能遺漏!請確定你已經很好的閱讀了第一課的理論基礎,然后保留適當的概念

來源:網頁教學網//所屬分類:Flash教程/更新時間:2008-03-05
相關Flash教程
欧美色图亚洲自拍| 日韩经典一区二区三区| 91精品在线国产| 性鲍视频在线观看| 懂色av蜜臀av粉嫩av分享吧| 国产农村妇女毛片精品久久莱园子| 欧美性生交xxxxxdddd| 国产精品白丝jk喷水视频一区| 午夜激情在线观看视频| 国产视频一区二区三| 亚洲经典视频在线观看| 色婷婷综合视频在线观看| 成人夜晚看av| 午夜一区二区三区免费| av在线一区不卡| 国产精品91一区二区| 亚洲人成人99网站| 国产一二三四区在线观看| 久久久久99精品成人片我成大片| 久久视频精品| 精品成人在线视频| 成人黄色网免费| 国产精品福利导航| 欧美日本三级| 国产亚洲精品aa| 久久久久久免费精品| 99re精彩视频| 精品国产第一福利网站| 国产69精品久久久久毛片| 亚洲性生活视频在线观看| 特级西西444| 怡红院男人的天堂| 亚洲麻豆一区| 日韩网站在线看片你懂的| 奇米影视首页 狠狠色丁香婷婷久久综合| 亚洲欧美精品aaaaaa片| 成人看的羞羞网站| 都市激情亚洲色图| 99九九视频| √天堂中文官网8在线| 国产真实有声精品录音| 欧美日韩国产一区二区| 91久久爱成人| 黄视频网站免费看| 欧美好骚综合网| 欧美性色欧美a在线播放| 精品一区二区日本| 精品无码久久久久久久| 久久久久亚洲| 欧美男同性恋视频网站| 视频一区二区在线| 成年人视频免费| 亚洲欧美日韩专区| 日韩va亚洲va欧洲va国产| 黄色一级片av| 国产哺乳奶水91在线播放| 免费的成人av| 在线播放日韩av| 香蕉视频网站入口| 超薄肉色丝袜脚交一区二区| 2024国产精品视频| 欧美一区二区影院| 日韩在线免费观看av| 免费欧美一区| 日本电影亚洲天堂一区| 欧洲精品国产| 又色又爽又黄无遮挡的免费视频| 日产欧产美韩系列久久99| 亚洲一级一级97网| 黄色片在线免费| 成人午夜在线| 综合欧美一区二区三区| 亚洲综合中文字幕在线| 激情五月婷婷小说| 亚洲精品男同| 亚洲欧美一区二区三区久久| 国产精品涩涩涩视频网站| 免费高清视频在线一区| 中文字幕亚洲精品在线观看 | 色欲av永久无码精品无码蜜桃| 国产九九视频一区二区三区| 欧美激情视频网| 国产+高潮+白浆+无码| 色哟哟精品丝袜一区二区| 一本久道中文字幕精品亚洲嫩| 日韩av高清| 一级黄色免费片| 国产精品1024| 欧洲成人免费视频| 色噜噜噜噜噜噜| 欧美精品国产一区| 日韩成人中文字幕在线观看| 欧洲熟妇精品视频| 欧美日韩国产一区二区在线观看| 午夜精品免费在线观看| 日本高清不卡一区二区三| 亚洲一级特黄毛片| 成人精品一区二区三区中文字幕| 欧美亚洲一级片| xxxxx99| 亚洲国产电影| 国产亚洲精品久久久| 一级黄色免费毛片| 国产一区二区三区探花| 日韩欧美一区二区三区在线| 人妻熟女一二三区夜夜爱| 欧美xxxx网站| 天天综合色天天综合| 伊人天天久久大香线蕉av色| 天天综合永久入口| 亚洲四区在线观看| 欧美日韩最好看的视频| 99视频免费看| 国产精品欧美极品| 精品欧美日韩| www.99视频| 国产精品污污网站在线观看| 国产色综合一区二区三区| 中文字幕人妻一区二区三区视频| av一本久道久久综合久久鬼色| 国产精品一区二区三区成人| 亚洲国产成人精品激情在线| 国产乱码精品一区二区三区av| 国产国语刺激对白av不卡| 免费日韩在线视频| 久久精品免费观看| 人人澡人人澡人人看欧美| 欧美片一区二区| 极品美女销魂一区二区三区免费| 欧美孕妇性xx| 黄色一级片免费看| 高清av一区二区| 亚洲一区二区三区久久| 中文字幕福利视频| 久久精品视频在线免费观看 | 国产一级在线播放| 国产一区二区免费看| 国产精品一区二区久久精品| 日韩在线播放中文字幕| 91在线porny国产在线看| 91手机在线观看| 国产精品久久久久久久免费| 国产精品拍天天在线| 日韩色妇久久av| 日本成人伦理电影| 日韩欧美国产激情| 无码精品a∨在线观看中文| 国产香蕉精品| 亚洲激情第一页| 天堂va欧美va亚洲va老司机| 欧美激情视频一区二区三区免费| 播播国产欧美激情| 欧美性生交大片| 蜜桃视频在线一区| 国产欧美最新羞羞视频在线观看| 天天爽夜夜爽人人爽| 久久男人中文字幕资源站| 久久精品日韩精品| 天天干天天色天天| 欧美日韩免费看| 国产中文字幕免费观看| 亚洲尤物av| 亚洲网在线观看| 亚洲欧美va天堂人熟伦| 热久久免费视频| 国产精品一区二区三区成人| 国产精品国产av| 一区二区三区蜜桃| 人妻少妇精品久久| 伊人久久大香线蕉无限次| 国产午夜精品全部视频播放 | 日韩大陆av| 制服丝袜亚洲网站| 手机在线播放av| 日韩视频在线一区二区三区 | 一区二区三区中文字幕精品精品 | 亚洲精品二区| 韩国三级大全久久网站| 日韩美女在线视频| 中文字幕xxx| 久久狠狠亚洲综合| 95av在线视频| 欧美一级特黄aaaaaa| 欧美久久九九| 欧美美女15p| 黄色小视频在线免费看| 久久综合久久综合久久| 亚洲国产精品www| 榴莲视频成人app| 亚洲第一偷拍网| 一区二区精品免费| 国产一区二区三区av电影| 国产另类第一区| 成人全视频免费观看在线看| 日韩视频中午一区| 亚洲国产欧美视频| 韩国成人福利片在线播放| 国产美女精品在线观看| 主播大秀视频在线观看一区二区| 欧美一级免费大片| 中文字幕国产综合| 国产乱人伦精品一区二区在线观看| 精品视频在线观看| 国产日韩欧美中文在线| 日韩国产精品一区| 中文字幕五月天| 国产亚洲欧洲997久久综合| 综合国产精品久久久| 精品中文一区| 精品自拍视频在线观看| 波多野结衣视频网址| 亚洲成人免费影院| 一级黄色录像在线观看| 亚洲综合社区| av资源站久久亚洲| 国产精品亚洲成在人线| 国产视频久久久久| 青娱乐免费在线视频| 国产欧美日韩另类视频免费观看| 亚洲色成人www永久在线观看| 日韩视频在线观看| 青青a在线精品免费观看| www香蕉视频| 欧美精品v国产精品v日韩精品| 成人免费av片| 99久久er热在这里只有精品15| 欧美少妇在线观看| 日韩在线观看一区| 国产成人亚洲综合| 性xxxx视频播放免费| 日韩女优制服丝袜电影| 午夜三级在线观看| 中文字幕av免费专区久久| 欧美日韩在线中文| 99精品欧美| 国产精品嫩草在线观看| 视频一区日韩精品| 美女撒尿一区二区三区| 国产精品高潮呻吟久久久| 欧美日产在线观看| jizz18女人高潮| 国产欧美一二三区| 久久久久久久久久福利| 久久久久久一区二区| 美乳视频一区二区| 日本欧美高清| 欧美综合激情网| xxxxx性欧美特大| 精品视频在线观看日韩| 国产精品老女人| 日韩欧美国产高清91| 激情综合丁香五月| 久久综合九色综合欧美98| 91av资源网| 日韩专区一卡二卡| 秋霞在线观看一区二区三区| 久久av免费| 日本国产一区二区三区| av激情成人网| 日韩在线观看免费全| aaa级黄色片| 欧美精品一区二区三区蜜桃 | 精品国产免费av| 肉色丝袜一区二区| 亚洲午夜激情| 欧美国产高清| 成人资源视频网站免费| 精品久久ai电影| 日本欧美爱爱爱| 岛国一区二区| 久久夜色撩人精品| 高潮一区二区三区乱码| 亚洲欧美日韩精品久久| 中国一级片黄色一级片黄| 6080午夜不卡| 精品亚洲永久免费| 日韩欧美在线观看视频| 欧美xxxx精品| 亚洲自拍偷拍图区| 国产三级视频网站| 国产亚洲一区二区在线观看| 不卡中文字幕在线观看| 高清在线观看日韩| 欧美韩国日本在线| 精品一区二区在线播放| 污污污污污污www网站免费| 国产精品社区| 中文字幕中文字幕在线中一区高清 | 97久久综合精品久久久综合| 2025国产精品视频| 欧美天堂一区| 久久久久久久国产精品视频| 91tv亚洲精品香蕉国产一区| 美女视频久久黄| 在线看欧美视频| 久久91亚洲精品中文字幕| 三级成人黄色影院| 美女精品视频一区| 日韩在线短视频| 欧美疯狂做受xxxx高潮| 成人自拍视频网| 国模精品系列视频| 国内自拍亚洲| 欧洲日韩成人av| www.久久热| 青青草国产精品一区二区| 中文字幕一区图| 国产精品你懂得| 图片婷婷一区| 国产传媒一区| 欧美好骚综合网| 日本不卡一区| 亚洲精品美女91| 红桃一区二区三区| 久久成人免费日本黄色| 黄色a级片免费| 国产91精品欧美| 911福利视频| 久久免费视频色| 亚洲av永久无码精品| 亚洲精品一卡二卡| 日韩精品电影一区二区三区| 欧美午夜影院在线视频| 久久久久亚洲av无码专区| 欧美男女性生活在线直播观看| 一级黄色av片| 亚洲男人av在线| 少妇一区二区三区四区| 久久99精品久久久久久噜噜| 色诱色偷偷久久综合| 国产suv精品一区二区| 欧美日韩另类图片| 国产伦精品一区二区三区在线| 亚洲综合激情在线| 中文字幕日韩精品一区二区| 蜜桃av噜噜一区| 亚洲三级视频网站| 久久九九国产精品| 国产偷人妻精品一区| 精品久久久久久中文字幕| 国产精品suv一区二区69| 欧美大片免费久久精品三p| a天堂视频在线| 美女av一区二区| 天堂va在线高清一区| 99一区二区| 亚洲第一精品影视| 欧美午夜小视频| 99久久国产综合精品色伊| 日批在线观看视频| 欧美日韩国产色视频| 国产又粗又爽视频| 亚洲深夜福利在线| yy6080久久伦理一区二区| 国产精品免费在线免费 | 男人透女人免费视频| 91亚洲精品久久久蜜桃网站 | 日韩 欧美一区二区三区| 白嫩少妇丰满一区二区| 久久精品视频免费| 变态另类ts人妖一区二区| 欧美三级中文字幕在线观看| 一区二区三区免费在线| 久久综合久久美利坚合众国| 亚洲午夜精品| 精品国产综合久久| 欧美在线综合| www.99在线| 亚洲免费资源在线播放| 久久亚洲精品大全| 亚洲精品suv精品一区二区| 成人小电影网站| 国产精品永久免费视频| 亚欧美无遮挡hd高清在线视频| 韩国无码av片在线观看网站| 99久精品国产| 麻豆视频免费在线播放| 欧美一区二区三区在线看| www黄色在线观看| 91爱视频在线| 99国产精品免费视频观看| 裸体大乳女做爰69| www.欧美.com| 精品无码国产污污污免费网站| 91精品一区二区三区在线观看| 性欧美videos另类hd| 奇米影视亚洲狠狠色| 91亚洲国产高清| 国产 欧美 日韩 一区| 久久精品亚洲精品国产欧美| av最新在线观看| 日韩电影中文字幕在线观看| 欧美美女福利视频| 国产富婆一区二区三区| 日韩精品亚洲一区| 久久久精品人妻一区二区三区| 色综合天天综合网天天狠天天| 国产精品综合在线| 国产91色在线| 国内精品久久久久久久97牛牛 |