李愛軍
(蘇州職業(yè)大學(xué)計(jì)算機(jī)工程學(xué)院 蘇州 215104)
基于Cocos2d的迷宮游戲的設(shè)計(jì)與實(shí)現(xiàn)
李愛軍
(蘇州職業(yè)大學(xué)計(jì)算機(jī)工程學(xué)院蘇州215104)
本游戲用Xcode開發(fā),并基于Cocos2d,開發(fā)過程中運(yùn)用了流程控制、菜單、特效、精靈等技術(shù)開發(fā)。蘋果游戲開發(fā)模式雖然說看似封閉,但是從另一方面卻極大地激起開發(fā)者興趣。
迷宮手機(jī)游戲Cocos2d-X
迷宮游戲設(shè)計(jì)目的是訓(xùn)練人的思維能力,為了解決玩家在等公交車,放松休息,在咖啡廳等悠閑時(shí)間無聊的問題,既不占用工作時(shí)間,又可以給玩家?guī)順啡?。游戲更是設(shè)計(jì)了眾多關(guān)卡,隨著關(guān)卡的增加,游戲難度會(huì)逐漸增加,讓玩家可以盡情享受游戲的樂趣。
本游戲設(shè)計(jì)是單機(jī)類迷宮闖關(guān)小游戲,相比于電腦版的闖關(guān)類迷宮類小游戲,在操作方面更加的簡潔方便,畫面更加的明了。為了保證游戲的流暢性,游戲在計(jì)算步驟方面運(yùn)用了不算太過于冗長的代碼,但同時(shí)有保證了游戲的樂趣性。在整個(gè)游戲中,實(shí)現(xiàn)以下功能。
1、進(jìn)入游戲界面,出現(xiàn)游戲介紹和游戲開始的選項(xiàng);
2、游戲進(jìn)行時(shí),可以選擇返回選項(xiàng);
3、當(dāng)迷宮人物路線選擇錯(cuò)誤,人物可以自動(dòng)回到起點(diǎn);
4、玩家可以隨意游戲的關(guān)卡,不會(huì)被限制于固定關(guān)卡;
5、游戲關(guān)卡的排列,確保排列格式為蛇形排列;
6、腳印圖形的嵌入,當(dāng)人物進(jìn)入出口時(shí),界面自動(dòng)跳轉(zhuǎn)為游戲的關(guān)卡選擇界面;
7、設(shè)計(jì)每張圖形的路線,從第一關(guān)開始逐漸加大游戲的難度;
8、當(dāng)游戲進(jìn)入或者退出關(guān)卡時(shí),切換界面的方式的選擇為切入;
9、當(dāng)人物選擇路線的方向固定時(shí),游戲自動(dòng)控制人物走到方向選擇路口,優(yōu)化游戲操作。
如圖1。
主視圖初始化模塊:創(chuàng)建并添加游戲視圖,添加游戲關(guān)卡的選擇視圖,通關(guān)關(guān)卡視圖,返回界面選擇視圖。
迷宮初始化模塊:清空人物相應(yīng)位置的信息,將地圖上面的人物位置移動(dòng)到初始化位置。
迷宮關(guān)卡選擇模塊;選擇游戲的關(guān)卡,一共40關(guān)迷宮,玩家可以自由選擇迷宮的關(guān)卡,突顯游戲的高度自由。
游戲介紹模塊:游戲開始時(shí),玩家可以通過游戲簡介加快對游戲的了解,以便玩家可以盡快的上手游戲。
判斷游戲通過模塊:玩家通過自己的計(jì)算步驟,并且走入終點(diǎn),該模塊通過判斷玩家控制的人物是否到達(dá)終點(diǎn)來決定是否通過關(guān)卡。
返回關(guān)卡選擇模塊:當(dāng)玩家未通過此關(guān)卡時(shí),玩家可以選擇返回,返回到游戲關(guān)卡選擇界面,重新選擇游戲其他關(guān)卡進(jìn)行游戲。
A*(A-Star)算法是一種靜態(tài)路網(wǎng)中求解最短路徑最有效的直接搜索方法。估價(jià)值與實(shí)際值越接近,估價(jià)函數(shù)取得就越好。例如對于幾何路網(wǎng)來說,可以取兩節(jié)點(diǎn)間歐幾理德距離(直線距離)做為估價(jià)值,即:f=g(n)+sqrt((dx-nx)*(dx-nx)+(dy-ny)*(dy-ny));這樣估價(jià)函數(shù)f在g值一定的情況下,會(huì)或多或少的受估價(jià)值h的制約,節(jié)點(diǎn)距目標(biāo)點(diǎn)近,h值小,f值相對就小,能保證最短路的搜索向終點(diǎn)的方向進(jìn)行。
通過使用A*算法實(shí)現(xiàn)將人物移動(dòng)到指定的位置,如果路徑不存在,則無法移動(dòng)。因?yàn)檫@里A*尋路算法是有個(gè)概念的,就是有個(gè)路徑最短的計(jì)算方法:f=g+h,簡單的講就是這個(gè)節(jié)點(diǎn)到達(dá)目的節(jié)點(diǎn)的距離f等于這個(gè)節(jié)點(diǎn)周圍的一個(gè)節(jié)點(diǎn)到達(dá)這個(gè)節(jié)點(diǎn)的距離g值再加上周圍節(jié)點(diǎn)到達(dá)目的節(jié)點(diǎn)的距離h值。
尋路的第一步是簡化成容易控制的搜索區(qū)域。怎么處理要根據(jù)游戲來決定了。例如,我們可以將搜索區(qū)域劃分成像素點(diǎn),但是這樣的劃分粒度對于我們這款基于方塊的游戲來說太高了。作為代替,我們使用方塊(一個(gè)正方形)作為尋路算法的單元。其他的形狀類型也是可能的(比如三角形或者六邊形),但是正方形是最簡單并且最適合我們需求的。
像那樣去劃分,我們的搜索區(qū)域可以簡單的用一個(gè)地圖大小的二維數(shù)組去表示。所以如果是25*25方塊大小的地圖,我們的搜索區(qū)域?qū)?huì)是一個(gè)有625個(gè)正方形的數(shù)組。如果我們把地圖劃分成像素點(diǎn),搜索區(qū)域就是一個(gè)有640,000個(gè)正方形的數(shù)組了(一個(gè)方塊是32*32像素)。我們將會(huì)給每個(gè)方塊一個(gè)G+H和值。G是從開始點(diǎn)A到當(dāng)前方塊的移動(dòng)量。所以從開始點(diǎn)A到相鄰小方塊的移動(dòng)量為1,該值會(huì)隨著離開始點(diǎn)越來越遠(yuǎn)而增大。H是從當(dāng)前方塊到目標(biāo)點(diǎn)(我們把它稱為點(diǎn)B,代表骨頭?。┑囊苿?dòng)量估算值。這個(gè)常被稱為探視,因?yàn)槲覀儾淮_定移動(dòng)量是多少-僅僅是一個(gè)估算值。
G是從開始點(diǎn)A到達(dá)當(dāng)前方塊的移動(dòng)量。為了計(jì)算出G的值,我們需要從它的前繼(上一個(gè)方塊)獲取,然后加1。所以,每個(gè)方塊的G值代表了從點(diǎn)A到該方塊所形成路徑的總移動(dòng)量。
H值是從當(dāng)前方塊到終點(diǎn)的移動(dòng)量估算值(在本游戲中是指方塊的數(shù)目)。移動(dòng)量估算值離真實(shí)值越接近,最終的路徑會(huì)更加精確。如果估算值停止作用,很可能生成出來的路徑不會(huì)是最短的(但是它可能是接近的)。為了讓它更簡單,我們將使用“曼哈頓距離方法”(也叫“曼哈頓長”或者“城市街區(qū)距離”),它只是計(jì)算出距離點(diǎn)B,剩下的水平和垂直的方塊數(shù)量,略去了障礙物或者不同陸地類型的數(shù)量。
方法會(huì)返回一個(gè)數(shù)組,里面包含了地圖周圍的四個(gè)節(jié)點(diǎn)對象。依次取出地圖四周的節(jié)點(diǎn)對象,因?yàn)槭峭ㄟ^點(diǎn)擊地圖后地圖和人才移動(dòng)的,但是需要檢查地圖四個(gè)方向上是否有人,移動(dòng)的方向即人面向的方向,如果有則判斷哪個(gè)節(jié)點(diǎn)對象的位置是人物按鈕。
-(void)moveNext:(NSButtonNode*)nextNode currentNode:(NSButtonNode*)currentNode
UIButton*oneButton=currentNode.mapButton;UIButton*nextButton=nextNode.button;
第一行意思把當(dāng)前節(jié)點(diǎn)NSButtonNode對象的屬性上層按鈕賦給一個(gè)按鈕引用對象。第二行把下一個(gè)NSButtonN-ode對象節(jié)點(diǎn)的屬性下層按鈕也賦給一個(gè)按鈕引用對象。來判斷這兩個(gè)按鈕是否是存在的。
假如當(dāng)前節(jié)點(diǎn)的上層按鈕屬性值是存在的而且下一個(gè)節(jié)點(diǎn)的下層按鈕屬性值也是存在的,則可以進(jìn)行兩個(gè)節(jié)點(diǎn)的按鈕屬性值交換的操作以實(shí)現(xiàn)按鈕移動(dòng)的效果。下一個(gè)按鈕的 frame值賦值給當(dāng)前節(jié)點(diǎn)對象的上層按鈕的frame屬性是為了使得將oneButton移動(dòng)到nextButton的位置時(shí)使其位置和大小保持一致。nextButton的tag值也賦給oneB-utton是因?yàn)閠ag值標(biāo)識(shí)了按鈕所在的位置,可以通過獲取按鈕的tag值來判斷按鈕的位置在第幾行第幾列,根據(jù)這個(gè)行列值就可以到NSButtonNode節(jié)點(diǎn)對象數(shù)組中獲取擁有這個(gè)按鈕的NSButtonNode對象,因?yàn)榘粹o的位置發(fā)生變化了所以我們也要更新它的tag值使其與新位置保存一致。設(shè)置這個(gè)按鈕在當(dāng)前父視圖上前置顯示。
將當(dāng)前節(jié)點(diǎn)的當(dāng)前狀態(tài)值復(fù)制另存是為了賦給下一個(gè)節(jié)點(diǎn)的當(dāng)前狀態(tài)值屬性,因?yàn)檫@個(gè)狀態(tài)值標(biāo)識(shí)了一個(gè)節(jié)點(diǎn)對象它所控制的位置給人看到的按鈕是何種類型的。地圖按鈕或者是人物按鈕移動(dòng)位置后就不在當(dāng)前節(jié)點(diǎn)上面了,所以要它的屬性mapButton賦值為空。由于當(dāng)前節(jié)點(diǎn)對象的mapButton按鈕屬性值已為空,那么當(dāng)前節(jié)點(diǎn)對象所控制位置顯示的按鈕是它的屬性button值,也就是就一層按鈕了,所以這個(gè)節(jié)點(diǎn)對象用來標(biāo)識(shí)當(dāng)前顯示的是何種類型的按鈕的屬性currentState值,要恢復(fù)成它之前的狀態(tài)值,而這個(gè)狀態(tài)值就保存在它的屬性lastState中。由于節(jié)點(diǎn)原來的狀態(tài)還原了,所以將屬性lastState值賦值為一開始初始化時(shí)的枚舉值NOSTATE。
把這個(gè)引用上一個(gè)節(jié)點(diǎn)的用于顯示在上層的按鈕對象賦給下一個(gè)節(jié)點(diǎn)的用于顯示的上層按鈕屬性。因?yàn)橄乱粋€(gè)節(jié)點(diǎn)對象所控制位置顯示的按鈕發(fā)生變化,所以要將它自己原來的狀態(tài)值保存在屬性lastState中,以便人物或者是地圖移走后,還能夠恢復(fù)成原來的狀態(tài)。因?yàn)檫@個(gè)節(jié)點(diǎn)對象所控制位置顯示在視圖上的按鈕發(fā)生了變化,所以它相應(yīng)標(biāo)識(shí)的屬性currentState也要設(shè)置成對應(yīng)的屬性值。
第一個(gè)if是指,如果測試節(jié)點(diǎn)的周圍的這個(gè)節(jié)點(diǎn)對象已經(jīng)在openAry數(shù)組中了,就判斷在這個(gè)測試節(jié)點(diǎn)的基礎(chǔ)上再前進(jìn)一步到這個(gè)屬于周圍節(jié)點(diǎn)中的這個(gè)節(jié)點(diǎn)的g值是否比它原來算的g值是否要小,如果要小則表示原來要走的節(jié)點(diǎn)通過這個(gè)測試節(jié)點(diǎn)走過去g值更小,距離更加的短,由于已經(jīng)在開發(fā)數(shù)組中的節(jié)點(diǎn)的g值發(fā)生了改變則需要建造堆,也就是對開放數(shù)組中的節(jié)點(diǎn)進(jìn)行針對g值的重新排序,使得首節(jié)點(diǎn)是g值最小的節(jié)點(diǎn)
設(shè)置父節(jié)點(diǎn)的目的是為了在尋找的測試的節(jié)點(diǎn)就是目標(biāo)節(jié)點(diǎn)后通過目標(biāo)節(jié)點(diǎn)的父節(jié)點(diǎn)可以進(jìn)行遞歸到開始的人的節(jié)點(diǎn),這樣做的目的是為了將從人的位置通向目標(biāo)節(jié)點(diǎn)的路徑,也就是順序排列的節(jié)點(diǎn)都找出來,在通過倒序后的路徑就可以走到目標(biāo)節(jié)點(diǎn)位置的路徑了。
節(jié)點(diǎn)發(fā)生了變化,需要重新按照f值給openAry數(shù)組的節(jié)點(diǎn)對象進(jìn)行最小二叉堆的排序如果這個(gè)周圍的節(jié)點(diǎn)對象不在openAry數(shù)組里面,就把它加入到openAry數(shù)組中,如果此時(shí)openAry數(shù)組中元素個(gè)數(shù)是三個(gè)或者是三個(gè)以上,則進(jìn)行按照節(jié)點(diǎn)對象的屬性f值最小二叉堆的排序。也就是使得openAry數(shù)組中的首元素的f值是最小的,最小的f值節(jié)點(diǎn)對象優(yōu)先作為最短路徑構(gòu)成選擇。
游戲本身是一款可以在iPad運(yùn)行的迷宮類闖關(guān)類小游戲,在游戲打開后直接進(jìn)入游戲主界面,用戶這時(shí)可以兩個(gè)選項(xiàng):進(jìn)入進(jìn)一步的關(guān)卡選擇或者看游戲簡介。當(dāng)玩家選擇關(guān)卡時(shí)玩家進(jìn)入選定關(guān)卡,繼而指揮角色從起點(diǎn)穿過層層障礙到達(dá)出口。玩家在這個(gè)過程也可以進(jìn)行游戲的退出,進(jìn)而可以選擇新的關(guān)卡,開始新一輪的游戲。
本文在詳細(xì)論述了基于Cocos2d的迷宮類闖關(guān)類小游戲,介紹了系統(tǒng)的主要模塊和算法分析以及算法關(guān)鍵代碼實(shí)現(xiàn),最后對該游戲平臺(tái)進(jìn)行了試運(yùn)行。此系統(tǒng)具有一定的實(shí)用性和應(yīng)用前景。
[1][美]Rob Napier.Mugunth Kumar,庫 瑪.iOS編程實(shí)戰(zhàn)[M].人民郵電出版社,2014.
[2][美]赫樂嘎斯,康威.iOS編程(第4版)[M].華中科技大學(xué)出版社,2015.
[3]劉劍卓.Cocos2D-X游戲開發(fā)技術(shù)精解[M].人民郵電出版社,2013.
李愛軍(1973~),男,碩士,講師,研究方向?yàn)槊嫦虺绦驅(qū)ο笤O(shè)計(jì)、數(shù)據(jù)庫技術(shù)、IOS開發(fā)技術(shù)。
Design and Implementation of Maze Game Based on Cocos2d
Li Aijun
(Computers Engineering Institute,Suzhou Vocational UniversitySuzhou215004)
The game with Xcode development,and based on Cocos2d,the process of developing the use of process control,menu,special effects,elves and other technology development.Apple game development model that seems to be closed,but on the other hand is greatly aroused the interest of developers.The design of the original intention of this game is to solve peoplesent in the boring time,exercise the brain,so as to let the game player to find the joy of the game of the.
MazeMobile phone gameCocos2d-X
TP311
A
160607-7303