首頁(yè) 游戲

Minecraft指令手冊(cè)

第一百五十八章 重新認(rèn)識(shí)NBT

Minecraft指令手冊(cè) 你好MC 3287 2023-01-01 15:18:29

  看到這個(gè)題目,你是不是大吃一驚?NBT怎么還要重新認(rèn)識(shí)?

  別太驚訝。還記得最開始我們接觸到NBT的時(shí)候嗎?在第五十四章的最后,我指出這其實(shí)并不是真正的NBT,而是Mojang專門搞出來(lái)給人看的『SNBT』,即『Stringified NBT』,『字符串化的二進(jìn)制命名標(biāo)簽』。在之后的章節(jié),我們也重點(diǎn)了解了SNBT,知道了它的格式和使用方法。而現(xiàn)在,我們已經(jīng)了解并掌握了許多物品和實(shí)體的NBT,這時(shí)候,也是時(shí)候來(lái)認(rèn)識(shí)一下真正的樹狀結(jié)構(gòu)的NBT,這樣子你才能真正理解接下來(lái)的內(nèi)容。

  —————分割線—————

  樹,是大自然的鬼斧神工。它提供了人類賴以生存的氧氣和食物,也給了人類許多靈感。

  一棵樹,有樹根、樹干、樹葉。它們均發(fā)源于一點(diǎn),我們可以把這一點(diǎn)稱為——根(root)。為了方便講解,我們接下來(lái)忽略位于地底下的樹根,只看樹干和樹葉。

  樹干上有許多分叉點(diǎn),我們可以把這些分叉點(diǎn)稱為——節(jié)點(diǎn)(node)。通過(guò)節(jié)點(diǎn)可以長(zhǎng)出一些樹葉或新的樹干,在新的樹干上則又有許多新的節(jié)點(diǎn),分叉出更多的樹葉和樹干。

  一個(gè)節(jié)點(diǎn)所分叉出的所有樹葉和樹干,以及這些樹干上所有的節(jié)點(diǎn),可以全部視為這個(gè)節(jié)點(diǎn)的值(value)。你可以這么理解——這些樹葉和樹干,就是這個(gè)節(jié)點(diǎn)所存在的價(jià)值。如果沒有這些樹葉和樹干,那么這個(gè)節(jié)點(diǎn)也將不復(fù)存在。

  這就是一棵樹——一顆完全由根、節(jié)點(diǎn)和值構(gòu)成的樹?。▓D158-1)

  根其實(shí)是一種特殊的節(jié)點(diǎn),它是整個(gè)樹的開始,所以整個(gè)樹都可以看作是根的值。

  除了根,其他節(jié)點(diǎn)都可以取名字。在同一個(gè)樹干上,每個(gè)節(jié)點(diǎn)的名字都必須是獨(dú)一無(wú)二的,以防與其他節(jié)點(diǎn)弄混。

  比如,我們可以給根上面的第一個(gè)節(jié)點(diǎn)取名『Apple』、第二個(gè)節(jié)點(diǎn)取名『Beluga』。這樣子,我們就不容易搞混這兩個(gè)節(jié)點(diǎn),也可以方便用名稱指代這兩個(gè)節(jié)點(diǎn)。

  假設(shè)第一個(gè)節(jié)點(diǎn)長(zhǎng)出了一條樹干,上面也有一個(gè)節(jié)點(diǎn),我們給它取名為『Cen』。而這個(gè)『Cen』節(jié)點(diǎn)也長(zhǎng)出了一條樹干,上面也是有一個(gè)節(jié)點(diǎn),我們給他取名『Sama』(圖158-2)。那么,如果其他人也要尋找『Sama』節(jié)點(diǎn),該如何尋找呢?

  假設(shè)其他人只知道這個(gè)節(jié)點(diǎn)叫『Sama』然后去尋找它,在節(jié)點(diǎn)很多的情況下這無(wú)疑是大海撈針。而且有可能在不同樹干上的其他節(jié)點(diǎn)也叫『Sama』。這時(shí)候該怎么辦?

  我們來(lái)看一個(gè)現(xiàn)實(shí)生活中的情景:

  你此時(shí)正在學(xué)校里上課,老師要求你將書翻到這節(jié)課要講的『第三模塊第五單元第一課』。你肯定是先找到『第三模塊』,然后找到『第五單元』,最后找到『第一課』。老師不可能只告訴你『翻到第一課』,因?yàn)槊總€(gè)單元都有自己的第一課。老師這樣說(shuō),讓你得知了『第一課』的路徑(path),于是你才找到了這節(jié)課要講的『第一課』。

  回到上面的問(wèn)題,答案已經(jīng)十分明顯了——那位要尋找『Sama』節(jié)點(diǎn)的,應(yīng)該去詢問(wèn)得知『Sama』節(jié)點(diǎn)具體位置的人,比如我們。然后我們應(yīng)該將『Sama』節(jié)點(diǎn)的路徑告訴他,也就是:

  Apple.Cen.Sama

  這就是『Sama』節(jié)點(diǎn)的路徑。如你所見,一個(gè)路徑就是『節(jié)點(diǎn).節(jié)點(diǎn).節(jié)點(diǎn)』的形式,從左往右的節(jié)點(diǎn)指出了一條從根開始通向終點(diǎn)節(jié)點(diǎn)的具體道路(圖158-3)。

  路徑既然可以用來(lái)找到節(jié)點(diǎn),那么他們應(yīng)該也就能夠表示節(jié)點(diǎn),乃至于表示這個(gè)節(jié)點(diǎn)的值。畢竟『一個(gè)節(jié)點(diǎn)』只對(duì)應(yīng)『一條路徑』,『一條路徑』也只對(duì)應(yīng)『一個(gè)節(jié)點(diǎn)』,『一個(gè)節(jié)點(diǎn)』也只能有『一個(gè)值』。因此,如果我們?cè)僖淮慰聪颉篠ama』節(jié)點(diǎn)的路徑『Apple.Cen.Sama』,我們就會(huì)發(fā)現(xiàn)『Apple.Cen.Sama』既可以用來(lái)表示『Sama』節(jié)點(diǎn),也可以用來(lái)表示『Sama』節(jié)點(diǎn)的值。(只不過(guò)Sama節(jié)點(diǎn)的值是空的)

  又比如說(shuō),路徑『Apple.Cen』既表示節(jié)點(diǎn)『Cen』,也表示節(jié)點(diǎn)『Cen』的值——從『Cen』節(jié)點(diǎn)長(zhǎng)出的樹干以及上面的『Sama』節(jié)點(diǎn)。

  看起來(lái)像『節(jié)點(diǎn).節(jié)點(diǎn)』這樣的路徑解決了尋找節(jié)點(diǎn)以及節(jié)點(diǎn)的值的問(wèn)題,但如果『Apple』節(jié)點(diǎn)又長(zhǎng)出了一條新的樹干,這條新的樹干上又有一個(gè)節(jié)點(diǎn)『Touhou』該怎么辦(圖158-4)?此時(shí)『Sama』節(jié)點(diǎn)的路徑又該如何表示?

  很明顯,現(xiàn)在『Apple』節(jié)點(diǎn)長(zhǎng)出了兩條樹干(另外兩條是貫穿Apple節(jié)點(diǎn)的從根長(zhǎng)出來(lái)的主干,其實(shí)是一條,不要搞錯(cuò)了),我們需要有一個(gè)正確的方式來(lái)表示這兩條樹干。比如我們可以取名字,但這似乎過(guò)于麻煩了,而且容易把樹干和節(jié)點(diǎn)搞混。最好也最簡(jiǎn)單的方法就是給樹干編『號(hào)數(shù)』,也就是使用索引(index)。

  將節(jié)點(diǎn)『Cen』所在的樹干編上索引0,那條新的樹干編上1,然后我們只需要在路徑中的『Apple』后面,『.』前面加上樹干的索引,就大功告成了:

  Apple[0].Cen.Sama

  其中,[0]指的就是索引為0的樹干,也就是『Cen』節(jié)點(diǎn)所在的那一條。通過(guò)這種方法,我們也可以表示『Touhou』節(jié)點(diǎn):

  Apple[1].Touhou

  不過(guò),這些東西跟NBT有什么關(guān)系呢?

  這個(gè)問(wèn)題問(wèn)得好?,F(xiàn)在,讓我們?cè)賮?lái)看看另外一顆樹(圖158-5):

  根

  │

  ├id:“minecraft:jukebox“

  ├IsPlaying: 1b

  │

  ├ RecordItem:

  │├Count: 1b

  ││

  │└id:“minecraft:music_disc_ward“

  │

  ├x:-1

  ├y: 60

  ├z:-53

  │

  ├RecordStartTick: 0L

  └TickCount: 514L

  仔細(xì)看這東西,你有沒有發(fā)現(xiàn)?

  如果沒有發(fā)現(xiàn),那讓我們把這棵樹的形態(tài)轉(zhuǎn)化一下,變成:

  {id:“minecraft:jukebox“,x:-1,y:60,z:-53, IsPlaying :1b, RecordItem :{Count:1b,id:“minecraft:music_disc_ward“}, RecordStartTick:0L, TickCount:514L}

  這不就是SNBT嗎?

  沒錯(cuò),上面那棵樹,其實(shí)就是下面這個(gè)SNBT的NBT形式,游戲所看到的NBT就長(zhǎng)這個(gè)模樣。

  這棵NBT其實(shí)就是一個(gè)放在(-1,60,-53)的唱片機(jī)的方塊實(shí)體。我們會(huì)在第十八卷具體了解到方塊以及方塊實(shí)體的內(nèi)容,在這邊你只需要將方塊實(shí)體當(dāng)作是方塊NBT即可。從這棵NBT中,我們和游戲都可以得知,這個(gè)唱片機(jī)此時(shí)正在播放(IsPlaying)ward唱片(RecordItem),并且已經(jīng)播放了25.7秒(TickCount),這個(gè)唱片機(jī)在此之前沒有播放過(guò)任何唱片(RecordStartTick)。

  你可以在Minecraft Wiki上搜索『唱片機(jī)』來(lái)具體了解上述標(biāo)簽的作用,NBT都講到這了你應(yīng)該不可能看不懂Minecraft Wiki上關(guān)于NBT的內(nèi)容吧?

  回到這棵NBT樹上,仔細(xì)觀察它與它的SNBT形式,你應(yīng)該不難發(fā)現(xiàn),id節(jié)點(diǎn)的樹葉上寫著『“minecraft:jukebox“』,x、y、z節(jié)點(diǎn)的樹葉上寫著『-1』『60』和『-53』,IsPlaying節(jié)點(diǎn)的樹葉上寫著『1b』,RecordStartTick和TickCount節(jié)點(diǎn)的樹葉上寫著『0L』和『514L』。在SNBT中,上面這些節(jié)點(diǎn)所對(duì)應(yīng)的標(biāo)簽的值的類型都是字符串、Int整型、Byte字節(jié)型和Long長(zhǎng)整型。也就是說(shuō),String字符串、Byte字節(jié)型、Short短整型、Int整型和Long長(zhǎng)整型,以及其他的浮點(diǎn)數(shù)數(shù)據(jù)類型,在NBT樹中都無(wú)一例外承載于『樹葉』之上。

  而RecordItem節(jié)點(diǎn),長(zhǎng)出的是一條樹干,樹干上有id和Count節(jié)點(diǎn)。在SNBT中,RecordItem標(biāo)簽的值類型是復(fù)合標(biāo)簽,復(fù)合標(biāo)簽內(nèi)也有id和Count標(biāo)簽。也就是說(shuō),『復(fù)合標(biāo)簽』在NBT樹中所體現(xiàn)出來(lái)的就是一條樹干。

  也就是說(shuō),整個(gè)NBT標(biāo)簽其實(shí)就是一個(gè)復(fù)合標(biāo)簽?

  沒錯(cuò),確實(shí)是這樣。

  通過(guò)上面的觀察,你應(yīng)該已經(jīng)總結(jié)出來(lái)了NBT樹與SNBT的一些對(duì)應(yīng)關(guān)系,比如節(jié)點(diǎn)對(duì)應(yīng)標(biāo)簽名,樹干對(duì)應(yīng)復(fù)合標(biāo)簽。那……列表呢?在NBT樹中,列表又是長(zhǎng)什么樣子?

  還記得上面的『Apple』節(jié)點(diǎn)嗎,我們?cè)谘芯抗?jié)點(diǎn)的路徑(path)時(shí),遇到了一個(gè)節(jié)點(diǎn)長(zhǎng)出兩條樹干的情況。如果我們以SNBT的形式將『Apple』節(jié)點(diǎn)表示出來(lái),其實(shí)就是這樣的:

  {Apple:[{Cen:{Sama:}},{Touhou:}]}

  在SNBT中,『Apple』標(biāo)簽的值就是一個(gè)復(fù)合標(biāo)簽列表!列表的順序規(guī)定了列表內(nèi)每個(gè)元素(element)的索引值(index)。和生活中數(shù)數(shù)不一樣的是,列表的索引并不是從1開始,而是從0開始,這就是為什么我們給『Cen』節(jié)點(diǎn)所在的樹干標(biāo)上索引0而不是1的原因。

  同理,如果一個(gè)節(jié)點(diǎn)長(zhǎng)出了一堆承載相同類型數(shù)據(jù)的葉子,那這個(gè)節(jié)點(diǎn)的值也是一個(gè)列表(或數(shù)組)。如果一堆值是列表的節(jié)點(diǎn)擠在一起,那這一堆節(jié)點(diǎn)所形成的大節(jié)點(diǎn)自然也是一個(gè)值是列表的節(jié)點(diǎn),而且這列表還是列表的列表:

  {節(jié)點(diǎn):[[{},{},…],[{},{},…],…]}

  \\它的SNBT形式\\

  只不過(guò),像這樣的二維列表,甚至是三維列表,我們?cè)谥岸紱]有碰到過(guò),在以后也很有可能不會(huì)碰到。

  這就是NBT的樹狀結(jié)構(gòu),也就是真正的NBT??雌饋?lái)講了很多,但其實(shí)內(nèi)容并不是很難,唯一的難點(diǎn)估計(jì)是語(yǔ)言比較枯燥。

  但這并不是本章唯一的重點(diǎn)。你應(yīng)該還記得剛才講的『節(jié)點(diǎn)的路徑』。相比于NBT的樹狀結(jié)構(gòu),我們會(huì)在接下來(lái)的內(nèi)容中更常碰見節(jié)點(diǎn)的路徑(path)。其實(shí),這個(gè)『節(jié)點(diǎn)的路徑』,就是NBT路徑(NBT path)——用來(lái)從NBT數(shù)據(jù)樹中指定一系列特定元素的描述性標(biāo)簽。

  在接下來(lái)的/data指令中,NBT路徑是非常重要的一個(gè)東西,可以說(shuō)只要你掌握了NBT路徑,你就幾乎掌握了/data指令。我們會(huì)在下一章更加深入了解NBT路徑,但在此之前,請(qǐng)你『務(wù)實(shí)一點(diǎn),把NBT的戰(zhàn)術(shù)打法,NBT樹的這個(gè)理念先搞懂』——范志毅,國(guó)家Minecraft指令教學(xué)前任大將軍,此句話為他2013年6月15日在評(píng)價(jià)Minecraft指令教學(xué)時(shí)所說(shuō)的名言警句。

  本章到此為止。

  對(duì)了,2023新年快樂(lè)!

按 “鍵盤左鍵←” 返回上一章  按 “鍵盤右鍵→” 進(jìn)入下一章  按 “空格鍵” 向下滾動(dòng)
目錄
目錄
設(shè)置
設(shè)置
書架
加入書架
書頁(yè)
返回書頁(yè)
指南