这当然不是教程...这只是一系列来自一只话唠的碎碎念。
目标选择器,又叫实体选择器,通常被简称作选择器,是用来对部分命令指向的对象进行选择的工具。
在第一章中便说到,命令是得有目标的,而有些命令的目标指向到玩家/实体。有的时候我们可以直接使用玩家名去使得命令作用于某一特定的玩家,但毕竟不是每个系统都只为了对一个人生效。我们不可能通过例举每个玩家的名字来让命令对每个人生效(讲个笑话,穷举玩家名),这种时候,我们就需要目标选择器的帮助,来使得命令可以很方便的指向到满足条件的实体。
可以理解为,目标选择器是一种对满足其条件的实体的指代。
每个人第一次见到目标选择器,大概都是在命令方块打开的GUI里:

这就是最基础的实体选择器用法。
2021.12 数据,可能有更多内容
这不是教程§3|目标选择器
这当然不是教程...这只是一系列来自一只话唠的碎碎念。
目标选择器,又叫实体选择器,通常被简称作选择器,是用来对部分命令指向的对象进行选择的工具。
在第一章中便说到,命令是得有目标的,而有些命令的目标指向到玩家/实体。有的时候我们可以直接使用玩家名去使得命令作用于某一特定的玩家,但毕竟不是每个系统都只为了对一个人生效。我们不可能通过例举每个玩家的名字来让命令对每个人生效(讲个笑话,穷举玩家名),这种时候,我们就需要目标选择器的帮助,来使得命令可以很方便的指向到满足条件的实体。
可以理解为,目标选择器是一种对满足其条件的实体的指代。
每个人第一次见到目标选择器,大概都是在命令方块打开的GUI里:

这就是最基础的实体选择器用法。
mojang提供了4个选择器给我们使用:@a、@p、@r和@e。它们有着不同的基础指向,用以去更方便的做出对不同的实体的操作。其中,@e是正式版1.8之后添加的选择器。在此之前,选择器能且仅能指向玩家,当然那时候也没有针对玩家外实体的命令就是了。
@a:全体玩家
指向所有在线的玩家。可以认为,是从tab显示的玩家list里所有被记录的人。通过假名创建的fake player是不会被选中的,因为它们不满足“在线”这个条件。所以有的时候需要调用假名分数,是不能通过选择器来操作的。
@p:最近玩家
指向离命令执行者最近的玩家。命令执行者的概念见第二章,此后不再赘述。
@r:随机玩家/实体
指向随机的玩家/实体。默认目标为玩家,但可以通过type参数来指向玩家外的实体。可以通过type=!LightingBolt指向全体能被选中的实体。
@e:全部实体
指向全体加载中的实体。如果一个实体存在但不在加载的区块内,它将不会被选中。
在大多数情况下,@a、@p和@e间的关系可以写成这样的表达式:
代码:
- @p=@a[c=1]=@e[type=Player,c=1]
虽然几乎是可以互换的东西,但是一般来说,在保证效果相同的时候,优先使用更简洁的写法是比较好的习惯。
不过呢,虽然@p一般可以看作是@a[c=1],但实际上也有细微的差别——举个例子,@a[c=1]可以选中已经死去的玩家,但@p只能选择到尚活着的玩家。这种时候,显然你能用的就只有看起来更繁杂一点的写法了。
pca写过一个足够完整的版本了,这里也就不献丑了。
老实讲贴了他这个帖子我觉得我整个帖子都不用写了。
如果一个选择器的参数中出现了距离范围参数(x,y,z,dx,dy,dz,r,rm),那么只有与执行点同一个世界的实体才能够被选中。
这让我们不得不怀疑死亡的玩家在四次元(笑)。
选择器在执行到时会被解析成一系列UUID以供命令使用。得到的列表遵照一定的顺序依次被传递给命令,所以通常对实体的命令,选择顺序即执行顺序。
选择器会根据它自身和其中参数检索符合条件的实体,并按照与执行点间的距离顺序列出。当两实体与执行点距离相同时,则存在的更久的实体会在列表中处于更靠前的位置。
如果选择器为@r,则在符合条件的实体被筛出之后,随机进行排序。
最后选择器根据自身类型(@p)及选择器参数c来确定最后从列表中按照顺序取出的实体数量。
同一个参数在一个实体选择器中只能出现一次。否则,后出现的将会覆盖掉前者的内容。例如,选择器@e[type=zombie,type=skeleton]将会指向骷髅而不是同时选中僵尸和骷髅。
遇到这种问题往往有两个情况:
第一是我们需要选中分别具有不同属性的实体,例如上例里不同种类的实体;
第二是我们需要选中同时具有多个需要用同一个参数来描述的属性的实体,比如同时具有tag A和tag B的实体;
不同的情况自然要区别对待。对于第一种情况,我们往往考虑两种解:一是分别穷举不同种类的实体分别处理;比如如果只是要把它们全部tp到一个地方的话,那么分别写
代码:
- tp @e[type=zombie] x y z
- tp @e[type=skeleton] x y z
就可以了;二是给它们一个统一的标记,比如tag或者score,然后在选择器里填写这个用来标记的参数,就可以单参数快速选中所有的目标实体。
对于第二种情况,同样是两种解:一是在标记时就做好处理,比如只给有A这个tag的实体附加B这个tag,这样选中拥有tag B的实体就一定同时拥有两个tag;二则是通过多重execute来强行往一个实体上做两次tag判定:
代码:
- execute @e[tag=A] ~ ~ ~ execute @e[tag=B,r=0,c=1] ~ ~ ~ <后续命令>
r=0,c=1是选中同坐标出现时间最久的实体,原则上你不tp的话想让两个实体完全重合还是很难的……所以一般不会误选,总会精准命中执行者本身。这样的话就通过一条命令对拥有tag A的实体再做了一次tag检测,满足条件的即拥有两个tag的实体。
另:
有的人会问啊,不同记分板的score_xxx_min和score_xxx不是可以在同一个选择器下写多个么?
对,它们可以。但是你首先要搞清楚,它们为什么可以。
选择器参数部分,通过半角逗号分隔不同参数,通过等号连接一对参数:前面的为键,后面的为值。键可以简单地理解为标记,mc通过这个标记来明白这个选择器参数是要声明什么东西;而值则是这个声明的具体内容。当选择器解析着解析着发现“诶这个标记不是已经被用过了么?”的时候,它就会把重复的标记对应的值用后来者的覆盖掉。
这时候想想看score系列参数。
不同记分板产生的标记,本身就是不一样的。因此,写一万个不重复的记分板的score参数,也不违反记分板参数的对应规则(当然会远远超出mc的命令字数上限所以这就是个玩笑啦)。
不过如果你给同一个记分板写了不同的分数范围,mc可是会扔给你一个覆盖并静待你debug哦。
有时候,我们要对不满足某一条件的实体进行相应操作,这就涉及了反选。
有些选择器参数(type,name,m,team,tag)自带反选功能。比如@a[m=!1],将选中所有非创造模式的玩家。
而其他的参数并不支持通过!来进行反选,但提供了一对相对的参数来方便你对不同值范围的实体进行选择:例如l和lm,score_xxx和score_xxx_min此类,一个参数规定值的上界,一个参数规定值的下界。这种时候你可以通过同时加入这些参数来确定一个具体的选择范围。
还有一些东西是不能直接反选的……最简单的例子就是dx/dy/dz这些确定方形选区的参数。你可以很轻松的通过它们选择到目标区域内的实体,但是想选择区域外的实体就要费点劲;最常见的解法依旧是给区域内的实体加个tag,然后反选此tag。也就是说,借助其他能够标记区域内外的方式给不想选到的实体打个戳,那么没有戳的就是你想选到的实体了。
首先mc会检测应该写在选择器位置的字串是否是一个选择器。如果格式满足要求,它将继续检查其中的参数以确定具体的选择范围。此时如果是单目标的选择器/参数(如@p), 它将根据你的描述直接找到目标并返回其UUID;否(即有多个目标时),则根据其描述和选择顺序生成一张表,从表里面按照对应的规则(数量及随机性)返回与要求相称的UUID;
如果选择器参数内含有非法字符,或者不满足选择器格式(其实前面的也算是不满足格式2333),mc会尝试它当做玩家名,在在线玩家中搜寻此名字并返回相应的玩家UUID;
如果没有找到这个“玩家”,mc会尝试将给定字串直接当成一个UUID来解析;
此时解析到的UUID将被扔进命令等待进一步操作,如果经过上面三个步骤仍旧没有得到(至少一个)可以用的UUID,那么选择失败,返回找不到目标并指令失败。
此部分作为进阶内容,不知道也没有问题,不过可以更好地帮助你理解命令整个体系。
这篇(可能也包括接下来几篇,json和nbt)内容会偏少,因为本身都有足够靠谱的资料了想想看也没啥可讲的……哇json真的好想一本json圣典糊上去啊不过那就没意思了不是么2333
再之后就会进入记分板和命令系统的深坑,那两章就真不知道填到猴年马月了。
再之后……没了。反正开坑的时候写了纲,那两张纲最长…………要讲的点也基本都讲到了,如果什么时候想起来有遗漏就到时候更新好了。
也是离上一篇时间有点久了,前段时间沉迷写小说不能自拔,还顺带坑了pe的命令介绍,也不是没干事情,但是的确这边给落下了。放心啦,开了的坑跪着也要填完就是。
惯例的欢迎提醒+欢迎纠错。
同样,惯例的抱抱。
老实讲贴了他这个帖子我觉得我整个帖子都不用写了。
。。。结果你还是写了。。
这个感叹号怎么没了。。。。。。。。
chyx 发表于 2016-12-25 01:55
type=LightingBolt
怎么没见改啊