(注:非常不推荐在手机上阅读此章节,请使用平板或电脑阅读此章)
(本章用到了大量的字符画,有可能会出现严重的错位情况,可手动调整字体和大小至最佳状态)
(此章节已于2022年7月17日重写)
在第六十九章,我为了提醒你注意各个子命令的顺序,专门举了个例子:
/execute as @e at @e run tp @s ~~1 ~
但是你是否有注意到游戏运行这条指令的过程:
①将玩家传送至玩家上方1米的位置(玩家此时抬高了1米)
②将玩家传送至村民上方1米的位置(玩家此时位于村民上方1米)
③将玩家传送至羊上方1米的位置(玩家此时位于羊上方1米)
④将村民传送至玩家上方1米的位置(村民此时位于玩家原本位置上方1米,玩家此时位于羊上方1米)
⑤将村民传送至村民上方1米的位置(村民此时位于村民原本位置上方1米,玩家此时位于羊上方1米)
⑥将村民传送至羊上方1米的位置(村民和玩家此时位于羊上方1米)
⑦将羊传送至玩家上方1米的位置(村民和玩家此时位于羊原本位置上方1米,羊位于玩家原本位置上方1米)
⑧将羊传送至村民上方1米的位置(村民和玩家此时位于羊原本位置上方1米,羊位于村民原本位置上方1米)
⑨将羊传送至羊上方1米的位置(村民、玩家和羊此时都位于羊原本位置上方1米)
这个过程有何特殊的呢?
你仔细看看第④、⑤、⑦、⑧和⑨条过程,你有没有什么发现?
当游戏将村民传送至玩家上方1米的位置时,虽然玩家已经被传送至了羊上方1米的位置,但游戏仍然将村民传送至玩家原本位置上方1米,而不是羊上方2米的位置。
这是怎么回事?
我们设玩家(2,2,2)为A、村民(3,2,3)为B、羊(4,2,4)为C,游戏在运行execute时,其实它的流程是这样的:
execute---A---------B---------C
游戏先解析as @e,得到了上面的三个目标。
execute---A---------B---------C
------------↓---------↓----------↓
---------2·2·2-----2·2·2-----2·2·2
------------↓---------↓----------↓
---------3·2·3-----3·2·3-----3·2·3
------------↓---------↓----------↓
---------4·2·4-----4·2·4-----4·2·4
然后游戏会解析at @e,预先将实体的位置记录下来。上面为了方便展示,用x·y·z来表示坐标。
execute---A------------------------B-----------------------C
------------↓-------------------|----↓------------------|-----↓
---------2·2·2—3·2·3—4·2·4-|-2·2·2—3·2·3—4·2·4-|-2·2·2—3·2·3—4·2·4
------------↓-------↓-------↓---|----↓------↓-------↓---|----↓-------↓-------↓
-----------①------②------③---|---④-----⑤------⑥---|---⑦------⑧------⑨
①:/tp 玩家名 2 3 2
②:/tp 玩家名 3 3 3
③:/tp 玩家名 4 3 4
④:/tp 村民UUID 2 3 2
⑤:/tp 村民UUID 3 3 3
⑥:/tp 村民UUID 4 3 4
⑦:/tp 羊UUID 2 3 2
⑧:/tp 羊UUID 3 3 3
⑨:/tp 羊UUID 4 3 4
接下来游戏会解析run tp @s ~~1 ~,根据三要素,将其中的目标选择器和相对坐标等参数具体化(但计分板分数之类的不会具体化,因为没必要),得到具体的指令(如上)。
最后,游戏运行具体的指令,也就是本章最开头的那九个过程。
其中,最重要的,也是最关键的一点,就在于execute指令解析at @e的过程。
小主,
execute并不是说运行一次解析一次,而是先全部解析了再运行,所以并不会使得『村民传到玩家传送过后上方1米的位置』之类的事情发生。
能理解吧?
那问题来了,如果execute再套一个execute会发生什么?比如我们将上述指令写成:
/execute as @e run execute at @e run tp @s ~~1 ~
其实效果还是一样的,具体原因就等你自己去推导吧,按照我上面的流程去推导。
这就是Java execute 1.13+版本的运行流程。如果你还不懂,我们再看一个简单并且效果比较明显的例子。
设有盔甲架A和B,分别位于主世界的(40,-60,29)和(42,-60,29)。盔甲架A的生成时间比盔甲架B更早,已加载区块中没有其他盔甲架。在盔甲架A、B旁运行如下指令:
/execute as @e[type=minecraft:armor_stand] at @s run tp @e[type=minecraft:armor_stand,distance=1..3]~~10 ~
让我们分析一下,运行上述指令会发生什么。