Flash游戲編程之地圖布置與地圖相關(guān)算法_第1頁
Flash游戲編程之地圖布置與地圖相關(guān)算法_第2頁
Flash游戲編程之地圖布置與地圖相關(guān)算法_第3頁
Flash游戲編程之地圖布置與地圖相關(guān)算法_第4頁
Flash游戲編程之地圖布置與地圖相關(guān)算法_第5頁
已閱讀5頁,還剩28頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、Flash游戲編程游戲編程肖肖 剛剛閩江學(xué)院電子系計算機教研室閩江學(xué)院電子系計算機教研室Email:第六章第六章 地圖布置與地圖相關(guān)算地圖布置與地圖相關(guān)算法法 教學(xué)提要游戲地圖的組成方式游戲地圖的組成方式幾種常用的地圖編碼方式幾種常用的地圖編碼方式掃雷游戲的編碼與算法的實現(xiàn)掃雷游戲的編碼與算法的實現(xiàn)掌握掌握Flash游戲中的地圖編碼及其算法游戲中的地圖編碼及其算法1 游戲地圖的組成方式游戲地圖的組成方式地圖是許多游戲的重要組成。小游戲例如俄羅斯方塊、地圖是許多游戲的重要組成。小游戲例如俄羅斯方塊、各種棋類游戲、搬運工游戲等,大型游戲例如英雄無各種棋類游戲、搬運工游戲等,大型游戲例如英雄無敵、魔

2、獸爭霸,無不與地圖緊密關(guān)聯(lián)。敵、魔獸爭霸,無不與地圖緊密關(guān)聯(lián)。地圖的組成:地圖的組成:地圖元件地圖元件編碼數(shù)據(jù)編碼數(shù)據(jù)基于編碼的算法基于編碼的算法右圖是一款用右圖是一款用 Flash制作的滾制作的滾 方塊游戲方塊游戲:1.1 地圖的組成地圖的組成其地圖(即游戲中的地板方塊組合)的三個部分分為其地圖(即游戲中的地板方塊組合)的三個部分分為為:為:地圖元件:地圖元件:一個個的小地磚對象,他們都是同一個類的實例,只是一些屬性一個個的小地磚對象,他們都是同一個類的實例,只是一些屬性值(如位置,顯示效果和編碼值)不同而已。值(如位置,顯示效果和編碼值)不同而已。編碼數(shù)據(jù):編碼數(shù)據(jù):顯然這個地圖應(yīng)該采用二

3、維數(shù)組進行編碼。在一個顯然這個地圖應(yīng)該采用二維數(shù)組進行編碼。在一個M*N的二維的二維數(shù)組中,數(shù)組中,1表示有地磚,表示有地磚,0表示沒有地磚,就可以準(zhǔn)確無誤地表表示沒有地磚,就可以準(zhǔn)確無誤地表示出這個地圖的實際情況。示出這個地圖的實際情況。基于編碼的算法:基于編碼的算法:根據(jù)編碼數(shù)據(jù)創(chuàng)建地磚實例并平鋪在舞臺上就是一個算法,這是根據(jù)編碼數(shù)據(jù)創(chuàng)建地磚實例并平鋪在舞臺上就是一個算法,這是具有整齊排列特征的地圖常用的做法。具有整齊排列特征的地圖常用的做法。先獲得方柱所在的位置編碼,根據(jù)編碼在地圖編碼數(shù)據(jù)中判斷這先獲得方柱所在的位置編碼,根據(jù)編碼在地圖編碼數(shù)據(jù)中判斷這個位置的值是否都為個位置的值是否都為

4、1,如果是,就表示這個方柱是,如果是,就表示這個方柱是“穩(wěn)固穩(wěn)固”的,的,否則就是否則就是“不穩(wěn)不穩(wěn)”的,這就是一個簡單的基于編碼的算法的描述,的,這就是一個簡單的基于編碼的算法的描述,它用來支持游戲的運行邏輯。它用來支持游戲的運行邏輯。2 幾種常用的地圖編碼方式幾種常用的地圖編碼方式 地圖元件的制作采用角色設(shè)計思想進行設(shè)計即可。所地圖元件的制作采用角色設(shè)計思想進行設(shè)計即可。所以地圖設(shè)計的一個關(guān)鍵就是進行地圖編碼。以地圖設(shè)計的一個關(guān)鍵就是進行地圖編碼。地圖編碼的作用:在地圖元件與算法之間建立一個最地圖編碼的作用:在地圖元件與算法之間建立一個最簡的溝通橋梁。簡的溝通橋梁。基于編碼方式設(shè)計算法,然

5、后通過編碼找到對應(yīng)的元件;基于編碼方式設(shè)計算法,然后通過編碼找到對應(yīng)的元件;從元件出發(fā)獲取其編碼值,然后用這個編碼值參與算法過程。從元件出發(fā)獲取其編碼值,然后用這個編碼值參與算法過程。例如:掃雷游戲,可以建立一個二維數(shù)組,每個數(shù)據(jù)項存儲例如:掃雷游戲,可以建立一個二維數(shù)組,每個數(shù)據(jù)項存儲一個方塊的引用,這樣二維數(shù)組就是游戲的編碼方式。然后一個方塊的引用,這樣二維數(shù)組就是游戲的編碼方式。然后基于二維數(shù)組索引(即數(shù)組的下標(biāo))找到每個方塊,同時,基于二維數(shù)組索引(即數(shù)組的下標(biāo))找到每個方塊,同時,在每個方塊中定義變量在每個方塊中定義變量indexX和和indexY,用于記錄其索引,用于記錄其索引值,

6、當(dāng)點擊了某個方塊之后,可通過讀取這個方塊的索引值值,當(dāng)點擊了某個方塊之后,可通過讀取這個方塊的索引值來確定它在二維數(shù)組中的位置。來確定它在二維數(shù)組中的位置。好的地圖編碼算法應(yīng)該是既滿足記錄數(shù)據(jù)的需要,又好的地圖編碼算法應(yīng)該是既滿足記錄數(shù)據(jù)的需要,又是最簡的。是最簡的。 2.1 常見的地圖編碼方式常見的地圖編碼方式一維數(shù)組(隊列,堆棧)一維數(shù)組(隊列,堆棧)例如開心碎碎冰游戲例如開心碎碎冰游戲2.2 常見的地圖編碼方式常見的地圖編碼方式二維數(shù)組二維數(shù)組例如炸方塊游戲例如炸方塊游戲 2.3 常見的地圖編碼方式常見的地圖編碼方式變形的二維數(shù)組編碼方式變形的二維數(shù)組編碼方式 例如蜂窩狀地圖,這樣的地圖

7、每個格子有六例如蜂窩狀地圖,這樣的地圖每個格子有六個方向的通路。也有可能是菱形或者六邊形,個方向的通路。也有可能是菱形或者六邊形,如下圖所示如下圖所示:2.4 常見的地圖編碼方式常見的地圖編碼方式完全可以參考二維方陣的編碼方法。上面兩張圖,可以分別編碼完全可以參考二維方陣的編碼方法。上面兩張圖,可以分別編碼成成4*8和和7*7的方陣。的方陣。如下圖所示:如下圖所示:于是我們又可以用一個二維數(shù)組保存地圖信息了。基于不同的編于是我們又可以用一個二維數(shù)組保存地圖信息了。基于不同的編碼規(guī)則,就要使用不同的算法規(guī)則。例如采用菱形邊編碼規(guī)則,碼規(guī)則,就要使用不同的算法規(guī)則。例如采用菱形邊編碼規(guī)則,那么當(dāng)考

8、察第那么當(dāng)考察第i行第行第j列位置的通路時,需要判斷的六個位置的編列位置的通路時,需要判斷的六個位置的編碼如下圖所示:碼如下圖所示:2.5 常見的地圖編碼方式常見的地圖編碼方式非二維陣列地圖的陣列化非二維陣列地圖的陣列化事實證明,二維陣列是游戲地圖非常簡單、非常有用的編碼與索引方式。如事實證明,二維陣列是游戲地圖非常簡單、非常有用的編碼與索引方式。如果可能,應(yīng)盡量采用陣列編碼,以便獲得陣列計算的簡單性。例如九子游戲,果可能,應(yīng)盡量采用陣列編碼,以便獲得陣列計算的簡單性。例如九子游戲,每個位置的編碼不僅要起到互相區(qū)分的作用,還要能夠以此判斷棋子之間是每個位置的編碼不僅要起到互相區(qū)分的作用,還要能

9、夠以此判斷棋子之間是否同在一條連線上。如果僅是從上到下,從左到右對位置逐個編碼,則難以否同在一條連線上。如果僅是從上到下,從左到右對位置逐個編碼,則難以實現(xiàn)同線判斷。但事實上,這個地圖還是有規(guī)律可循的,可以將地圖理解成實現(xiàn)同線判斷。但事實上,這個地圖還是有規(guī)律可循的,可以將地圖理解成是一個二維陣列上分布的點。這樣我們又可以使用二維數(shù)組來存儲索引每個是一個二維陣列上分布的點。這樣我們又可以使用二維數(shù)組來存儲索引每個位置單元了,此時同線與否就再明顯不過了。位置單元了,此時同線與否就再明顯不過了。 2.6 常見的地圖編碼方式常見的地圖編碼方式用圖進行地圖編碼用圖進行地圖編碼 圖是一種數(shù)據(jù)結(jié)構(gòu),它指出

10、了每個節(jié)點的信圖是一種數(shù)據(jù)結(jié)構(gòu),它指出了每個節(jié)點的信息以及它的相鄰點。息以及它的相鄰點。假如游戲中有如下的一張地圖:假如游戲中有如下的一張地圖: 由于其連線的不規(guī)則性,不能采用簡單的陣由于其連線的不規(guī)則性,不能采用簡單的陣列化編碼。列化編碼。2.6 常見的地圖編碼方式常見的地圖編碼方式方法是先對位置按順方法是先對位置按順序編碼,如下圖所示:序編碼,如下圖所示:然后記錄每個節(jié)點的然后記錄每個節(jié)點的相鄰節(jié)點,如右表所相鄰節(jié)點,如右表所示:示:這樣就可以既簡單又這樣就可以既簡單又完全地表示這張地圖。完全地表示這張地圖。節(jié)點編碼節(jié)點編碼相鄰節(jié)點相鄰節(jié)點01,2,310,2,4,520,1,3,530,

11、2,5,641,5,751,2,3,4,6,763,5,774,5,62.7 常見的地圖編碼方式常見的地圖編碼方式可以用一個一維數(shù)組存儲位置數(shù)據(jù),用一個二可以用一個一維數(shù)組存儲位置數(shù)據(jù),用一個二維數(shù)組表示位置之間的連線。維數(shù)組表示位置之間的連線。示例代碼如下:示例代碼如下:/棋子信息,棋子信息,0表示沒有棋子,表示沒有棋子,1表示白棋,表示白棋,2表示黑棋表示黑棋var chesses=new Array(0,0,1,1,2,2,0,0);var path = new Array(8);path 0 = new Array(1,2,3);path 1 = new Array(0,2,4,5);

12、path 2 = new Array(0,1,3,5);path 3 = new Array(0,2,5,6);path 4 = new Array(1,5,7);path 5 = new Array(1,2,3,4,6,7);path 6 = new Array(3,5,7);path 7 = new Array(4,5,6); 2.7 常見的地圖編碼方式常見的地圖編碼方式使用這種編碼方式的好處是計算相鄰棋子非常使用這種編碼方式的好處是計算相鄰棋子非常方便,例如下面的代碼判斷指定位置是否有指方便,例如下面的代碼判斷指定位置是否有指定一方的棋子相鄰:定一方的棋子相鄰:function have

13、Neighbor(position:int,color:int):Boolean for (var i = 0; ipathposition.length; i+) if (ppathpositioni = color) return true;return false; 小結(jié)小結(jié)元件是游戲地圖的展現(xiàn),編碼是游戲地圖的元件是游戲地圖的展現(xiàn),編碼是游戲地圖的結(jié)構(gòu),算法是地圖功能的實現(xiàn)。結(jié)構(gòu),算法是地圖功能的實現(xiàn)。地圖編碼以簡單有效為設(shè)計準(zhǔn)則。地圖編碼以簡單有效為設(shè)計準(zhǔn)則。不管使用何種編碼方式開發(fā)游戲,最好都先不管使用何種編碼方式開發(fā)游戲,最好都先畫好編碼圖,甚至打印出來放在電腦旁以便畫好編碼圖,

14、甚至打印出來放在電腦旁以便隨手翻閱。隨手翻閱。2.8 常見的地圖編碼方式常見的地圖編碼方式3 掃雷游戲的編碼與實現(xiàn)掃雷游戲的編碼與實現(xiàn) 內(nèi)容包括:內(nèi)容包括:編碼與索引編碼與索引 布置雷區(qū)布置雷區(qū) 隨機分布地雷隨機分布地雷 計算單元格周圍雷數(shù)計算單元格周圍雷數(shù) 無雷區(qū)自動擴張的設(shè)計無雷區(qū)自動擴張的設(shè)計 判斷地雷是否已經(jīng)全部掃除判斷地雷是否已經(jīng)全部掃除 人機交互部分的設(shè)計人機交互部分的設(shè)計 設(shè)置難度級別設(shè)置難度級別 游戲結(jié)束時顯示所有地雷游戲結(jié)束時顯示所有地雷3.1 方塊角色的設(shè)計方塊角色的設(shè)計很明顯,掃雷游戲很明顯,掃雷游戲中的每一個方格,中的每一個方格,都是一個雷區(qū)單元都是一個雷區(qū)單元角色的實

15、例。這個角色的實例。這個雷區(qū)單元應(yīng)該包含雷區(qū)單元應(yīng)該包含如下的成員:如下的成員:假設(shè)我們已經(jīng)完成假設(shè)我們已經(jīng)完成這個角色的設(shè)計,這個角色的設(shè)計,并將其鏈接為并將其鏈接為Cell。 成員成員成員描述成員描述discovered是否被打開了haveMine是否有地雷haveFlag是否有旗幟i、j雷區(qū)單元所在的位置各個視覺界面showMine()顯示地雷界面showExplode()顯示地雷爆炸界面showInit()顯示初始化時的界面showAround(num)顯示地雷被排除的界面flag()顯示/隱藏旗幟3.2 編碼與索引編碼與索引 首先,對每個單元進行編碼,以便能夠通過特定的單首先,對每個

16、單元進行編碼,以便能夠通過特定的單元獲取它的編碼值。給方塊類定義元獲取它的編碼值。給方塊類定義i、j屬性,起的就是屬性,起的就是編碼的作用。編碼的作用。其次,要能通過編碼找到所對應(yīng)的單元。將方塊實例其次,要能通過編碼找到所對應(yīng)的單元。將方塊實例創(chuàng)建在一個二維數(shù)組中,而數(shù)組的下標(biāo)正好與編碼的創(chuàng)建在一個二維數(shù)組中,而數(shù)組的下標(biāo)正好與編碼的i、j對應(yīng),那么就可以用編碼作為數(shù)組的下標(biāo)直接找到對對應(yīng),那么就可以用編碼作為數(shù)組的下標(biāo)直接找到對應(yīng)的單元,即為索引。應(yīng)的單元,即為索引。使用二維數(shù)組存儲方塊的另一個好處是可以非常方便使用二維數(shù)組存儲方塊的另一個好處是可以非常方便地找到某個方塊的相鄰方塊。地找到某

17、個方塊的相鄰方塊。 3.3 布置雷區(qū)布置雷區(qū) 設(shè)計好設(shè)計好Cell之后,要創(chuàng)建之后,要創(chuàng)建Cell實例并將它們排布在舞實例并將它們排布在舞臺上。很顯然,通過嵌套的臺上。很顯然,通過嵌套的for循環(huán)結(jié)構(gòu)即可。這個過循環(huán)結(jié)構(gòu)即可。這個過程其實包含了方塊編碼與索引的實現(xiàn)。程其實包含了方塊編碼與索引的實現(xiàn)。代碼段如下圖所示:代碼段如下圖所示:var cellContainer=new Sprite();var cells:Array=new Array();for (var i=0; ilineCount; i+) var cellList:Array=new Array();for (var j=0

18、; jlineCount*rowCount) return;var mineSet:int = 0;var i,j,k;while (mineSetmineCount) k = int(Math.random()*lineCount*rowCount);i = int(k/rowCount);j = k%rowCount;if (cellsij.haveMine!=true) cellsij.haveMine=true;mineSet+; 3.4 隨機分布地雷隨機分布地雷 3.5 計算單元格周圍雷數(shù)計算單元格周圍雷數(shù) 同樣利用同樣利用cells數(shù)組,假設(shè)需要考察的是第數(shù)組,假設(shè)需要考察的是第i

19、行第行第j列的列的單元。那么,我們只要判斷下面單元。那么,我們只要判斷下面8個單元,將有雷的單個單元,將有雷的單元數(shù)累加即可。元數(shù)累加即可。 function around(i:int,j:int) /統(tǒng)計統(tǒng)計i,j位置周圍的類數(shù)位置周圍的類數(shù)var count:Number = 0;for (var int_i=i-1; int_i=i+1; int_i+) for (var int_j=j-1; int_j=j+1; int_j+) if (int_i=lineCount) /超出上下邊界超出上下邊界break;if (int_j=rowCount) /超出左右邊界超出左右邊界break;

20、if (cellsint_iint_j.haveMine =true) count+;if (cellsij.haveMine=true) /減去自身被統(tǒng)計進入的雷數(shù)減去自身被統(tǒng)計進入的雷數(shù)count-;return count; 3.6 無雷區(qū)自動擴張的設(shè)計無雷區(qū)自動擴張的設(shè)計 當(dāng)玩家點擊的單元周圍沒有地雷,那么應(yīng)該將周圍的當(dāng)玩家點擊的單元周圍沒有地雷,那么應(yīng)該將周圍的所有單元都自動打開,如果自動打開的單元還有周圍所有單元都自動打開,如果自動打開的單元還有周圍無地雷的情況,那么繼續(xù)打開它周圍的單元。這樣玩無地雷的情況,那么繼續(xù)打開它周圍的單元。這樣玩家只要點擊一下,就可以成片地排除無雷區(qū)。家

21、只要點擊一下,就可以成片地排除無雷區(qū)。很顯然,這是一個遞歸操作。請描述很顯然,這是一個遞歸操作。請描述基于二維陣列,尋找其周邊單元的遞歸操作具有自反基于二維陣列,尋找其周邊單元的遞歸操作具有自反性(旁邊的旁邊可能是自身),要避免這種自反性造性(旁邊的旁邊可能是自身),要避免這種自反性造成無限遞歸,程序崩潰。只要限定只有未打開過的單成無限遞歸,程序崩潰。只要限定只有未打開過的單元允許遞歸就可以解決這個問題。元允許遞歸就可以解決這個問題。 function expand(i,j) /無雷區(qū)擴張無雷區(qū)擴張var count=around(i,j);/周圍的雷數(shù)周圍的雷數(shù)cellsij.discove

22、red=true;cellsij.showAround(count);if (count!=0) /非無雷區(qū)非無雷區(qū)return;for (var int_i=i-1; int_i=i+1; int_i+) /遍歷周圍的單元遍歷周圍的單元for (var int_j=j-1; int_j=j+1; int_j+) if (int_i=i & int_j=j) /自身,不遞歸自身,不遞歸continue;if (cellsint_iint_j.discovered=false) /未打未打開過,進入遞歸開過,進入遞歸expand(int_i,int_j); 3.7 判斷地雷是否已經(jīng)全部掃

23、判斷地雷是否已經(jīng)全部掃除除 當(dāng)所有的有地雷的單元被插上旗幟并且也只有這些單當(dāng)所有的有地雷的單元被插上旗幟并且也只有這些單元被插上旗幟的時候表示全部地雷已經(jīng)掃除,代碼如元被插上旗幟的時候表示全部地雷已經(jīng)掃除,代碼如下:下:function checkVictory():Boolean if (mineLeft!=0) /沒有掃除干凈或者有掃錯沒有掃除干凈或者有掃錯return false;for (var i=0; icells.length; i+) for (var j=0; jcellsi.length; j+) if (cellsij.haveMine=true&cellsij.

24、haveFlag=false) return false;return true; 3.8 人機交互部分的設(shè)計人機交互部分的設(shè)計 這個游戲就只有兩個操作:這個游戲就只有兩個操作:排除無雷單元排除無雷單元插拔旗幟插拔旗幟遺憾的是遺憾的是Flash并不提供右鍵操作的事件,而并不提供右鍵操作的事件,而雙擊事件和單擊事件也無法同時使用。經(jīng)過考雙擊事件和單擊事件也無法同時使用。經(jīng)過考慮,使用以下方式進行人機交互:慮,使用以下方式進行人機交互:鼠標(biāo)單擊:排除無雷單元,如果是按下鼠標(biāo)單擊:排除無雷單元,如果是按下Ctrl按鍵的按鍵的同時單擊鼠標(biāo),則表示插拔旗幟操作。同時單擊鼠標(biāo),則表示插拔旗幟操作。鼠標(biāo)滾輪

25、:插拔旗幟,如果玩家鼠標(biāo)沒有滾輪,則鼠標(biāo)滾輪:插拔旗幟,如果玩家鼠標(biāo)沒有滾輪,則改用改用Ctrl+鼠標(biāo)單擊。鼠標(biāo)單擊。 function activeCells() /給單元格添加事件偵聽器給單元格添加事件偵聽器for (var i=0; icells.length; i+) for (var j=0; jcellsi.length; j+) MovieClip(cellsij).addEventListener(MouseEvent.MOUSE_UP,adjustClick);MovieClip(cellsij).addEventListener(MouseEvent.MOUSE_WHEEL,flagCell);adjustClick與與flagCell的實現(xiàn)請看備注的實現(xiàn)請看備注3.9 設(shè)置難度級別設(shè)置難度級別 本例中,設(shè)置難度級別非常容易,只要在初始本例中,設(shè)置難度級別非常容易,只要在初

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論