UU看書

第七十一章 條件子命令

天才一秒記住【UU看書】地址:www.uukanshu.co

(於2022715重寫)

還記得那些被execute替代的指令嗎?其中,testfor、testforblock、testforblocks和scoreboardplayerstest的功能被合併到了條件子命令中,也就是if和unless子命令。

if和unless這兩個子命令雖說是子命令,但它們畢竟是多條指令融合而成的,自然而然也就有『子命令』的『子命令』,所以說我們是否可以把子命令的子命令稱之為execute的『孫子命令』呢?

(滑稽)

雖然if和unless這兩個子命令有完全相同的格式,但它們倆的效果是完全相反的:

if——如果給出的條件為真(true),也就是條件成立,即透過檢測,執行指令

unless——如果給出的條件為假(false),也就是條件不成立,即透過檢測,執行指令

如果你看不懂上面的描述,沒關係,待會我們會舉些例子,畢竟上面的描述比較偏向於程式設計思維。

條件子命令的子命令,截止MinecraftJava119版本,一共有六個:

block——探測指定位置是否為某種方塊

blocks——將指定區域與另外一個指定區域進行對比

entity——探測指定實體是否存在。

score——探測指定玩家在指定計分項上的分數是否與另一個玩家在指定計分項上的分數符合指定的關係

data——探測指定方塊、實體和儲存NBT是否擁有指定的NBT標籤

predicate——檢查指定謂詞是否透過

其中,data子命令我們放到以後講NBT時再來(這玩意兒作為一個孫子命令,竟然還有三個子命令,也就是說execute有曾孫子了),predicate子命令我們在上一章已經遇到過了,所以我們這邊就先來看看這剩下的四個子命令:

block、blocks、entity和score

其中,前三者實際上根本就不用講。為何呢?讓我們看一下它們的用法:

ifunlessblocklt方塊位置gtlt方塊ID或標籤gt

ifunlessblockslt源區域起始座標gtlt源區域終止座標gtlt比較區域下西北角座標gtlt對比模式maskedallgt

ifunlessentitylt檢測目標:目標選擇器gt

是不是有些熟悉?這難不成就是:

Java113之前

testforlt指定目標:目標選擇器gt探測NBT是否符合

testforblocklt探測位置:座標gtlt方塊ID:字串gt資料值:整數

testforblocklt探測位置:座標gtlt方塊ID:字串gt方塊狀態

testforblockslt源區域起始座標gtlt源區域終止座標gtlt比較區域下西北角座標gtlt模式maskedallgt

Mojang這是直接移植過來的啊,模式名都不帶改一下的。

既然這些子命令和被刪除的那些指令用法幾乎完全一樣,我們這邊也就不多講了,直接上例子。

例子一:

executeasetypeplayeratsifentityedistance1,nbtItemid“minecraftsnowball“,tagdisplayName“text““回城雪球“,typeitem,limit1,sortnearestruntagsaddhub

這條execute有四個子命令:as、at、if和run,其效果是:

將所有線上且活著的玩家分別作為執行者,他們的位置作為執行位置,他們的旋轉角度作為執行朝向,如果執行者周圍1米有一個叫做『回城雪球』的雪球掉落物,就給執行者自己新增上標籤hub。

其中,我們重點看一下if子命令這一段:

ifentityedistance1,nbt物品是叫做『回城雪球』的雪球,typeitem,limit1,sortnearest

這個if子命令用到了entity,也就是相當於113之前的testfor指令,用於探測指定實體是否存在。在這邊,entity的引數就不講了,涉及到nbt,你大概知道是探測一個叫做『回城雪球』的掉落物就行。

讓我們試一試將上面這一段if子命令轉化為testfor指令:

testforer1,name回城雪球,typeitem,c1

是不是立馬就理解了?所以,在使用if子命令的block、entity和blocks子命令時,不妨可以回憶回憶以前的指令是怎麼個用法。

例子二:

testforblocks111111121

這是我們在第三十七章講testforblocks時引用的例子,其作用是『檢測執行者腳下3×3的區域是否和頭頂3×3的區域完全一樣』,現在我們嘗試將這一串指令轉化為113的版本:

executeifblocks111111121all

這個113版本的指令和上面的testforblocks例子的效果是完全一樣的,唯一需要注意的是比較模式引數從可選變成了必選,並且由於testforblocks預設就是all比較模式,所以轉化後要在最後加上個『all』。

你可能會疑惑:run呢?run子命令呢?我那麼大一個run呢?

其實,當一個execute指令中含有條件子命令時,就不一定要含有run子命令了。因為條件子命令也可以看做是一個具有功能的,能夠返回東西的指令(畢竟原來就是由幾條單獨指令結合在一起的嘛)。

例子三:

executeasaatsifblock1redstoneblockruncamerashakeadds

這條指令並不適用於Java版,而是適用於基岩版。

沒錯,這個例子是使用目前基岩版還在測試中的新版execute指令寫成的,不難發現基岩版的新版execute和Java版的幾乎沒差別。

這條指令的作用是:

將所有玩家分別作為執行者,將執行者的位置作為執行位置,將執行者的旋轉角度作為執行朝向,如果執行位置下方一格方塊(玩家腳底下的方塊)是紅石塊,就搖晃玩家的鏡頭(站久就變鬼畜了)。

其中,指令camerashake是基岩版目前較為冷門的一個指令,因為是新新增的所以還有許多人不太瞭解。其實基岩版在116版本時新增了許多有用的指令,以後可能會專門抽出來幾章講一講。

既然說到了基岩版的新版execute,那就不妨來看看基岩版的條件子命令格式和Java版有何不同:

ifunlessblocklt座標gtlt方塊IDgt方塊資料值方塊狀態

看看,基岩版做得多麼人性化,不一定要填寫的引數就不一定要填寫,一定要填寫的引數就一定要填寫,在這一方面Java版的ifblocks就做得不好,為什麼一定要填寫『比較模式』呢?

現在,block、blocks和entity三條子命令我們都會用了,接下來我們來看看score:

ifunlessscoreltA目標gt

a計分項gtlt比較模式gtltB目標gtltb計分項gt

ifunlessscoreltA目標gt

a計分項gtmatcheslt範圍gt

雖然score是用來替代scoreboardplayerstest的,但這個格式第一眼給人的感覺卻像是另外一個東西:scoreboardplayersoperation

但這兩個東西有很大的區別——前者(score)僅僅是對比分數,並不會修改兩個分數;後者(scoreboardplayersoperation)雖然也可以對比,但更多的作用是修改分數。

而且,score可比scoreboardplayersoperation要簡單多了,因為你並不需要考慮A新A舊,以及有多個比較目標的情況,其中的目標選擇器都只能選取一個目標(看來Mojang還是很人性化的對不對?)。

讓我們來仔細看看上面的格式,可以發現相比scoreboardplayerstest,新的score不僅僅可以用來測試單個分數,還可以比較兩個分數。

其中,前面部分的『A目標』『a計分項』兩個引數,以及後面的『B目標』『b計分項』兩個引數,就不需要我多說了吧?前者是用於指定『式子』的左側分數x,後者是用於指定『式子』的右側分數y。

中間部分的『比較模式』引數,也就是填寫在數學上大名鼎鼎的五個符號:

gt——如果分數x大於分數y,則為真

gt——如果分數x大於等於分數y,則為真

——如果分數x等於分數y,則為真

lt——如果分數x小於等於分數y,則為真

lt——如果分數x小於分數y,則為真

舉個例子:

scoreboardobjectivesadddeathdeathCount“死亡榜“

scoreboardobjectivesaddduibidummy“分數對比專用“

scoreboardplayerssetmanydeadtimesduibi50

executeasaifscoresdeathgtmanydeadtimesduibiruntellraws“text““兄弟,你已經死了“,“score““name““s“,“objective““death“,“color““red“,“text““次了!“,“color““reset“

前面的三條指令就不多講了,你應該知道是幹什麼的。最後一條execute指令,將會讓所有玩家分別作為執行者,如果其死亡次數(death計分項中的分數)大於等於50(也就是manydeadtimes這個假玩家在duibi計分項中的值),玩家自己就會收到一條訊息:

兄弟,你已經死了x次了!

其中,x指的是這名玩家在計分板death上的分數,也就是他死亡的次數。

除去這個tellraw內的JSON文字有一部分我們沒學過以外,其他部分還是很容易理解的。

至於matches模式的比較就更簡單了,這就是原本playerstest子命令的功能。其中的『範圍』也就是採用和目標選擇器一樣的『兩點法』。舉個例子:

executeasaifscoresdeathmatches50run同上

這是上面例子的簡化版,功能還是一樣的。

值得注意的是,在基岩版中,『兩點法』可以使用來反選。比如:

executeifscoresdeathmatches1015

這將會測試執行者自己在death計分板上的分數,如果分數不在1015(含)的範圍內就會測試透過。同樣的,基岩版在其他能用到這種『兩點法』的地方基本上也能夠用『』來反選,比如目標選擇器。

最後,我們來看看前一章節就已經碰到過的predicate子命令:

ifunlesspredicatelt謂詞條件IDgt

什麼是謂詞?我在上一章已經解釋過了:

『在我們講資料包之前(也有可能永遠不會講到),你可以將這東西當作是一個打包好的『判斷函式』,在這個『判斷函式』裡面寫了一些東西,可以判斷當前遊戲的情況是否符合指定的條件,如果符合則透過判斷,如果不符合則不透過判斷。比如裡面寫了一個『當前遊戲正在下雨』的條件,當這個條件被呼叫時就會看看現在遊戲是否在下雨,如果下雨就會透過判斷,你的指令也就能夠執行,反之就不會執行。』

舉個簡單的例子,假設有一位大佬做了一個資料包,其名稱空間為『thedarkforest』,裡面有一個叫做『isRainingjson』的謂詞條件。這個條件會判斷當前世界是否在下雨,如果下的是普通的雨,就隨機50的機率使條件成立,如果下的是暴雨,這個機率會提升到80。

我們可以透過如下命令來呼叫這個謂詞條件:

executeifpredicatethedarkforestisRaining

如果你呼叫這個謂詞條件時,遊戲里正在下普通的雨,那麼你的指令就有50的機率能夠執行。如果下的是雷暴雨,那麼就有80的機率會執行。如果是晴天,那麼不可能會執行。

當然,你也可以將if改為unless來反轉條件:

executeunlesspredicatethedarkforestisRaining

這條指令和上面指令的執行條件完全是反著來的:如果是晴天,那麼必定會執行;如果是普通的雨天,有50的機率會執行;如果是雷暴雨,只剩下20的機率會執行。

現在你懂了吧?讓我們來做幾道題目,鞏固一下知識。

第一題:請寫出下列execute指令成功執行的條件

①executeasetypeitematsifblock1minecraftgrassblockrunkills

②executepositioned101010ifblockminecraftairifentityedistance2,limit1,sortnearest

③executeunlessblocks111111000all

第二題:請寫出下列execute指令最大的成功執行次數

①executeaselimit10rotatedasalimit10runtp111

②executeifpredicatethedarkforestisRaining

③executeifscoreescoreerunsayhello

所以這就是我們本章的全部內容,下一章我們將會來初步瞭解一下儲存子命令。

參考答案

第一題:

①所有維度的已載入區塊內必須要有掉落物型別的實體,且至少有一個掉落物的下方方塊是草方塊

②座標10,10,10處的方塊必須是一個空氣方塊,且範圍2米內必須要有一個實體存在。

③執行地點上方3×3的範圍與範圍0,0,03,0,3完全一致,且執行地點上方3×3的範圍沒有超出世界邊界

第二題:

①100(as的引數指定了10個實體,rotated的引數也指定了10個實體)

②1(跟if子命令沒關係)

③0(在Java版中,score子命令的兩個目標選擇器引數都不能指定多個實體)或1(在基岩版中,只要e實際只選擇到了1個實體就行)

如遇章節錯誤,請點選報錯(無需登陸)

新書推薦

獨臂籃球王 穿越瘋狂遊戲 網王之重生越前龍馬 低調修仙,高調復仇 全民轉職之我的被動強無敵 遊戲降臨:諸神破防,我乃真傷刺客 傳奇幽影