我的世界指令:检测玩家y值是否低于指定值

我的世界指令:检测玩家y值是否低于指定值

以下内容仅在Java版中有效
在我的世界中,我们有时候有一个需求,即检测玩家的y坐标是否低于(或高于)给定值,该怎么做呢?

目录

第一时间我们应该会想到用目标选择器来完成这个操作,我从wiki中截了一段有关目标选择器中坐标参数的描述。

坐标(x、y、z):

[x=<值>,y=<值>,z=<值>] — 在世界中定义一个位置。
这个位置将成为目标选择器执行位置(不修改命令执行位置),这意味着@p所选择的目标可能发生改变。
如果其中任意参数未定义,则默认使用命令执行位置的坐标。
可用于distance参数或dxdydz参数,以平移选择范围。
坐标可以是整数或像12.34这样的小数(具体为双精度浮点数)且不会进行中心校正(center-corrected),这意味着x=0不再自动更正为x=0.5。在基岩版中,波浪号可用于此参数。

体积尺寸(dx、dy、dz):

[dx=<值>,dy=<值>,dz=<值>] — 在同一个维度内,在Java版中,选择所有实体判定箱与所定义的长方体区域相交的所有实体。如果位置参数未定义,则直接相对于命令执行位置计算所选长方体区域。这三个参数可以为负数和小数。

很容易想到,在目标选择器中,我们可以使用x,y,zdx,dy,dz来检测玩家是否处于一个给定范围,比如用下面的指令检测玩家是否在(6,7,8)和(123,124,125)两点所表示的长方体区域中:

#命令中的xxx表示一个玩家的名字或者玩家选择器,下同
#这里没有给出后面run的部分,读者可以根据自己的需求来写
#该情况下dx=123-6=177,dy=124-7=177,dz=125-8=177
execute as xxx at @s if entity @s[x=6,y=7,z=8,dx=177,dy=177,dz=177]

回到前面的问题,怎样检测玩家的y坐标是否低于(或高于)给定值?

方案一:“无限大”长方体

其中的一种想法是,既然目标选择器可以检测玩家判定箱与所定义的长方体区域是否相交,我们可以取一个“无限大”的长方体,即在xz方向上足够大,以延伸到足够远处,然后仅在y值上做文章,y可以取你要检测的y值的临界值。
这主要是由于世界大小是有上限的,wiki中的资料指出世界边界本质上是一个巨大的边界框。在默认设置下,世界边界的中心位于坐标x=0, z=0处,每一方向的长度或宽度约为三千万(29,999,984)方格,因此我们的xz都取这个最大宽度的一半并取负值,然后dxdz就取这个最大值。
比如你想监测玩家的y坐标是否低于64,我们可以这样写:

execute as xxx at @s if entity @s[x=-14999992,y=63,z=-14999992,dx=29999984,dy=-340,dz=29999984]

注意,这个地方的y为什么写的是63呢?这是由于我的世界的一个特性(参考MC-123441),也就是说,如果你要检测玩家y坐标是否低于M,你把上面指令的y=63换成y=M-1就行了,还有就是,上面我dy写的是-340,如果你的y值很大,你需要修改这里的dy,要保证y-dy的值是玩家不会存在的高度(一般情况下是要小于-128,再往下就是虚空了),否则玩家低于该值时检测不到。

方案二:跟随玩家的长方体

上面的方案中我们取了一个“无限大”的长方体区域来进行检测,实际上我们完全可以在玩家的脚下取一个区域进行检测,想象一下,我取一个长方体区域,这个区域由x=<玩家x值>,y=<要检测的y值>,z=<玩家z值>以及dx=1,dy=-1,dz=1定义,这个区域始终和玩家在一个竖直线上,下面我用一个村民来说明这个问题:

村民移动的时候下面的检测区域仍然固定(y值固定,x、z值跟随村民)

白色的是村民的碰撞箱,下面的那个方块是检测区域,那个检测区域的其中一个顶点的x,z坐标始终和玩家一致,并由于dx=1,dz=1以及dy=-1分别延伸1个方块。
因此只需检测玩家的碰撞箱是否与该区域有交点即可。
比如检测是否低于64,采用下面命令,仍然要注意上面说到的问题,即y要减1。

execute as xxx at @s if entity @s[y=63,dx=1,dy=-1,dz=1]

关于其他的检测,比如检测y值是否大于某个值,xz的检测等,思路相同,不多赘述。