四、A*尋路之大補充
鑒於目前很多朋友反饋說A*難度過高而無法理解,因此,我打算就A*尋路的使用及相關要點做一次重大補充說明:
使用A*,首先需要引用QX.dll程序集;接著在程序中創建IPathFinder PathFinder = new PathFinderFast(Matrix);這裡有個重要的參數Matrix,它是用來描述尋路坐標系中(即縮小後的坐標系)障礙物的二維矩陣,我們這樣創建它byte[,] Matrix = new byte[1024, 1024]; Matrix[x,y]與尋路坐標系中的坐標是一一對應的關系,例如Matrix[150,266]即對應尋路坐標系中的(150,266)這個點,假設GridSize=10,那麼尋路坐標系中的(150,266)此點即對應游戲窗口中的Canvas.LeFTProperty(1500)、Canvas.TopProperty(2660)。並且如果該點是障礙物,則我們設置Matrix[150,266]=0,如果不是障礙物而是可以通行的地點,則我們設置Matrix[150,266]=1,Matrix[,]數組中的其他所有的點依此類推均設置後即完成了地圖中障礙物的布局。這裡出現了GridSize這個很重要的概念,它起到縮放坐標系的作用,如何來理解它呢?這裡我以byte[,] Matrix = new byte[1024, 1024]為例,1024*1024像素地圖僅僅是一張大約我們一個電腦桌面尺寸,但是要在它上面構建障礙物卻需要我們對1024*1024=1048576個點進行設置,簡單有規律的障礙物布局還好,要是遇到復雜的地圖該怎麼辦?這還是小事,要是地圖的尺寸為10000*10000像素(這在MMORPG中再常見不過了),它帶來的不僅是一個大內存數組int[,] Matrix = new int[10000, 10000],更可怕的是在沒有制作地圖編輯器之前去設置其中的100000000個障礙物,簡直就是一件讓人崩潰致極的事。
因此,我引入GridSize(單位格尺寸)這個參數來對坐標系進行縮放操作,從而達到簡化地圖構建過程。例如,我設置GridSize=20,那麼游戲坐標系中的坐標都是窗口中坐標的1/20,例如窗口中Canvas.getLeft(Spirit)=123;Canvas.getTop(Spirit)=353;則對應游戲坐標系中(6,17)(可以直接用整數相除,結果會取整數部分)。這樣的話,一張10000*10000的地圖只需要Matrix[500,500]來實現障礙物構造,並且一個角色占據一個20*20尺寸的單元格是非常合理的。以下為關於引入GridSize這個參數概念的幾大優勢總結:
1、簡化障礙物數組,並且使得地圖構造伸縮自如:關於簡化數組提高性能在上面已經說了,至於伸縮自如是因為我只需要通過改變GridSize的值,其他代碼均不變即可以實現不同精度的游戲坐標系。不信?在前面章節中我的GridSize均為20,本節我將之設置成了10,大家可以很明顯的看到障礙物精度提高了1倍(如下圖):
大家也不妨將GridSize分別設置成1、5、30等,然後相應的修改障礙物(不同GridSize下,障礙物的位置肯定不同)再運行程序看看在不同GridSize下,游戲地圖界面是一樣的,但是單元格精度卻是不同的。特別值得一提的是,當GridSize=1時,此時的尋路坐標系==窗口坐標系,這或許也能讓朋友們更好的理解GridSize的意義。
2、提高尋路算法速度。例如我們設置GridSize=20,此時在40*40像素的地圖區域內只有2*2=4個游戲坐標系單元格即(0,0)、(0,1)、(1,0)、(1、1);如果你需要讓角色從區域左上角移動到右下角,則只需要在這4個點內進行尋路計算出從點(0,0)到點(1,1)的路徑;而如果GridSize=1,即不進行游戲坐標系中單元格縮放而以窗口中的像素點作為基礎單元格,那麼在40*40像素區域內有40*40=1600個坐標點;同樣的如果你需要將角色從區域左上角移動到右下角,就必須在這1600個點內進行尋路計算出從點(0,0)到點(40,40)的路徑。因此我們將GridSize設置為<=20的值,即不失定位的精度,又大幅度簡化及優化地圖構造及性能,何樂而不為?
3、SLG、回合制等類型游戲地圖引擎制作中的必定參數。如果你說RPG(ARPG、MMORPG等)類型的游戲肯定都有自己的地圖編輯器,從而能輕松實現以像素為單位(精確度達到GridSize<=5)的高精度障礙物構造及地圖編輯,這我100%贊同(前提:必須有地圖編輯器,否則後果就如我上文中提到的,一張大且無規律的地圖將讓你痛不欲生)。但是,在SLG、回合制等基於N*N尺寸基礎單元格的游戲中,就如同它們往往被大家通俗的描述為走格子(戰棋類)游戲一樣,地圖格子的概念無處不在。無論是垂直地圖或是斜度地圖,通過設置GridSize都可以輕松的將之實現。
歸納補充了那麼多關於A*的相關使用,大家是漸漸進入狀態了?
本節即將結束,同樣標志著第二部分的開始。第二部分我將就本文開頭用彩色字所提到的相關知識進行講解,或許那才是您真正想要了解的,它將引領我們進入一個真正2D游戲制作中,敬請關注。