本帖最后由 贰逼 于 2018-10-14 13:31 编辑
我才刚刚接触1.13命令,以下只是我的一点想法,如果有更便捷的方法欢迎探讨。
从1.12出现mcfunction以来,mcfunction从形式上只能算作"static public void e()"函数,即静态、全局、无返回值的函数,不过这都没关系,关键是不能用一条命令传参,也就是说定义一个复杂的涉及到多变量计算的对象,我们可能需要用多次scoreboard命令。
结合自定义nbt和data get,我们将这个过程移植到mcfunction内部,以简化操作。
拿这个帖子作为范例:
Random(min, max)获取随机值
在这个帖子里面,要调用整套方法,我们要使用两次scoreboard和一次function命令
复制代码其中计分板用于传参,function命令用于执行。
无论是手动输入,还是放到命令方块,或者是写在function里面,要执行完整的函数,我们都至少需要执行三条命令。
如何才能把涉及参数设定的函数调用简化到一条命令呢?
下面来看在1.13里针对上帖中关于函数调用繁琐问题的改良:
原理
至于随机原理就不多说了,那篇帖子有详细介绍
首先存在三个计分板:"random"、"random_min"、"random_max"
接下来唯一的改动就是在random.mcfunction最开头加上了以下命令:复制代码就是依靠自定义NBT获取参数。
然而,改进后的random.mcfunction仍然是一个需要手动执行的函数,要让它自动触发,我们需要添加一个触发器。
接下来我们创建一个erandom.mcfunction,并将它绑定到"tick.json":复制代码这条命令就是为random.mcfunction函数添加触发事件,即当生成自定义NBT中包含command:"random"标签的物品时,触发函数。
函数源码
public:erandom.mcfunction (binded in "tick.json")
在function内使用单命令调用多参数函数也是可以的。如果想要将函数所得的参数传递给其他实体,不妨借助distance精准选择。
如果想要带参的物品不被拾取,或者能被迅速重置,在触发后kill掉即可:复制代码
可能你会说有些麻烦,但实际上加了这么几行东西能简化许多命令,尤其是涉及到多参数遍历的情况
而且这么做能让mcfunction更符合面向对象的思想,同时简化用户交互。来自群组: Command Block Logic
我才刚刚接触1.13命令,以下只是我的一点想法,如果有更便捷的方法欢迎探讨。
从1.12出现mcfunction以来,mcfunction从形式上只能算作"static public void e()"函数,即静态、全局、无返回值的函数,不过这都没关系,关键是不能用一条命令传参,也就是说定义一个复杂的涉及到多变量计算的对象,我们可能需要用多次scoreboard命令。
结合自定义nbt和data get,我们将这个过程移植到mcfunction内部,以简化操作。
拿这个帖子作为范例:
Random(min, max)获取随机值
在这个帖子里面,要调用整套方法,我们要使用两次scoreboard和一次function命令
- scoreboard players set @p random_min [value1]
- scoreboard players set @p random_max [value2]
- function random:random
无论是手动输入,还是放到命令方块,或者是写在function里面,要执行完整的函数,我们都至少需要执行三条命令。
如何才能把涉及参数设定的函数调用简化到一条命令呢?
下面来看在1.13里针对上帖中关于函数调用繁琐问题的改良:
原理
至于随机原理就不多说了,那篇帖子有详细介绍
首先存在三个计分板:"random"、"random_min"、"random_max"
接下来唯一的改动就是在random.mcfunction最开头加上了以下命令:
- #get param
- execute as @s store result score @s random_min run data get entity @s Item.tag.randomMin 1
- execute as @s store result score @s random_max run data get entity @s Item.tag.randomMax 1
然而,改进后的random.mcfunction仍然是一个需要手动执行的函数,要让它自动触发,我们需要添加一个触发器。
接下来我们创建一个erandom.mcfunction,并将它绑定到"tick.json":
- #trigger
- execute as @e[type=item,nbt={Item:{tag:{command:"random"}},Age:0s}] run function public:random
函数源码
public:erandom.mcfunction (binded in "tick.json")
public:random.mcfunction
在function内使用单命令调用多参数函数也是可以的。如果想要将函数所得的参数传递给其他实体,不妨借助distance精准选择。
如果想要带参的物品不被拾取,或者能被迅速重置,在触发后kill掉即可:
- @e[type=item,nbt={Item:{tag:{command:"random"}},Age:0s}]
可能你会说有些麻烦,但实际上加了这么几行东西能简化许多命令,尤其是涉及到多参数遍历的情况
而且这么做能让mcfunction更符合面向对象的思想,同时简化用户交互。来自群组: Command Block Logic
本帖最后由 ruhuasiyu 于 2018-10-14 14:05 编辑
感觉用list传参更好一点?
例如 minecraft:apple{command:["random",1,10]} ?
感觉用list传参更好一点?
例如 minecraft:apple{command:["random",1,10]} ?
那对于依靠自定义nbt的触发模式
同时出现十几个的情况下对性能会不会有所影响呢..
同时出现十几个的情况下对性能会不会有所影响呢..
xu11xx 发表于 2018-10-14 14:05
那对于依靠自定义nbt的触发模式
同时出现十几个的情况下对性能会不会有所影响呢.. ...
触发器(帖中的erandom.mcfunction)实际上就相当开了一个新的线程
帖尾中我说直接kill掉就可以,就是针对于不需要回调(无返回值)的函数,直接将物品清除即可,线程其实还在执行
如果是一个要回调的函数且物品无法用作对象储存参数(因为物品有碰撞体积,加之物品有材质),可以在触发器上面下功夫,比如在生成一个新的对象(比如效果云),再将参数储存在这个对象上面即可。
总之基于自定义nbt读取参数,性能影响微乎其微。物品只是作为一个传参的中介罢了,读参后立即清除没有大碍,况且data命令操作自定义nbt本身就不卡顿。
至于执行几十个,如果调用的函数本身就卡那也没办法
本帖最后由 贰逼 于 2018-10-14 14:23 编辑
这样确实也好,这个的确更类似于一个函数的传参方式
复制代码这个就像读命令行一样用args[0]、args[1]来读参,有被定义的参数顺序
其实将物品看做是实例化的一个对象,用何种自定义nbt传参都无所谓了,帖中示例我定义的是两个属性也无妨
ruhuasiyu 发表于 2018-10-14 13:48
感觉用list传参更好一点?
例如 minecraft:apple{command:["random",1,10]} ?
这样确实也好,这个的确更类似于一个函数的传参方式
- function(param1, param2, ...)
其实将物品看做是实例化的一个对象,用何种自定义nbt传参都无所谓了,帖中示例我定义的是两个属性也无妨
xu11xx 发表于 2018-10-14 14:05
那对于依靠自定义nbt的触发模式
同时出现十几个的情况下对性能会不会有所影响呢.. ...
只是读取一个物品的nbt不会有啥太大影响的,而且一般来说传参结束就杀死了。返回值其实也可以存储在物品,至于物品模型什么的,弄到y=9999应该就行了吧==
虽然我觉得大部分情况还是存放在计分版更省事点……
好腻害的样子