首页 男生 游戏竞技 Minecraft指令手册

第六十九章 修饰子命令 上 三要素与修饰子命令

Minecraft指令手册 你好MC 5541 2024-07-09 15:29

  (于2022/7/14重写)

  在第七章,我们总结出了指令执行的三要素:执行者、执行位置和参数。

  但在经过了六十几章的学习后,我们会发现,这三要素似乎有点不对啊?

  哪里不对呢?

  执行者肯定会有,就算没有也会有默认值;执行位置肯定也会有,并且它照样也有默认值。

  但参数呢?

  虽然有些参数也有默认值,但有些指令它根本就没有参数啊!比如/seed指令,根本就不需要参数。

  所以在这,我们必须纠正一个已经持续了几十个章节的错误,那就是:

  参数并不是指令必须要有的东西,它不算是指令执行的要素。

  那照这样子说,我们的三要素是不是就要变为二要素了?

  NONONONO。三要素还是三要素,虽然参数不是了,但有一个一直以来都在被我们忽略的东西能够被当作是指令执行的三要素。

  什么呢?难不成是目标选择器的基准点?

  答案是:执行朝向。

  执行朝向是一个神奇的东西。我们第一次遇见它在第九章,花了较长的篇幅讲解了水平旋转角度和垂直旋转角度;第二次遇见它在第二十六章,又讲了一遍水平旋转角度;第三次遇见在第六十四章,花了较长的篇幅讲解了相对旋转角度和基准部位;接下来,我们可能还要再次遇见它,讲解它和局部坐标的关系。

  不难发现,相对于执行位置、执行者,我们却很少遇见执行朝向。但每次执行朝向一出现,我们就得花大量的笔墨去讲解它。所以说,执行朝向是指令执行三要素中最难理解的部分,它不仅仅只是一个朝向那么简单,它还关系到许许多多的东西。

  现在,我们总结出了新的指令执行三要素:执行者、执行位置和执行朝向。其中,执行位置还包括维度和坐标;执行朝向包括旋转角度和基准部位。而这些东西,我们都可以通过新版execute的8条修饰子命令来自定义:

  as ——更改执行者

  at ——更改执行位置(包括维度和坐标)和旋转角度为指定实体的位置和旋转角度

  facing ——更改旋转角度

  rotated——更改旋转角度

  anchored——更改基准部位

  br /ositioned ——更改执行位置中的坐标

  in ——更改维度位置

  align——将执行位置中的坐标转化为方块坐标

  这一章,我们就先讲几个简单的:as、at和in。

  as子命令可以更改执行者,类似于旧版的『执行者』参数,但其仅仅只会更改执行者,而旧版的『执行者』参数还会更改旋转角度。

  as子命令的使用十分简单,如下:

  ... as <执行者:目标选择器>...

  举个例子:

  /execute as @a run 一条指令

  (run子命令虽然我们没有讲过,但其实你应该也懂了,『run +命令』就可以运行指令)

  这将会将指令执行者更改为所有玩家自身,指令在运行时会分别将每个玩家作为执行者运行一遍。唉,什么叫『指令在运行时会分别将每个玩家作为执行者运行一遍』呢?,之前讲旧版的execute时可从未提到过啊?

  举个小小的例子,你就知道了:

  /execute as @e[tybr /e=villager] run scoreboard br /layers add villager_count an_objective 1

  假设villager_count这个假玩家在计分项an_objective上的分数原先为0。请你猜一猜,运行这条指令过后,分数将会变为多少?一定会变为1吗?

  上面这条指令的意思是:将所有村民作为执行者,给villager_count在计分项an_objective上的分数加上1。而指令在运行过程中,会将每位村民都作为执行者运行一遍指令,因此最终指令将会运行『村民总数量』遍,我们也成功地将村民的总数量作为分数记到了计分板上。假设现在有两名村民,最终得到的分数将会是2,因为这两个村民都分别运行了一遍『scoreboard br /layers add villager_count an_objective 1』。

  为什么指令在运行过程中,会将每位村民都作为执行者运行一遍指令,而不是直接将所有村民作为执行者,仅仅运行一遍指令?

  原因很简单:每条指令执行过程中,执行者、执行位置、执行朝向分别都只能有一个。

  请你一定要记住这个知识点,因为接下来我们将会需要运用这个知识点来解决一些问题。

  对了,既然新版本的execute有这个特性,那旧版本呢?

  也是有的。

  所以你能想到这有什么用处吗?

  testfor指令虽然可以用来探测指定实体是否存在,但想要将数量储存到计分板中还需要一个/stats指令,十分麻烦且容易出错。而execute如果这样用,直接吊打testfor啊!而且,这是可以用于基岩版的,做玩家人数检测或实体数量检测!

  比如在基岩版,你可以这么干:

  /execute @a[r=10,x=15,y=94,z=20,tag=游戏参与者]~~~ scoreboard br /layers add br /layer_count count 1

  这将会计算出以(15,94,20)为中心,半径10米内带有『游戏参与者』标签的玩家数量,非常适合用于小游戏的人数判定。

  回到正题啊,接下来我们来看看at子命令。

  at子命令,可以更改执行位置中的维度位置、坐标以及执行朝向中的旋转角度为指定实体的维度位置、坐标和旋转角度。其格式也是十分滴简单:

  ... at <实体:目标选择器>...

  举个例子:

  /execute at @e[tybr /e=minecraft:arrow] run summon villager ~~~

  这将会在每支箭的位置,分别运行一遍『summon villager ~~~』来召唤一只村民。

  可以发现,虽然我们没有更改执行者,但相对坐标的基准点却被更改了,这说明相对坐标默认不是将执行者的位置作为基准点的,而是将指令执行位置作为基准点。其实这个我们在第五章就已经提到了,这里只不过再提一下而已。

  另外,你有没有注意到『分别』两个字?也就是说,at子命令照样会使得指令在每个位置分别运行一遍。不要小看这一点,待会你就会知道小看这一点会导致什么严重的灾难。

  in可以更改指令执行的维度位置,因此我们可以通过in指令来快速前往其他维度。其语法如下:

  ... in <维度ID>...

  举个例子:

  /execute in minecraft:the_nether run tbr / @s ~~~

  这将会把你传送到地狱。需要注意的是,你的x和z坐标可能会被除以8。比如你原先的坐标是(16,80,16),传送到下界后估计就会变成(2,80,2)。

  为什么呢?如果你有一点MC常识的话,你就会知道,在大多数Minecraft版本中,下界中的1米相当于主世界的8米,所以自然而然,你从主世界传送到下界,x和z轴就会除以8(可以通过添加其他子命令来避免这种情况)。

  但在Java稍微旧一些的版本中,运行上述指令并不会改变你的坐标,也就是说不会除以8,还是会保留你原先的(16,80,16)。这是作者在1.14.4版本中发现的,但在最新的1.19版本中不会出现这种情况,因此应该是在1.14.4~1.19间的某个版本修复了这个BUG。作者猜测可能是1.16更新,只不过懒得去测试了。

  另外还需要注意,在1.18及更高版本中,虽然主世界的Y坐标向下延伸到了-64,但其他维度并未变化,因此如果你从Y坐标小于0的地方直接传到地狱或其他维度,极有可能会掉进虚空!

  现在我们来尝试一下结合上面的三个子命令+run子命令,看看当多条子命令结合起来时会有什么效果。

  我们来试着将所有实体往上抬1米:

  /execute as @e at @e run tbr / @s ~~1 ~

  运行之后,你会惊喜的发现,所有实体都往上抬了1米,但也都传到了同一个地方,甚至有些实体还被挤死了。

  这是怎么回事?

  这就是为什么我在前面一直提醒着你说at和as都会在每一个实体和每个位置运行一遍指令。

  让我们来逐步分析一下上面的指令出了什么bug,也就是模拟一下游戏运行这条指令的过程。

  假设现在整个世界仅仅只有3个实体:一名玩家(最早生成),一位村民和一只羊(最晚生成)。

  当这名玩家敲下回车键将指令发送给游戏时,游戏开始对这条指令进行解析并运行:

  as子命令让游戏知道,接下来要改变执行者。而目标选择器@e选择了这三个实体,并使得它们按照生成时间的早晚排序,因此游戏根据as @e,先选择了这名玩家作为执行者,然后再选择村民,最后选择羊。

  接下来游戏看到了at @e,由于之前已经选择好了执行者,所以游戏根据上文还有这里,得知这名玩家将会依次在玩家的位置、村民的位置和羊的位置分别运行一遍指令,村民和羊同理。

  最后游戏看到了run以及后面的指令,它已经完全明白接下来要干什么事情了:

  ①将玩家传送至玩家上方1米的位置(玩家此时抬高了1米)

  ②将玩家传送至村民上方1米的位置(玩家此时位于村民上方1米)

  ③将玩家传送至羊上方1米的位置(玩家此时位于羊上方1米)

  ④将村民传送至玩家上方1米的位置(村民此时位于玩家原本位置上方1米,玩家此时位于羊上方1米)

  ⑤将村民传送至村民上方1米的位置(村民此时位于村民原本位置上方1米,玩家此时位于羊上方1米)

  ⑥将村民传送至羊上方1米的位置(村民和玩家此时位于羊上方1米)

  ⑦将羊传送至玩家上方1米的位置(村民和玩家此时位于羊原本位置上方1米,羊位于玩家原本位置上方1米)

  ⑧将羊传送至村民上方1米的位置(村民和玩家此时位于羊原本位置上方1米,羊位于村民原本位置上方1米)

  ⑨将羊传送至羊上方1米的位置(村民、玩家和羊此时都位于羊原本位置上方1米)

  最终,三者都跑到了羊原先位置上面1米处,指令运行了3×3=9遍。

  太离谱了是不是?但既然写两个@e会造成混乱的话,那么该怎样写呢?

  因为第一个as子命令已经更改了执行者,后面的子命令都会按照更改后的来,所以我们只需要:

  /execute as @e at @s run tbr / @s ~~1 ~

  将at的@e改为@s即可。

  或者说把at放前面,曲线救国一下:

  /execute at @e as @e[limit=1,sort=nearest] run tbr / @s ~~1 ~

  这也是可以的。

  所以在execute中,各个子命令的顺序十分重要,每个子命令都会影响到后面的子命令。希望你能记住这一点,不然可能会犯一些就像上面这样的严重错误。

  我们再来试试结合in和at两个子命令,看看当两个子命令所影响的范围有重合时会发生什么:

  /execute at @s in minecraft:the_nether run tbr / @s ~~~

  /execute in minecraft:the_nether at @s run tbr / @s ~~~

  你可以猜一猜,当你运行这两条指令时,效果分别是怎样的?

  首先,第一条指令的效果和之前『/execute in minecraft:the_nether run tbr / @s ~~~』的效果不能说十分相似,只能说是完全一样。at子命令将执行位置和朝向设定为了你的位置和朝向,但由于本来就是这样所以可以去掉。in虽然仅仅会影响到维度,但如果像是地狱这种特殊的维度,在影响到维度位置的同时,in也会对当前的坐标进行设置。所以说是完全一样,并不会说你这样设置可以将你传到地狱而不改变坐标的。

  而第二条指令就更不用说了,in刚刚把维度改过去,at又改了回来,所以第二条子命令相当于『/tbr / @s ~~~』,把自己传送到自己的位置,实际上没有任何效果。

  所以说,execute就像是个流水线,指令的三要素从指令开头出发,依次经过各个修饰子命令的洗礼,最终在run子命令『出厂』。采用这种『流水线思维』,我们才能更好地理解更加复杂的execute命令。

  本章到此结束。

目录
设置
手机
书架
书页
评论