最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

世界平滑生成筆記

2021-12-30 23:54 作者:道家深湖  | 我要投稿

需要指出的是,世界生成的流程大多數(shù)是寫在IChunkGenerator里的,但它畢竟只是個(gè)接口而已,實(shí)際是什么效果完全看怎么實(shí)現(xiàn)。此外,它在mod中又可能被完全重寫,所以接下來所說的大部分原理,主要適用于原版主世界,以及根據(jù)主世界的設(shè)計(jì)精神延伸出的其他維度。

想生成大型建筑,不搞明白這個(gè)過程是免談的,做出來的很有可能會(huì)遇到各種問題,不僅不知道怎么解決,甚至不知道發(fā)生了什么。


原版中,ChunkGenerator有五個(gè)子類,它們分別是:

  • ChunkGeneratorDebug,調(diào)試用的,一般玩家不會(huì)用到。

  • ChunkGeneratorEnd,用于生成末地。

  • ChunkGeneratorFlat,用于生成超平坦世界。它實(shí)際上只會(huì)用于處理主世界,超平坦模式下,地獄還是老樣子,不會(huì)變平。

  • ChunkGeneratorHell,用于生成下界(地獄)。

  • ChunkGeneratorOverworld,用于生成主世界,最復(fù)雜、最關(guān)鍵,也是接下來要重點(diǎn)討論的內(nèi)容。

世界生成分為兩個(gè)大階段,我們稱之為底漆階段和殖民階段。

這兩個(gè)名字是我起的,前者主要操作ChunkPrimier,后者大多數(shù)在populate中進(jìn)行。


第一階段,premier底漆

我們看ChunkGeneratorOverworld::generateChunk,根據(jù)它對(duì)這個(gè)接口的實(shí)現(xiàn),我們可以看到,

區(qū)塊首次被加載時(shí),確定隨機(jī)種子,進(jìn)入底漆階段;此時(shí)它只是個(gè)ChunkPrimer,甚至不是一個(gè)Chunk。

【底漆其一:山海定高】

這個(gè)Primier先會(huì)通過setBlocksInChunk進(jìn)行基本的地貌雕刻,設(shè)置石頭和海洋,用以塑造一個(gè)高度圖的雛形。它的塑造結(jié)果完全取決于輸入的隨機(jī)種子,x、z的值,還有根據(jù)getBiomeProvider()獲取的群系參數(shù)。這里,不同區(qū)塊的平滑連接是靠柏林噪聲的連續(xù)型實(shí)現(xiàn)的。

【底漆其二:群系變貌】

到目前為止,不同的群系只是有高度平均值、高度方差的區(qū)別。我們接下來執(zhí)行ChunkGeneratorOverworld::replaceBiomeBlocks。

他會(huì)先觸發(fā)ChunkGeneratorEvent.ReplaceBiomeBlocks這個(gè)事件,這個(gè)事件的結(jié)果為阻止的話,這一步到此為止。

如果沒有被阻止,那么根據(jù)x和z的每一個(gè)位置,它們會(huì)根據(jù)柏林噪聲的高度圖結(jié)果和群系分布,讓群系Biome執(zhí)行Biome::genTerrainBlocks。這里會(huì)防止沙子、砂礫、石頭;水會(huì)根據(jù)溫度變成冰。越往下的地方,越容易形成基巖。這一切都是混在一起的。群系的topBlock和fillerBlock在這里生效,換成對(duì)應(yīng)的方塊。各種教程教的群系自定義方塊基本都是在這一步生效的。

我們知道,多數(shù)地形地表是草方塊;雪地表層是雪方塊;沙漠沙灘地表是沙子。這一步就是在這里調(diào)整topBlock實(shí)現(xiàn)的。草下面是泥土;惡地下面是染色黏土,這是靠fillerblock。

不幸的是,作為骨架的石頭并不能在群系里指定。實(shí)際上,它不依賴群系,而依賴于剛才所說的Generator實(shí)現(xiàn),早在第一步“山海定高”就都做完了。

【底漆其三:八尺畫餅】

這一步我們喜聞樂見地開始生成各種矩形結(jié)構(gòu),包括峽谷、洞穴等天然的,和村莊、礦井等看起來比較“人工”的。他們都是各種MapGenBase在工作。

所謂的八尺,是指MapGenBase這個(gè)generate函數(shù)里,假設(shè)這個(gè)正在被處理的區(qū)塊的區(qū)塊坐標(biāo)為x和z(1區(qū)塊坐標(biāo)=16方塊坐標(biāo)),那么它會(huì)從 x-8遍歷到x+8, z-8遍歷到z+8,對(duì)自身和周圍總共加起來17x17個(gè)區(qū)塊全都畫一次餅。8這個(gè)數(shù)是MapGenBase里range域的默認(rèn)值,原版沒有哪個(gè)子類改過這值,但mod理論上可以通過派生新的類而修改。

所謂的畫餅,是指這里實(shí)際上有一半只畫餅,不實(shí)際生成區(qū)塊里的方塊,只是確定周圍有什么東西。

  • 對(duì)于自然的洞穴來說,這里真的就會(huì)直接修改方塊狀態(tài)。如果這里算出區(qū)塊內(nèi)某一格該被挖掉,那真的就直接挖了。這里我不是很確定是否會(huì)存儲(chǔ),因?yàn)槲疫€沒有特別仔細(xì)地閱讀MapGenCave類源碼。(可讀性很低)。

  • 對(duì)于建筑來說,每種建筑一旦在這個(gè)八方畫餅行為里被發(fā)現(xiàn)要生成建筑,就會(huì)被存到專門的建筑映射表里,下次畫餅的時(shí)候直接讀取該建筑即可。需要指出的是,在這個(gè)八方畫餅的過程中,只有結(jié)構(gòu)的原點(diǎn)(邏輯上的生成起始點(diǎn))會(huì)觸發(fā)這個(gè)生成。

    • 一旦畫餅發(fā)現(xiàn)了一個(gè)起始點(diǎn),它會(huì)生成一個(gè)巨大的抽象結(jié)構(gòu),完全可以超出17x17的范圍。映射表是存在chunk以外的專門列表里的,并且有專門的內(nèi)存和硬盤存儲(chǔ)方式,所以此處沒有問題。

    • 假如畫餅的范圍內(nèi)應(yīng)該有建筑,但是沒有摸到起始點(diǎn),也沒有其他畫餅記錄標(biāo)明這范圍內(nèi)有建筑,那么建筑就暫時(shí)不會(huì)被畫餅。

    • 畫餅的時(shí)候只確定建筑的范圍,確定下礦井里的每條走道有沒有毒蜘蛛刷怪籠、有沒有鐵軌之類的,并不會(huì)立刻去setBlockState。實(shí)際生成要等后面populate,第二階段的“真殖民”。

【底漆定稿】

這些都完成后,代碼計(jì)算天空光照的分布,然后new 一個(gè)Chunk對(duì)象,把它正式從ChunkPremier升格為真正的Chunk,之后就可以設(shè)置TileEntity和Entity了。

第二階段,populate/殖民

Chunk里有兩個(gè)populate,我稱之為真假殖民。

  • 假populate:public void populate(IChunkProvider chunkProvider, IChunkGenerator chunkGenrator)

  • 真populate:protected void populate(IChunkGenerator generator)

假殖民只具有形式上的殖民,不直接做任何事,他只是根據(jù)附近的加載情況調(diào)用真殖民函數(shù)。

這里就是所謂的-X、-Z、-XZ、自身都加載好時(shí),就開始真殖民。假殖民的具體內(nèi)容可以去看實(shí)現(xiàn),總之就是每次假殖民一共涉及九個(gè)區(qū)塊,有四個(gè)可能會(huì)被真殖民。

真殖民,除了海洋神殿外,對(duì)每個(gè)區(qū)塊,實(shí)際內(nèi)容只會(huì)執(zhí)行一次。我們注冊(cè)的worldgenerator也是在這里執(zhí)行。

這里我們調(diào)用ChunkGenerator里的populate去做實(shí)際的工作。

首先觸發(fā)PopulateChunkEvent.Pre事件,然后開始生成礦井、村莊、末地要塞、散落小玩意(叢林神廟,冰原小屋等)、海洋神殿、林地府邸。注意這里就這么多,沒有地獄要塞。

接下來又是一大通雜七雜八的生成,湖泊、熔巖湖、地牢、動(dòng)物、冰。每個(gè)都有自己的forge事件,可以用來分別取消這些事情。

這些事情都做完后,PopulateChunkEvent.Post事件觸發(fā)。第二階段完結(jié),區(qū)塊生成完畢。

那生成礦井時(shí)實(shí)際在做什么呢?在根據(jù)之前算好的那些餅,取其中在本區(qū)塊的部分,往里填內(nèi)容。這里會(huì)實(shí)際一個(gè)個(gè)地碼放方塊和刷怪籠、召喚女巫。需要注意的是,這里只生成那些在本區(qū)塊里的內(nèi)容。(本區(qū)塊是指在進(jìn)行真殖民的區(qū)塊,而不是假殖民的發(fā)起區(qū)塊)這個(gè)過程在ChunkGeneratorOverworld里規(guī)定每個(gè)區(qū)塊只做一次(海洋神殿除外),如果世界種子變動(dòng)(或者建筑寫的不合理),導(dǎo)致真已經(jīng)殖民完畢后,又發(fā)現(xiàn)這里還需要補(bǔ)生成什么建筑,那涼涼了,生成不了。建筑將會(huì)缺失該區(qū)塊的部分。大多數(shù)情況下,因?yàn)槊總€(gè)區(qū)塊第一階段就算清楚了半徑八個(gè)區(qū)塊范圍的內(nèi)容(也包括區(qū)塊自身為核心的情況),而且區(qū)塊的第二階段是從玩家周圍逐步擴(kuò)散著生成的再者是先第一個(gè)階段再第二個(gè)階段,所以正常游玩基本不會(huì)有某個(gè)區(qū)塊進(jìn)入第二階段后還不知道自己頭上該有建筑的情況。


世界平滑生成筆記的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
乐昌市| 正安县| 确山县| 临夏县| 科技| 五家渠市| 泰州市| 华坪县| 万山特区| 皋兰县| 庆城县| 文登市| 安远县| 五寨县| 罗城| 法库县| 岐山县| 资兴市| 克山县| 柳河县| 疏勒县| 子长县| 博爱县| 化德县| 蒲江县| 辉南县| 明溪县| 澜沧| 安国市| 团风县| 夏河县| 都兰县| 巫山县| 格尔木市| 涿州市| 益阳市| 那曲县| 乾安县| 珠海市| 两当县| 道孚县|