本节最后修改于 2022 / 11 / 12
我们上一节讲到MP过程是在一串连锁命令方块中,通过给符合特定条件的实体打标签,使用此标签对其操作,最后去掉标签来结束MP过程——一共三步来对实体更方便安全地进行操作。
我们同时还讲到,选择器体现了一种条件判断的思想。MP过程的第一步打标签,就需要选择器进行判断。
那么我们换个视角来看,能不能把这套流程解释为“判断有无符合特定条件的实体,如果有则进行操作,否则不进行操作”呢?当然是可以的。于是对于一个接在循环命令方块后面——不停地循环执行——的MP过程,它就可以被看作是不停地判断实体,判断成功时执行操作。
在计算机程序界中(在其他地方也有可能),对于一个不停判断条件,一旦条件满足就进行动作的东西,我们可以说它属于一种“事件监听器”;不停判断条件就是在“监听”;判断的条件即为“事件”;而进行的动作,名字就多了,比如“回调”“响应函数”“钩子函数”等等。于是我们可以说,当这个东西“监听”到“事件”发生时,才执行“响应函数”;若“事件”没有发生,就不执行“响应函数”。十分的形象。
仿照计算机程序界(其他地方或许也有)的概念,我们可以管一个不停检测条件的MP过程叫做“事件监听器”,于是我们便成功把MP过程套到了一个简单易懂的“事件”模式中。类似的,我们可以把这种事件模式称为MP事件模式或简称MP事件。当我们的MP过程“监听”到“有特定条件的实体出现”这一“事件”发生后,便执行“响应指令”;否则就不执行。
听起来这个概念貌似还挺容易理解的,那么如何实现呢?我们跟着上面走,搭一个MP过程的命令方块串试试。
首先这个要不停地检测来“监听”,那么最好是接在一个循环命令方块上面。
好,接下来“监听”是判断事件有没有发生。我们讲过条件判断有两种形式,那就是选择器或者有条件命令方块。任选一个,比如就选择器吧,最简单的实现就是给符合条件的人打标签,就是MP过程的标记。那么这个命令方块串的第一个指令就是给人打标签。
然后监听完了,就是执行响应指令。这里我们发现一个问题,如果我们直接把无条件连锁命令方块的指令接在命令方块串后面,那么不论检测事件发生没发生,指令都会执行。那怎么办?我们发现有两个办法,一种是execute判断一下,如果有人有MP过程的标记,那就执行。一种是改成有条件连锁命令方块。
响应指令一般不止一个啊,我们还得继续加指令是吧。再加无条件连锁命令方块,发现又出现了上一次的问题:要不然用execute判断,要不然改成有条件命令方块。于是有条件命令方块的缺点在此显露了:这时的有条件并不是“第一个命令执行成功”,而是“第一个命令执行成功后,第二个命令执行,并且成功”。也就是说若第二个命令没成功,即使第一个命令成功了,事件发生了,响应也不会继续执行。所以我们一般使用execute判断。
其他的响应指令都一样了,最后我们别忘了MP事件是特殊的MP过程,还要把标记给去掉,结束这个MP过程,防止干扰下一次检测。
# 例子
# 当有人抬头时,提示“有人抬头了!”并杀光所有玩家,然后在聊天栏提示“玉米是大帅比”
[+,X,-,~] tag @a[rx=-89] add 抬头-ing
[+,L,-,0] execute @a[tag=抬头-ing] ~~~ say 有人抬头了!
[+,L,-,0] execute @a[tag=抬头-ing] ~~~ kill @a
[+,L,-,0] execute @a[tag=抬头-ing] ~~~ say 玉米是大帅比
[+,L,-,0] tag @a[tag=抬头-ing] remove 抬头-ing
最后我们发现这个所谓MP事件的响应指令前面全都有一个execute!你可能会说这“一点也不优雅,‘简单’个鸡毛!”。
是的,我的世界不存在真正的事件模型,这只是我们通过奇技淫巧搞出来的类似事件的东西。本系列所讲述的与其说是设计模式,倒不如说是设计技巧。有的时候这些技巧不仅不会让编写指令变简单,还会增加指令的复杂度。
那么什么时候这些技巧会让指令变简单呢?对于MP事件,比较简单的用法是将相同的条件判断串到一串上。这样子不仅提高了可维护性,还减少了命令方块串的数量,是简单的指令复用。
# 例子
# 当有“Eggless”标签的人抬头时,给他俩鸡蛋。
# 当有“Eggless”标签还有“帅比”标签的人抬头时,给他四个鸡蛋。
[+,X,-,~] tag @a[rx=-89,tag=Eggless] add 抬头-ing
[+,L,-,0] give @a[tag=抬头-ing] egg 0 2
[+,L,-,0] give @a[tag=抬头-ing,tag=帅比] egg 0 2
[+,L,-,0] tag @a[tag=抬头-ing] remove 抬头-ing
这样子就不需要分别为重工业玉米和其他不是帅比的人分别弄个抬头检测了。要是之后还有需要抬头的指令,直接在中间加命令方块就可以了。如果条件和指令又变得更多,可以在这个MP事件里再串一个MP过程,进行条件判断的复用。