魔獸爭霸自動地圖元件的繪製原理
序:
本文主要介紹一種簡單高效的自動地圖元件的繪製方法,基本的原理是基於CodeProject的作者爲Colin Vella的一篇文章:http://www.codeproject.com/KB/game/Autotiles_Algorithm.aspx#_comments 該文章介紹的方法非常簡單,而且很高效。本文會先講述此方法,然後在此方法的基礎上,介紹魔獸爭霸的自動地圖元件的繪製原理,因爲其實這2者的原理是一樣的,但方法稍有不同。
1.基本原理
對於自動地圖元件,我們可以這樣理解,它實際上是一種地形分割器,例如
岸邊 -- 水和陸地的分割;
牆壁 -- 室內和室外的分割。
圖1
那麼我們就可以用0和1分別來代表兩種地形了,我們將一個tile分成4個角,每個角都可能是兩種地形的其中一種(即可以是0,也可以是1)。
這樣我們用一個4位的數字b3b2b1b0表示一個tile,其中每一位表示一個角的地形,如下圖
圖2
這樣4個角總共有16種情況,分別是以下16種,如下圖,我們將藍色部分想象成水,黃色部分想象成陸地,而兩者間的黑線想象成岸邊
圖3
在實際繪製過程中,我們就是用這16種情況類拼接地圖的。
2.自動地圖元件的規格
上面圖3就是此方法使用的地圖元件的規格,注意此方法使用的自動地圖元件的規則與RMXP的規格並不一樣,在某種意義上說,RMXP的地圖元件的精度要高一點,這點會在後續文章中給出分析。
在圖3中,我們故意將原件按其對應數字的大小來排序,也就是說0000排在第一,0001排在第二,1111排在最後。這樣就可以很方便地根據tile的數值對應到其實際貼圖了,用如下方法
int tileNumber = tileMap[row][col];
Rect srcRect(tileNumber * tileWidth, 0, tileWidth, tileHeight);
3.繪製算法
繪製的算法非常簡單,反而是原文講得比較繞口。如下圖,我們打算在位置4繪製地圖元件,此時我們只需將位置4以及它周圍共16個小格填爲1即可。如下圖:
圖4
注意一點,我們只是將上圖紅色方框內的16個小格填爲1而已,並不改動方框外的格的內容。例如左上角,我們假設其當前值是0110,那麼改動後變成1110。
算法要注意的地方是,在地圖的邊緣時,要考慮繪製位置的旁邊是否有tile,例如在(0,0)位置繪製時,0,1,2,3,6格子都是不存在的。
繪製的代碼如下:r,c分別代表要繪製的行和列號,easyMap是二維數組,保存了所有tile。MAPROW和MAPCOL分別是地圖的行數和列數。
// 將中心點周圍的16個小格填爲1
if (r > 0)
{
if (c > 0) easyMap[r - 1][c - 1] |= 0x8; // 1000
easyMap[r - 1][c] |= 0xC; // 1100
if (c < MAPCOL - 1) easyMap[r - 1][c + 1] |= 0x4; // 0100
}
if (c > 0) easyMap[r][c - 1] |= 0xA; // 1010
easyMap[r][c] |= 0xF; // 1111
if (c < MAPCOL - 1) easyMap[r][c + 1] |= 0x5; // 0101
if (r < MAPROW - 1)
{
if (c > 0) easyMap[r + 1][c - 1] |= 0x2; // 0010
easyMap[r + 1][c] |= 0x3; // 0011
if (c < MAPCOL - 1) easyMap[r + 1][c + 1] |= 0x1; // 0001
}
消除的過程是繪製的反過程,也就是將填爲1的16個小格填爲0即可
// 將中心點周圍的16個小格填爲0
if (r > 0)
{
if (c > 0) easyMap[r - 1][c - 1] &= ~0x8; // 0111
easyMap[r - 1][c] &= ~0xC; // 0011
if (c < MAPCOL - 1) easyMap[r - 1][c + 1] &= ~0x4; // 1011
}
if (c > 0) easyMap[r][c - 1] &= ~0xA; // 0101
easyMap[r][c] &= ~0xF; // 0000
if (c < MAPCOL - 1) easyMap[r][c + 1] &= ~0x5; // 1010
if (r < MAPROW - 1)
{
if (c > 0) easyMap[r + 1][c - 1] &= ~0x2; // 1101
easyMap[r + 1][c] &= ~0x3; // 1100
if (c < MAPCOL - 1) easyMap[r + 1][c + 1] &= ~0x1; // 1110
}
4.魔獸爭霸的自動地圖繪製
如果你沒用過魔獸爭霸的地圖編輯器,那麼你可以在魔獸爭霸的遊戲目錄下找到它,World Editor.exe
打開它默認出現的就是編輯地形的模式,可以看到它的地形編輯與RMXP的不同是,它是以頂點來定位的,而不是RMXP的以tile來定位的。如下圖
圖5
要繪製出魔獸爭霸的地圖編輯器的效果,用上面的算法即可,不過需稍作修改。如下圖,我們打算在中心頂點位置繪製地圖元件,此時我們只需將該頂點附近4個小格填爲1即可,也就是將下圖紅色方框內的小格填爲1。
圖6
5.共性
我們將魔獸爭霸地圖編輯器的繪製形狀改爲正方形,尺寸改爲2,如下圖
圖7
這圖是不是有點時曾相識呢,就是跟上述填16格的算法的區域基本一樣。此時我們可以得知,此算法對繪製區域有一個隱性要求,就是繪製區域不能設定爲剛好是整數個方格。試想一下,參考圖4,如果在繪製時,我們僅將中心的4個小格填爲1會出現什麼情況?情況就是我們只能繪製出0000和1111兩種地形了,魔獸爭霸的地圖編輯器也一樣,你可以改一下繪製區域的尺寸,不管是什麼尺寸,都不會出現上面所說的情況。
6.實現
具體的實現代碼可以從下面地方下載,是用的HGE引擎編寫的。如果你沒用過,可以在這裏下載HGE並學習:http://hge.relishgames.com/
下面是程序的截圖
代碼下載地址:http://download.csdn.net/detail/gouki04/4025467
項目使用VS2008寫的,打開後直接生成解決方案即可。裏面包含2個項目,分別是上面所說的2種方法,生成成功後可直接運行,操作爲鼠標左鍵繪製,右鍵清除。