浅谈RPG Maker XP自动地图元件的绘制原理
淺談RPG Maker XP自動地圖元件的繪制原理
序:最近剛好想寫個類似RMXP的地圖編輯器,遇到的第一個問題就是自動地圖元件的繪制問題。老實說,我不知道這東西到底叫什么(特別是英文叫什么),只知道RMXP翻譯過來就是自動地圖元件,而且魔獸的地圖編輯器也用到這種技術,但我在網上卻始終找不到相關的資料。其繪制原理其實很清晰,就是用戶給出指定規格的地圖元件資源,編輯器將其拆分,在繪制時再根據繪圖上下文來進行拼接。但具體的過程以及拆分和拼接原理卻很少有人提及,這里我整理了一下。
1.RMXP的自動地圖元件規格
首先介紹下RMXP的自動地圖元件規格,其中第一格和第二格都是展示用的,并不用在具體的拼接上。話說我也是剛搞懂的。
圖1
真正用在拼接的就是剩下的內容,這里先將其按下圖拆分開
圖2
這里的每一個小格就是最后用于拼接的格子,我們暫且叫它小元件,如圖每一個小元件都有一個編號
雖然編號為0,1,2,3,6,7,8,9的小元件都不會用到,但這樣可以方便由編號來進行定位小元件的矩形
計算編號為i的小元件在圖中的矩形的方法為:
size = 16 // 小元件的寬高 row = i / 6 // 小元件所在的行 col = i % 6 // 小元件所在的列 (col * size, row * size, size, size)
2.分析所有拼接情況
在RMXP中,雙擊自動地圖元件,即可以打開自動展開元件的對話框。里面顯示的就是所有拼接情況。
圖3
同樣的,我們給每一種情況定一個編號
圖4
注意,最后2個情況是一樣的,所以總共有47種情況(編號從0開始)
每一種情況都是由4個小元件拼成的。這里先不急著確定每一種對應哪4個小元件。
先來分析下到底是哪47種情況。
假設我們現在正在用RMXP的地圖編輯器來繪制自動地圖元件,如下圖,我們打算在位置4繪制一個自動地圖元件
圖5
那么怎么判斷繪制出來的是哪個情況呢?很簡單,根據周圍的1,2,3,5,6,7,8格子是否有自動地圖元件來確定位置4的繪制情況。(這里要注意,影響位置4繪制情況的是周圍8個格子是否有自動地圖元件,而每個格子具體是哪個情況并不影響)
按照排列組合公式,可以算出8個格子的出現組合有256種,這比47大多了。為什么呢?
這是因為RMXP并不支持對角連接,如下圖
圖6
1和4位置的自動地圖元件并不連接起來,也就是說此時1位置并不會影響4位置的繪制情況。那什么時候才會影響呢?
看下圖
圖7
可以看到,當位置1和3同時存在時,位置0才會影響到位置4。也就是說:當左邊和上邊都存在時,左上角才有影響力。同理可得:當左邊不存在時,左上角和左下角都將失去影響力。(注意這點,后面就是靠這條理論來列舉情況的)
現在來列舉所有情況。可以不考慮對角,只考慮邊的組合。4邊的組合有16種,可以分為5類:
1.?4邊都沒有(1種)
????此時對角全失去影響力。位置4只有1種情況,即情況編號46
2.?只有1邊(4種)
????此時對角依然全失去影響力。位置4只有4種情況,即情況42,43,44,45
3.?有2邊(6種)
????3.1?對邊情況(2種)
????即左邊和右邊同時出現,或者上邊和下邊同時出現,此時對角依然全失去影響力。位置4只有2種情況,即情況32,33
?? 3.2?臨邊情況(4種)?
?? 考慮左邊和上邊同時出現,此時左上角有影響力,有左上角出現與不出現2種情況。其他臨邊情況一樣。位置4共有4*2=8種情況,即情況34-41
4.?有3邊(4種)
????考慮左上右同時出現,此時左上角和右上角有影響力,2個角有4種出現情況。所以共有4*4=16種情況。即情況16-31
5.?4邊都有(1種)
????此時所有角都有影響力,4個角有16種出現情況。所以共有1*16=16種情況。即情況0-15
????
上面的解析有點繞口,大家可以參考圖4理解一下。
所有情況加起來剛好47種。
分析好了所有情況,就可以列出每一種情況對應的哪4個小元件
下面把我辛苦寫出來的對應表給出:
等號左邊為情況編號,右邊為小元件表,注意小元件表里面小元件的順序,是以
“左上,右上,左下,右下”的順序的。
[0]?=?[26,27,32,33]
[1]?=?[4,27,32,33]
[2]?=?[26,5,32,33]
[3]?=?[4,5,32,33]
[4]?=?[26,27,32,11]
[5]?=?[4,27,32,11]
[6]?=?[26,5,32,11]
[7]?=?[4,5,32,11]
[8]?=?[26,27,10,33]
[9]?=?[4,27,10,33]
[10]?=?[26,5,10,33]
[11]?=?[4,5,10,33]
[12]?=?[26,27,10,11]
[13]?=?[4,27,10,11]
[14]?=?[26,5,10,11]
[15]?=?[4,5,10,11]
[16]?=?[24,25,30,31]
[17]?=?[24,5,30,31]
[18]?=?[24,25,30,11]
[19]?=?[24,5,30,11]
[20]?=?[14,15,20,21]
[21]?=?[14,15,20,11]
[22]?=?[14,15,10,21]
[23]?=?[14,15,10,11]
[24]?=?[28,29,34,35]
[25]?=?[28,29,10,35]
[26]?=?[4,29,34,35]
[27]?=?[4,29,10,35]
[28]?=?[26,27,44,45]
[29]?=?[4,39,44,45]
[30]?=?[38,5,44,45]
[31]?=?[4,5,44,45]
[32]?=?[24,29,30,35]
[33]?=?[14,15,44,45]
[34]?=?[12,13,18,19]
[35]?=?[12,13,18,11]
[36]?=?[16,17,22,23]
[37]?=?[16,17,10,23]
[38]?=?[40,41,46,47]
[39]?=?[4,41,46,47]
[40]?=?[36,37,42,43]
[41]?=?[36,5,42,43]
[42]?=?[12,17,18,23]
[43]?=?[12,13,42,43]
[44]?=?[36,41,42,47]
[45]?=?[16,17,46,47]
[46]?=?[12,17,42,47]
[47]?=?[12,17,42,47]
3.繪制
繪制的過程大概是以下偽代碼
// 在row行,col列繪制一個自動地圖元件 void drawAt(int row, int col) {// 判斷row和col是否越界// 將[row,col]位置填為47號情況// 這里可以填任意情況,只要確保[row,col]位置不為空即可drawTileIndex(row,col,47);// 更新[row,col]以及其周圍8個格子的狀態updateTileState(row,col);updateTileState(row-1,col-1);updateTileState(row-1,col);updateTileState(row-1,col+1);updateTileState(row,col-1);updateTileState(row,col+1);updateTileState(row+1,col-1);updateTileState(row+1,col);updateTileState(row+1,col+1); } void drawTileIndex(int row, int col, int index) {// 根據index得到對應的小元件表// 根據小元件表拼接成地圖元件 } void updateTileState(int row, int col) {// 如果該位置沒有地圖元件,則直接返回if (!hasTileAt(row,col)) return;// 判斷其周圍8個格子的狀態state// 根據判斷的狀態確定情況的編號indexdrawTileIndex(row,col,index); }這里最麻煩的就是“根據判斷的狀態確定情況的編號index”
由于情況有47種之多,而且判斷的過程也很糾結。這里提供我的方法,雖然也很麻煩,不過邏輯比較清晰。
核心就是用二進制表達,邊角共有8個,用一個8位的char即可。首先定義如下:4邊4角各占一位
left = 0000 0001 right = 0000 0010 top = 0000 0100 bottom = 0000 1000 left_top = 0001 0000 right_top = 0010 0000 left_bottom = 0100 0000 right_bottom = 1000 0000那么當前4邊4角的情況就可以上面的組合出來。
然后就可以用switch?case表達47種情況,如
switch(state) { case 1111 1111: /*即4邊4角都有*/ index = 0; break; case 1100 1000: /*即左邊和上邊以及左上角都有*/ index = 38; break; ... }4.小結
沒想到寫這樣一篇文章會這么費力,在寫這家伙時,我總感覺自己的方法太笨了。我感覺會有好的方法的,所以還是堅持寫下來,拋磚引玉了。
總結
以上是生活随笔為你收集整理的浅谈RPG Maker XP自动地图元件的绘制原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 矩阵分析与应用(20)
- 下一篇: CPU测评程序、指标、工具