引子
我所用的游戲引擎是Godot涝缝,一個用c++寫的開源2d/3d游戲引擎窑眯,代碼托管在github上梭伐,擁有一套比較完整的工具,并且使用整個引擎做的游戲?qū)τ诎姹竟芾砉ぞ弑容^友好陡叠,有自己的腳本語言(語法類似Python)玩郊。具體的可以到官網(wǎng)上面去看介紹(英文)。
游戲
下面是我做的游戲的一些大致機(jī)制的抓屏枉阵。
可以看到译红,這是一個固定視角的偽3D游戲,具體操作是通過使用上下左右四個方向來使方塊移動兴溜,從而是方塊達(dá)到一定的高度或形狀侦厚。
問題
我一開始學(xué)整個引擎的時候都是在2d環(huán)境下制作游戲,而且這個游戲的貼圖都是2d的像俗畫拙徽,所以我在做這個游戲小樣的時候就也沒有多想刨沦,直接在2d環(huán)境下開干了。
但是即使我對每個方塊都設(shè)置各自在整個三維網(wǎng)格中的座標(biāo)膘怕,2d環(huán)境能夠給我的就只是哪些圖片(在我這個游戲中就是方塊的貼圖)往哪個方向移動想诅,哪些圖片先渲染(會被后面的遮住)岛心,哪些圖片后渲染(不會被遮桌雌啤)而已。所以為了讓整個網(wǎng)格顯示正常忘古,必須手動來處理這個網(wǎng)格的渲染順序徘禁,或者說處理好方塊的渲染順序。
引擎
Godot引擎的游戲的制作方法是以“節(jié)點(diǎn)”的方式制作髓堪,每個節(jié)點(diǎn)可以是不同種類的東西送朱,也可以是另外制作好的“節(jié)點(diǎn)”,每個獨(dú)立制作的節(jié)點(diǎn)成為“場景”(scene)干旁,而節(jié)點(diǎn)的順序驶沼,就是引擎渲染的順序,有撒謊哪個到下依次渲染争群,所以最下面的節(jié)點(diǎn)是最后渲染的商乎。
如果有一個跟節(jié)點(diǎn)類型為 Node2D ,字節(jié)點(diǎn)是3個TextureRect祭阀,那么不論這三個TextureRect的貼圖大小如何鹉戚,位置如何,最下面的TextureRect是不可能被前兩個TextureRect遮擋住的专控。
不過對于 Node2D 抹凳,有一個屬性是 Z Index ,這個屬性是引擎中的 Z 軸伦腐,相當(dāng)于在你手垂直舉著一張紙時垂直于直面的一條線赢底。有了這個,就能手動地控制哪些方塊在哪些方塊的上面了柏蘑。
設(shè)定
游戲內(nèi)的座標(biāo)
- 游戲座標(biāo) :是指在上圖網(wǎng)格中的座標(biāo)
- 引擎座標(biāo) :是指在游戲引擎中的座標(biāo)
計算方式
接下來就是真正的計算方式了幸冻,嘿嘿
first try
這里要先弄清楚一點(diǎn),在上圖中最下面的格子中的方塊的圖層肯定是會比在座標(biāo)原點(diǎn)的格子的方塊圖層要高咳焚,也就是說最下面的方塊的引擎內(nèi)z軸一定會會比原點(diǎn)的方塊高洽损,絕對不會被原點(diǎn)的遮擋的。
那這樣的話革半,即使游戲內(nèi)是在同一層碑定,也需要根據(jù)游戲內(nèi)x軸和游戲內(nèi)y軸來計算圖層,那在統(tǒng)一層的話是怎么算圖層的呢又官?
從原點(diǎn)開始看吧延刘,在原點(diǎn)的方塊上,不論是往游戲內(nèi)的x軸還是游戲內(nèi)的y軸方向上移動一格六敬,引擎內(nèi)的z軸都應(yīng)該加1(或一個計量)碘赖,然后在那個格子再繼續(xù)的話也是加1。那么照這樣算外构,在游戲內(nèi)z軸相等普泡,也就是同一層的情況下,引擎z軸的計算公式是:
- 引擎z軸 = 游戲x軸 + 游戲y軸
然后因?yàn)橛螒騼?nèi)的網(wǎng)格有z軸典勇,也就是類似于”層“的概念劫哼,我就非常簡單地將每一層疊加起來,所以對于所有方塊:
- 引擎z軸 = 游戲最大x軸 * 游戲最大y軸 * 游戲z軸 + 游戲x軸 + 游戲y軸
這樣做的問題
正如你在上面的動圖中看到的割笙,方塊的移動有時侯會跨”層“权烧。如果使用這樣的算法,就會出現(xiàn)方塊下降層的時候北原先后面的方塊遮擋住伤溉,或者上升層的時候遮擋住原先在前面的方塊擋住般码。
finished one
上面這個問題一開始我還沒有發(fā)現(xiàn),因?yàn)槲易鲆恍y試地圖的時候乱顾,都會做一些比較簡單的圖來測試板祝。
不過這個問題的解決辦法騎士一開始就已經(jīng)有了,只不過我沒有反應(yīng)過來走净。那就是既然在同一個”層“上是 x+y 券时,那么在此基礎(chǔ)上孤里,把 x+y 作為一個獨(dú)立的軸,加上 z 橘洞,好像就可以了捌袜。
所以對于所有方塊:
- 引擎z軸 = 游戲x軸 + 游戲y軸 + 游戲z軸
這樣不論什么情況都不會出現(xiàn)不正確遮擋的問題,下面的兩張圖能比較好地證明這個:
寫在最后
公式很簡單炸枣,但是我卻花了很多時間去調(diào)試第一條公式虏等,不斷地調(diào)整,試過在每兩層之間添加一個過渡層适肠,但是因?yàn)橐姹旧淼膱D層渲染順序會有時候看不出來問題霍衫。不過有前輩說過,寫程序的時候走的彎路都不是彎路侯养。幸好最后都想出來了正確的做法敦跌,花的時間應(yīng)該都是值得的。