第一百四十一章 牛頓心中的Minecraft:下落的方塊
前十二章,我們詳細地了解了生物的共通NBT以及NBT格式。但別忘了,本卷的名字叫做:
實體與NBT
所以接下來,我們就要回歸正題。
——第一節(jié):關于下落的方塊這個大類只有一種實體這檔事
在第一百二十九章里,我們知道了很多關于實體的東東。比如:下落的方塊是個實體。
但有沒有人想過這么一個問題:
我在對下落的方塊這種實體舉例子的時候,為什么舉了一個“下落的方塊”實體的例子?
深入思考的話,我們就會得出一個神奇的結論:下落的方塊這種實體只有一個實體——下落的方塊(FallingSand[1.13之前]、falling_block[1.13及之后])
所以這就可以解釋你在用kill清除實體時,就不會跳出來“下落的沙子”了,更不會跳出來“沙子”(因為這名字已經(jīng)被掉落物占了),而是統(tǒng)一“下落的方塊”。因為人家變成實體之后就統(tǒng)一成了一個實體。
再深入思考,我們又會得到一個問題:
統(tǒng)一成一個實體后,下落的方塊是如何確定自身到底是什么方塊的?
為了解決這個問題,我們可以回顧一下第一百零八章到第一百零九章對掉落物的介紹,就會得出一個對掉落物確定自己到底是什么物品的方法的結論:
用NBT存儲物品的信息
按理來說,用實驗法來研究生物,得出結論后也就差不多了。但我們不是在進行一個生物實驗,而是在學習NBT。況且,就算我們這是一本生物書,生物學它本身也是一個:
...→觀察并思考→提出問題→收集資料→作出假設→制定實驗計劃→實施實驗并記錄→得出結果→研究并思考→提出新的問題→...
所以我們可以研究這個結論,并提出一個新的問題:
為什么掉落物要用NBT來存儲物品的信息呢,而不用item_<物品ID>這樣子每個物品的掉落物都有一個對應的單獨實體?
答案很簡單:
①Mojang這個喜歡3的家伙很懶(主要原因)
?、谌绻@樣子做的話雖然也能達到目的,但游戲會更大
深入思考,我們還會得出一個震驚的結論:
這樣子的話,那么掉落物這個大類也只有一個實體唉:掉落物
實際上還真是這樣的,掉落物確實只有一個實體:minecraft:item
(注意!minecraft:item_frame這個實體實際上是物品展示框,而不是掉落物)
得出了這些結論,我們再來看看下落的方塊。剛才我們發(fā)現(xiàn)下落的方塊只有一個實體:下落的方塊。這說明了什么?
下落的方塊也是使用NBT來存儲方塊的信息。
這就是上面那個問題的答案。
——第二節(jié):下落的方塊的NBT
下落的方塊中存儲著方塊信息的NBT是:
BlockState(復合標簽)
意思是:Block(方塊)State(狀態(tài))
這個復合標簽里有兩個重要的東西:
Name(字符串):這個正在下落的方塊的ID
Properties(復合標簽):可選,這個正在下落的方塊的方塊狀態(tài)
舉個例子。比如,現(xiàn)在這里有一個沙子被炸飛了,那么它的BlockState很有可能是:
{BlockState:{Name:“minecraft:sand“}}
Properties這個先不管,方塊狀態(tài)等我們以后講到你就立馬會了。
我們可以使用/summon minecraft:falling_block(1.11及之后,之前為/summon minecraft:FallingSand)來生成一個下落的方塊。按照生成掉落物的經(jīng)驗,我們就可以搞出一些神奇的東西,比如:
/summon minecraft:falling_block ~~~{BlockState:{Name:“minecraft:diamond_block“}}
執(zhí)行它,你的下半身就會立馬被一個鉆石塊包裹。然后這個鉆石塊開始下落,接著就消失了!
如果你用循環(huán)命令方塊來執(zhí)行,建議你稍微改一下指令:
/summon minecraft:falling_block ~~2 ~{BlockState:{Name:“minecraft:diamond_block“}}
開啟!你就會發(fā)現(xiàn)你搞出來了一個不斷在空中振動(???)的沒有碰撞箱(???)的鉆石塊(???)。
這到底是怎么一回事呢?
實際上還有更有趣的。
如果你在這個不斷振動的鉆石塊的位置上放置一個鉆石塊。如果下面是空的,你就會發(fā)現(xiàn):
你放置的這個鉆石塊給這個在不斷振動的鉆石塊給震掉下來了!
還可以更奇葩嗎?
可以!
如果下面有方塊,你還放的話,你就會發(fā)現(xiàn):
你放置的這個鉆石塊給這個在不斷振動的鉆石塊給感染了!成了鉆石塊下落,每到地面就重新下落,直到下面被打掉!(建議可以的親自去做一下這個實驗)
為什么會成這個樣子呢?
因為Time沒填,默認為0。
Time(Int整形):該下落的方塊已存在的刻數(shù),不設置默認為0。如為0,則:
當Time從0變?yōu)?時,如該實體的位置上的方塊與其存儲的方塊一致,則繼續(xù)下落,并刪除該方塊。不一致,則刪除該實體。(這應該就是方塊開始下落時游戲的替換原理)
如不為0,當Time值大于600(30秒)或Time值大于100(5秒)時超出建筑限制(y大于255或小于0),就變?yōu)榈袈湮铩?p> 所以,為了讓這個鉆石塊能夠快快樂樂地下落,我們就需要:
/summon minecraft:falling_block ~~~{BlockState:{Name:“minecraft:diamond_block“},Time:1}
然后你就會發(fā)現(xiàn):
鉆石塊竟然不浮空了,而是成功掉了下來!
?。═he strange laughter in Newton's coffin frightened the tourists around him.
——British Broadcast Corporation report)
BlockState和Time這兩個標簽是必填項。除此之外,還有一些非必填項:
TileEntityData(復合標簽):該實體存儲的方塊的方塊實體標簽
DropItem(Byte字節(jié)型:1或0[true|false]):該實體被破壞后是否掉落其方塊的物品形式。為1時掉落,但如果其方塊沒有對應的物品則仍然不會有物品掉落。
HurtEntities(Byte字節(jié)型:1或0[true|false]):該實體掉落時碰到其他實體是否對其造成傷害。為1時造成。
FallHurtMax(Int整形):被砸中的實體所承受的傷害上限。一般的方塊默認為40滴血(20?)
FallHurtAmount(Float單精度浮點型):給被砸中的實體造成的傷害=FallDistance(當前實體已經(jīng)墜落的距離)×FallHurtAmount(該標簽)。一般的方塊默認為2。
舉個例子,比如你召喚一個下落的水方塊(???):
/summon minecraft:falling_block ~~~{BlockState:{Name:“minecraft:water“},Time:1,DropItem:0,HurtEntities:1,F(xiàn)allHurtMax:150,F(xiàn)allHurtAmount:1.1}
召喚后,你會發(fā)現(xiàn)你看不到下落的水方塊。唯一能體現(xiàn)它存在的只有在它落地變?yōu)榉綁K之后。
而如果你從25米高空扔下一個這樣的下落水方塊,假設下面有一個正在整理物品的有20滴血的玩家。幾秒后,他就會原地去世,同時原地會憑空出現(xiàn)一攤水(忽然發(fā)現(xiàn)這可以做一些有趣的東西,因為這就像一個活生生的人其體內(nèi)除了水其他物質(zhì)都突然憑空消失的樣子)。
而他受到了多少傷害呢?
根據(jù)“給被砸中的實體造成的傷害=FallDistance×FallHurtAmount”這個公式,我們可以輕易得出:
給被砸中的實體造成的傷害=25×1.1=27.5(13.25?)
怪不得這名玩家會原地去世。
(TileEntityData這個標簽等我以后講方塊時候再來了解)
——第三節(jié):下落的方塊的神奇用途
下落的方塊有許多有趣的用途。
在第一百一十二章到第一百一十三章,我們了解了實體的通用標簽。在此之中,有這么幾個標簽和下落的方塊配合時會表現(xiàn)得很好:
NoGravity(Byte字節(jié)型):控制實體是否掉落
Motion(列表):記錄實體在dX、dY、dZ三個軸的速度
上面我們搞出來一個神奇的不斷在空中振動的沒有碰撞箱的鉆石塊。那我們可以弄出一個靜止在空中的可以穿過去的鉆石塊嗎?
可以!
NoGravity是控制實體是否掉落的,當為1時實體不會墜落。所以我們可以:
/summon minecraft:falling_block ~~~{BlockState:{Name:“minecraft:diamond_block“},Time:1,NoGravity:1}
然后......
媽媽你快看!這個鉆石塊它浮在空中唉!看,我可以走過去!也可以回來!現(xiàn)在我頭在鉆石塊里面!
(Newton's coffin lid suddenly shook, frightening passers-by.
——British Broadcast Corporation report)
只不過這有一個壞處,就是當Time過600它就會變成掉落物。
所以我們可以這樣子:
重復執(zhí)行/summon minecraft:falling_block ~~5 ~{BlockState:{Name:“minecraft:diamond_block“},Time:1,NoGravity:1,DropItem:0,CustomName:“{\“name\“:\“diamond_block\“}“}→連鎖有條件的保持開啟/kill @e[type=falling_block,name=“diamond_block“]
這樣子,我們就可以一直保持這個幽靈鉆石塊存在。
知道了如何坑朋友之后,我們還可以玩點新花樣:
Motion這個標簽可以讓我們設置實體的運動。通過它+MC的物理運動,我們就可以弄出一些新的東西,比如一個最基礎的:
/summon minecraft:falling_block ~~~{BlockState:{Name:“minecraft:redstone_block“},Time:1,DropItem:0,Motion:[0.7d,0.5d,0.3d]}
?。▽α耍敃r對Motion是一筆帶過,這里講一下。Motion的值是列表,列表里有三個值:
[dX速度,dY速度,dZ速度],值類型都是雙精度浮點型(Double:D),單位是米/刻。)
然后你就會發(fā)現(xiàn)飛出了一個紅石。
好像也沒什么稀奇的。但別忘了,一些全身由人類五臟中以代謝功能為主的一個器官構成的人會玩出一些新花樣,比如制作一個神奇的方塊動畫。
如果你不是這樣的人,那么你可以干些其他的實驗,比如一直重復執(zhí)行這條指令,命令方塊會幫你造出一個很神奇的建筑。
你也可以亂改數(shù)據(jù),這新花樣是有很大的發(fā)揮空間的。
——第四節(jié):結束
現(xiàn)在我們來總結一下:
[必]BlockState(復合標簽)
——[必]Name(字符串):這個正在下落的方塊的ID
——Properties(復合標簽):可選,這個正在下落的方塊的方塊狀態(tài)
[必]Time(Int整形):該下落的方塊已存在的刻數(shù),不設置默認為0。如為0,則當Time從0變?yōu)?時,如該實體的位置上的方塊與其存儲的方塊id一致,則繼續(xù)下落,并刪除該方塊。不一致,則刪除該實體。如不為0,當Time值大于600(30秒)或Time值大于100(5秒)時超出建筑限制(y>255或<0),就變?yōu)榈袈湮铩?p> TileEntityData(復合標簽):該實體存儲的方塊的方塊實體標簽
DropItem(Byte字節(jié)型:1或0[true|false]):該實體被破壞后是否掉落其方塊的物品形式。為1時掉落,但如果其方塊沒有對應的物品則仍然不會有物品掉落。
HurtEntities(Byte字節(jié)型:1或0[true|false]):該實體掉落時碰到其他實體是否對其造成傷害。為1時造成。
FallHurtMax(Int整形):被砸中的實體所承受的傷害上限。一般的方塊默認為40滴血
FallHurtAmount(Float單精度浮點型):給被砸中的實體造成的傷害=FallDistance(當前實體已經(jīng)墜落的距離)×FallHurtAmount(該標簽)。一般的方塊默認為2。
OK本章就到這里了,我們下一章再見。
===========資料============
——下落的方塊歷史
Java版Infdev
20100618——加入了應用于沙子和沙礫的ID FallingSand。
Java版
1.0.0——Beta 1.9 Prerelease 6——加入了可以下落的方塊龍蛋。
1.4.2——12w41a——加入了可以下落的方塊鐵砧。
1.7.2——13w39a——加入了可以下落的方塊紅沙。
1.12——17w06a——加入了可以下落的方塊混凝土粉末。
1.13——17w47a——重命名 FallingSand 到 falling_block。
1.14——18w45a——加入了可以下落的方塊腳手架。
攜帶版Alpha
0.6.0——沙子和沙礫現(xiàn)在可以下落了。
0.9.0——build 1——加入了可以下落的方塊紅沙。
0.12.1——build 1——加入了可以下落的方塊鐵砧。
攜帶版
1.0.0——alpha 0.17.0.1——加入了可以下落的方塊龍蛋。
1.1.0——alpha 1.1.0.0——加入了可以下落的方塊混凝土粉末。
基巖版
1.8.0——beta 1.8.0.8——加入了可以下落的方塊腳手架。
原主機版
TU1——————1.00———————————加入了可以下落的方塊沙子和沙礫。
TU9——CU1——————Patch 1——————加入了可以下落的方塊龍蛋。
TU14——————1.05———————1.0.1——加入了可以下落的方塊鐵砧。
TU31——CU19——1.22—Patch 3——————加入了可以下落的方塊紅沙。
TU53——CU43——1.49—Patch 23——1.0.3——加入了可以下落的方塊混凝土粉末。
—————————1.83——————————加入了可以下落的方塊腳手架。
New Nintendo 3DS版
0.1.0——加入了可以下落的方塊沙子、沙礫、紅沙和鐵砧。
1.7.10——加入了可以下落的方塊龍蛋。
1.9.19——加入了可以下落的方塊混凝土粉末。
++++++++++++++++
王五正在翻看Minecraft Wiki中文,去學習下落的方塊的使用方式。張三在旁邊修理刷物機。
張三叮叮當當?shù)匕阉⑽餀C搞了一陣子后,發(fā)現(xiàn)得出去到主城東方的那座山里的黑市買些材料。由于他們幾個的工作,導致他們的基地是在離主城很遠的一座山下面。如果馬不停蹄,最快也要三天才能到那里。于是他就收拾了工具,打算把這事情先放一放。
張三收拾著工具,突然發(fā)現(xiàn)門被打開了,走進來一個人。張三想把這人哄出去,想了一下最后站起來問:“你是誰?你從哪兒來?到這要干什么?”
他回答:“我叫劉一,從主城丁龍區(qū)來,來這是王五邀請我的。”劉一說著,眼角的余光發(fā)現(xiàn)王五愁眉苦臉。他很好奇,正好王五也注意到劉一來了,便招呼劉一過來。張三見是王五請來的,便不再說什么。
劉一第一句話就是:“王五啊,發(fā)生甚么事了?”
王五打開了幾張游戲截圖給劉一看。劉一一看,原來是剛才,有兩個下落的方塊,在三十多米高的高空,一個質(zhì)量九百多公斤,一個質(zhì)量八百多公斤。王五說,有一個是他一直重復執(zhí)行弄出來的沙子,就是很奇怪一生成就消失,而且他都寫了是diamond_block,大佬你能不能教教我這是怎么一回事,幫助修復一下我的下落的方塊。劉一說:“可以。你在游戲里弄來弄去,不好,得靈活變通,去看看Minecraft Wiki中文?!蓖跷宸瘩g:“剛剛我就在看唉,這就是我按照上面弄出來的!”劉一思考了一下,回:“你把指令給我看一下,應該是Time值的問題。”
王五打開了命令方塊,只見上面寫著:
/summon minecraft:falling_block {BlockState:{Name:“minecraft:diamond_block“},Time:1}
劉一仔細觀察,發(fā)現(xiàn)了一個問題:“你這沒有坐標啊,應該是/summon minecraft:falling_block ~~~{BlockState:{Name:“minecraft:diamond_block“},Time:1}?!?p> “哦,原來如此?!蓖跷暹@才想起來/summon的格式是/summon <實體id>[坐標:XYZ][NBT]。
試了試,可以正常下落,但還是沙子。
“下落的問題是解決了,但這仍然是沙子啊,不是鉆石塊。這該怎么辦?”王五看著劉一,眼睛睜的賊大。劉一看著這個好奇寶寶,發(fā)現(xiàn)越看越可愛,于是摸了一下王五的頭,說:“這應該是你標簽名沒寫對或是id沒對?!?p> 王五仔細檢查了一下,BlockState正確,Name正確,minecraft:diamond_block也正確。
劉一這才發(fā)現(xiàn)事情不簡單,皺起了眉頭仔細思考。他突然看到游戲界面左上角的Minecraft 1.12.2,靈光一閃,拍手叫道:“是不是版本的問題?!”
王五一聽,趕緊打開Minecraft Wiki中文,點開History,發(fā)現(xiàn)了一個問題:下落的方塊中文百科最早也已經(jīng)是2020年4月13日09:31。王五試圖在英文百科上找,發(fā)現(xiàn)頁面雖早,但數(shù)據(jù)值那個頁面早已不見。
這下子該如何是好?在發(fā)現(xiàn)Minecraft Wiki其早期記載的資料已經(jīng)無法參考了之后,兩人就像是熱鍋上的螞蟻,因為對于這種事情兩人還是第一次遇到。
張三已經(jīng)整理完了工具,正無事可干打算拿起手機看一下敦煌防護林已經(jīng)反轉多少次時,突然發(fā)現(xiàn)旁邊還有兩個蹦來蹦去的螞蟻,于是拿起了一個西瓜,問兩人發(fā)生了什么事。
在了解了具體情況后,張三感到震驚——Minecraft Wiki對于早期的資料保護竟然這么懈怠,萬一以后Minecraft30周年,新玩家想要回顧的時候,如果Minecraft Wiki還這樣,那么他們或許就只知道Minecraft有豬靈和僵尸豬靈,卻不知道在很久以前只有僵尸豬人。這還是比較重要的資料,如果像是更生僻的比如NBT,或許情況會更糟。
“互聯(lián)網(wǎng)還真是沒有記憶啊?!睆埲袊@道。感嘆雖感嘆,張三還是仔細想了一下。這一想,他突然想到一點:“扁平化!”
劉一愣了一下,然后趕緊打開扁平化的頁面。果真,還真有這么一句:
下落的方塊的Block數(shù)據(jù)和Data數(shù)據(jù)合并成了BlockState。
但這里并沒有講到“Block”和“Data”到底是個什么鬼。
進展很快就停止了。三人繼續(xù)想,但再也沒有了新點子。
最怕空氣突然安靜。
王五再一次打開下落的方塊頁面。他突然發(fā)現(xiàn)還有一個:
教程/下落的方塊
點開歷史,他很快從悲哀轉為震驚,接著又轉為驚喜,最后情緒化成了聲音:“哦吼。哦吼!哦吼!??!”
三人迅速瀏覽了歷史,得出了一些重要的結論:
?、貸ava1.13扁平化之前,BlockState是分為兩個標簽:Data和Block
②Block是字符串,在里面寫入方塊英文id就可以指定該下落的方塊代表的方塊
?、跠ata在教程/下落的方塊里并未提及,但應該是和Properties一樣,值為復合標簽,代表該方塊的方塊狀態(tài)。
?、茉诟绲陌姹荆?.8以前),沒有Block標簽,而是使用TileID標簽。TileID應該是Int整形,在值里填上方塊數(shù)字id就可以指定該下落的方塊所代表的方塊。這就可以解釋為什么現(xiàn)在的WIki在介紹Time標簽時有這么一句話:“Time刻數(shù)在從0變?yōu)?的這段時間里,如果在它的位置上方塊的 ID 和實體 TileID 都相同,那么這個方塊就不會被刪除......”
最終,王五得出了一個正確的指令:
/summon minecraft:falling_block ~~~{Block:“minecraft:diamond_block“,Time:1}
使用該指令,王五成功在1.12.2版本召喚出一個下落的鉆石塊!