基于组块设计执行开放世界等距游戏引擎
文 / Benedikt S. Vogler
過(guò)去今年里我一直在開(kāi)發(fā)一款名為Wurfel Engine的游戲引擎。以下大部分內(nèi)容是對(duì)于我在學(xué)校中的最后一次考試所發(fā)現(xiàn)的一些算式與解決方法的解釋并在過(guò)去2年里得到完善的論文摘錄。
你們可以在Wurfel Engine SDK,即我基于Java所編寫(xiě)的開(kāi)放源游戲引擎中找到以下的大多數(shù)算式。現(xiàn)在的我正使用該引擎創(chuàng)造名《Caveland》的商業(yè)游戲。
儲(chǔ)存地圖數(shù)據(jù)塊
儲(chǔ)存磚塊的一種簡(jiǎn)單的方式便是使用鉆石地圖。鉆石地圖就是一個(gè)旋轉(zhuǎn)的固定網(wǎng)格(如圖1)。
?
如果整款游戲都是發(fā)生在一張小小的地圖上的話這便很適合。然而如果你需要執(zhí)行一個(gè)更大的(開(kāi)放)游戲世界或生成地圖內(nèi)容,你便需要“流出”數(shù)據(jù)。為此你需要加載數(shù)據(jù)塊。使用鉆石地圖是否能夠完成流傳播?如果你使用鉆石地圖格式,你的數(shù)據(jù)塊只會(huì)如下無(wú)縫地進(jìn)行排列:
?
灰色矩形代表的是屏幕。你可以發(fā)現(xiàn)你需要更多組塊去覆蓋屏幕。然而你希望組塊能夠像這樣組合在一起:
?
因此Wurfel Engine使用了一排移動(dòng)的網(wǎng)格,通常被叫做“錯(cuò)列地圖”,這非常適合地圖流傳播。在錯(cuò)列地圖中每個(gè)第二排都會(huì)移動(dòng)半個(gè)磚塊。
?
擁有數(shù)據(jù)組塊的RAM將遭遇只能模仿接近攝像機(jī)的實(shí)體的問(wèn)題。這適合于大多數(shù)游戲。如果該區(qū)域外部的某些內(nèi)容(游戲邦注:對(duì)于游戲玩法來(lái)說(shuō)可能很重要)出現(xiàn),你就需要在RAM中添加更多數(shù)據(jù)塊。
訪問(wèn)并儲(chǔ)存數(shù)據(jù)塊
存在多種儲(chǔ)存數(shù)據(jù)的方式,在這種情況下數(shù)據(jù)塊總是包含組塊。我們想要更快速地訪問(wèn)數(shù)據(jù),這意味著基于0(1)進(jìn)行訪問(wèn)。做到這點(diǎn)的一種簡(jiǎn)單方式便是使用一個(gè)3D數(shù)組。很長(zhǎng)一段時(shí)間我都在使用一個(gè)巨大的3D數(shù)組,它將被插入一個(gè)巨大的地圖模型中,如果它們被移除可視區(qū)域,那么剩下的數(shù)據(jù)將被移出內(nèi)存。
這一解決方法也帶有自身的缺陷,因?yàn)樗试S一個(gè)視窗的存在。如果你想要在一個(gè)開(kāi)放世界中執(zhí)行分屏的話會(huì)怎樣?攝像機(jī)可以設(shè)置在完全不同的地方,但只有你處于同一個(gè)場(chǎng)所時(shí)地圖才會(huì)運(yùn)行。我通過(guò)將各自帶有一個(gè)3D模型的數(shù)據(jù)塊儲(chǔ)存在一起而解決了這一問(wèn)題(現(xiàn)在我正在使用一個(gè)簡(jiǎn)單的列表)。為了找到并獲得歸屬于游戲坐標(biāo)的單元格內(nèi)容,二手手機(jī)買(mǎi)賣(mài)平臺(tái)你需要為每個(gè)數(shù)據(jù)塊和維度儲(chǔ)存一個(gè)固定點(diǎn)。之后你可以在列表上反復(fù)進(jìn)行迭代并判斷哪個(gè)數(shù)據(jù)塊覆蓋了這一坐標(biāo)。如果是這種情況的話,你便可以通過(guò)在角落減去固定點(diǎn)而估算指標(biāo)的位置。
自定義迭代器是貫穿這張地圖的一種有效工具。
基于不為了海量?jī)?chǔ)存減少RAM的使用同游戲,你需要在內(nèi)存中儲(chǔ)存許多數(shù)據(jù)塊或組塊。如果你在每個(gè)數(shù)據(jù)塊中都包含數(shù)千個(gè)組塊,那么儲(chǔ)存每個(gè)伴隨著多個(gè)字段的組塊將快速消耗內(nèi)存容量。現(xiàn)在我正在嘗試一個(gè)版本,即我只會(huì)儲(chǔ)存3個(gè)字節(jié)去代表一個(gè)組塊。如果它們處于攝像機(jī)視窗中,它們便會(huì)被轉(zhuǎn)換成帶有更多字段且能夠用于渲染方法中的對(duì)象。這一方法能夠幫助我們節(jié)省不少空間,即我們可以使用200兆的空間去儲(chǔ)存一個(gè)1800平方千米的區(qū)域。
執(zhí)行屏幕的一種更好的方法
如果你正在使用一張鉆石地圖,你的行數(shù)將不會(huì)發(fā)生改變,你也不需要如下的方法,因?yàn)槟憧梢酝ㄟ^(guò)旋轉(zhuǎn)并改變屏幕空間坐標(biāo)獲得備選單元,然后再離散化數(shù)值。
使用錯(cuò)列地圖離散化屏幕空間的x和y坐標(biāo)將會(huì)呈現(xiàn)出兩個(gè)磚塊間模糊的結(jié)果。
存在兩種用于識(shí)別正確磚塊的常見(jiàn)方法。一種方法便是使用一些顏色編碼圖像(圖6)去識(shí)別你的鼠標(biāo)所點(diǎn)擊的角落。這更像是一個(gè)難以執(zhí)行的黑客,有可能改變磚塊的維度,并且會(huì)創(chuàng)造出錯(cuò)誤的結(jié)果。還有一種方法是估算磚塊中心位置間的距離并使用最接近的那個(gè)。我發(fā)現(xiàn)這一方法擁有一些意外的結(jié)果。這是一種動(dòng)態(tài)的方法,能夠通過(guò)使用一些不等式去檢測(cè)側(cè)面而支持不同的磚塊大小。
?
如果你使用如下方程式,你便能夠獲得與一些圖形計(jì)算器中的圖像方法一樣的結(jié)果:
?
當(dāng)然了,你也可以通過(guò)將x或y乘以一個(gè)系數(shù)而扭曲磚塊。
如果你著眼于圖表,你將會(huì)看到一些重疊的區(qū)域。通過(guò)檢查兩個(gè)完整的方程式,你便可以識(shí)別每個(gè)區(qū)域并檢測(cè)一些點(diǎn)是否位于一些鄰近的位置上。
一旦你執(zhí)行了這一方法,你便可以使用該方法去獲得游戲中任何點(diǎn)數(shù)的單元坐標(biāo),該功效也使這一方法變成了一個(gè)更加強(qiáng)大的工具。
巧妙地裁剪等距世界
等距游戲世界通常都是扁平的。有時(shí)候磚塊也是扁平的,但它們更常使用3維磚塊,因?yàn)檫@樣便可以在高度上移動(dòng)它們。渲染一個(gè)扁平的世界并不會(huì)受限于性能。然而Wurfel Engine使用了一個(gè)立方體地圖。你可以在彼此上方堆積許多組塊,這將導(dǎo)致許多重疊組塊的出現(xiàn)。因?yàn)閳?zhí)行碎片/像素著色器而出現(xiàn)的許多看不見(jiàn)的像素導(dǎo)致執(zhí)行非定義隱藏界面檢測(cè)(HSD)會(huì)非常致命。
提高性能的一種簡(jiǎn)單方式便是基于帶有三個(gè)不同精靈的三面分割每個(gè)組塊。如果沒(méi)有組塊在前方而遮住其它組塊,你便可以只渲染上方和前方。這一算法將執(zhí)行每個(gè)組塊的循環(huán)并檢查其直接鄰近對(duì)象,從而確定最終的裁剪對(duì)象。
為了讓設(shè)計(jì)高度等于設(shè)計(jì)深度(圖8)而使用扭曲的四邊形組塊時(shí),我們便能夠執(zhí)行一些有效的裁剪。
?
我通過(guò)面向每個(gè)組塊發(fā)送三條射線而做到了這點(diǎn)(圖9),每一面一條射線,貫穿地圖并檢測(cè)它們何時(shí)遇到可視的那一面。每一條射線會(huì)為了每一個(gè)半面而分裂成兩條以上的射線。在有些情況中一些組塊將覆蓋一半的面,而有些加深了另一半面的圖層將被隱藏于其它組塊中(圖10)。每個(gè)撞擊到的面都將獲得一個(gè)標(biāo)志。然后渲染器將只會(huì)渲染沒(méi)有標(biāo)志的面。
?
后面組塊的左邊被隱藏起來(lái)了,并且沒(méi)有直接的鄰近組塊
然而為了藝術(shù),維度將被轉(zhuǎn)換成真正的等距組塊。它們是存在問(wèn)題的,即當(dāng)你在堆積時(shí)它們并不能排成一行,因?yàn)樵O(shè)計(jì)高度大于設(shè)計(jì)深度。你可以在圖11中看到這點(diǎn):并不是每一個(gè)角落都能夠與網(wǎng)格對(duì)齊。射線將通過(guò)假設(shè)組塊是否勻稱(chēng)地將其覆蓋住而追蹤裁剪是否有效。所以基于光線投射的裁剪算法將被更簡(jiǎn)單的算法所取代。這一算法的問(wèn)題在于它并不能判斷組塊是否被隱藏起來(lái)以及組塊之間是否存在一定的空間,如當(dāng)組塊被一堵墻或屋頂所覆蓋住時(shí)。
?
當(dāng)?shù)貓D內(nèi)容改變時(shí),兩種裁剪算法都應(yīng)該被執(zhí)行。
總結(jié)
基于使用案例和要求,我們知道存在更多不同方式去創(chuàng)造一個(gè)類(lèi)似且有效的游戲引擎。每個(gè)設(shè)計(jì)選擇都應(yīng)該始于組塊的維度。在體素引擎領(lǐng)域中,我們可以找到許多更快捷的內(nèi)存節(jié)省方式,并且能夠?qū)⑵溆糜谥蟮难芯恐小?/span>
總結(jié)
以上是生活随笔為你收集整理的基于组块设计执行开放世界等距游戏引擎的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 发挥游戏人工智能的最大价值:线程化
- 下一篇: 游戏行业的人工智能设计(二):路径搜寻和