秋一
本帖最后由 acordome 于 2015-12-16 15:15 编辑

  大家好,今天我向大家隆重推荐1.9新的实体之王——AreaEffectCloud。字面的意思就是区域效果云,俗称药水云。
  顺便,咱来对比一下盔甲架(AS)和药水云(AEC)作为marker的优点和缺点。

  在进入正文以前,我先把一些简称稍微列一下吧,这些写法可以参考pca的这篇帖子:http://www.mcbbs.net/thread-522757-1-1.html

gt: gametick,游戏刻,一般为0.05秒,为MC里最小的时间单位(微观延迟就是1gt内的执行顺序)
scb: scoreboard,记分板
cb: command block,命令方块
icb: impulse command block,特指普通命令方块
ccb: chain command block,连锁CB
rcb: repeating command block,循环CB(会自动激活)
AS: ArmorStand,盔甲架,经常用于标记坐标

例子中可能用到的格式(其实是我生成器的格式来的)
icb:/rcb: 该命令是放在icb/rcb里
mark:名字 tag : 以一个指定名字、tag的AS来标记下一个CB的位置
init: 该指令只是在生成OCS的时候执行
cond: conditional,1.9CB的模式

在此基础上进行补充
    AEC:AreaEffectCloud,(滞留的)药水云

1. 什么是Marker

  对于CBer来说,在编写指令的时候,考虑到移植性的问题,通常要尽可能避免在CB中出现绝对坐标,并且如果可以减少相对坐标中出现的数字,那自然是更好的。这就是为什么我们越来越重视marker这一概念。
  例如,当我们需要激活一个远处的指令串的时候,我们可以使用这样的指令来激活
  1. /blockdata x y z {auto:1}
复制代码

  显然,如果使用绝对坐标的话,就不便于移植,使用相对偏移坐标的话,就需要考虑方位的问题。因此我们会考虑在(x,y,z)处放置一个不可动的实体来作为定位,例如上述指令,假设放置了一个tag=module的marker以后:
  1. execute @e[tag=module1] ~ ~ ~ blockdata ~ ~ ~ {auto:1}

  2. mark:module1
  3. icb:blockdata ~ ~ ~ {auto:0}
  4. blah blah blah...
复制代码

  可以看到,所有的坐标都是以~ ~ ~表示的,这样的话,会方便移植和调用,虽然看上去好像是麻烦了,实际上却是对思维和逻辑的一种简化和规范。

2. 什么样的实体适合充当Marker

  在明确了marker的作用以后,我们来探讨一下什么样的实体适合充当marker。显然候选人便是AS和AEC了。前两天chyx提出“AEC作为marker不卡”这一事实以后,我们几个人就开始了对aec marker的研究——不知道以前有没有人专门发过这样的帖子,如果有,纯属巧合,嗯√

 2.1 盔甲架:AS, ArmorStand

  首先,大家都比较熟悉的AS,作为marker,不考虑name和tag的话,它需要设定这样的NBT

  1. {Marker:1,NoGravity:1,Invisible:1}
复制代码

  AS作为marker,平时是看不见的,只有当切换旁观者模式以后才能看得见,这样设定的好处就是,在编写的时候,不会因为看见它们而感觉很烦,而debug的时候,则可以很方便的发现它们。缺点就是:当大规模使用AS marker的时候,由于需要渲染AS的模型,计算机会额外消耗很多资源。我曾经做过一个小测试,在一个点生成了500个AS marker,帧率从满帧直接掉到个位数……同样的测试也在AEC身上做了,结果稍后说,想必各位也是猜到了的。
  而且,AS要写的NBT挺麻烦的……


 2.2 药水云:AEC, AreaEffectCloud

  AEC是1.9新增的实体,之前我们很多人也没有想到拿它作为marker,最近开始研究才发现其实是很棒的一个东西。首先我们来看看它作为marker的两个重要的NBT——其实Age在marker中用处几乎为0,但是要顺带讲……

    Age:指AEC存在了的时间,单位是gt。也就是说每gt自动+1
    Duration:指AEC能存在的时间,单位也是gt。这是一个固有值,当Age达到这个数值的时候,AEC会消失。Duration最大值是2147483647,即2^31-1,超过这数字会溢出——注意:这个数值大概是3年4个月,对于一个MC存档来说,几乎等价于永久marker了

  这两个NBT如果默认的话,就是0,也就是说,如果没有指定AEC的Duration的话,AEC会存在短短的一瞬间。
  这就意味着,如果使用AEC作为临时的Marker的话,不需要我们使用kill/tp之类的指令来清除它。

  显然用于Marker的AEC,我们只需要考虑一个标签,那就是Duration。
  这里给出一条生成永久marker的指令,用2100000000(8个0)是因为懒得打2147483647,Duration:2100000000的AEC持续时间大约是3年3月,你们觉得一个CB存档可能运行3年吗(笑)?
  1. /summon AreaEffectCloud x y z {Duration:2100000000,CustomName:"xxx",Tags:["a","b"]}
复制代码

  对于单点放置,可以用tab补全x y z,对于大量放置,可以用下面的指令:
  1. icb:/fill x1 y1 z1 x2 y2 z2 command_block 0 replace {auto:1,Command:"/summon AreaEffectCloud ~ ~ ~ {Duration:2100000000,CustomName:"xxx",Tags:["a","b"]}"}
复制代码

  
  预计大型显示屏设备会井喷,放置这么多AEC并不会卡,但是同时执行指令的话,需要斟酌……

  可能会有很多人觉得AS更加稳妥一些,其实我觉得将来AEC完全可以取代AS成为新的marker之王,不过这并不意味着AS就失去了意义。我们应该明确一下它们各自的优缺点,了解它们分别用在什么场合更加合适。


AS
AEC
是否需要重置装置
理论上需要,实际上当Duration设定足够长的话就不需要了
作为临时marker的便捷性
需要手动清除
可以自动清除
消耗资源
G3下可见,因此有一定消耗
完全不可见,消耗资源极少
debug便捷性
比较便捷
不太方便,需要F3+b
相关NBT
Marker,Invisible,NoGravity
Duration

  下面对AEC稍微作一下总结,AS由于大家都比较了解了就不说了……
   AEC消耗的资源是很少的,我们在测试的时候放置了1万个AEC,帧数一点都没有降,如果是AS,早就崩MC了估计……
   AEC如果不打开F3+b的话,不便于debug,这一点是毋庸置疑的;
   AEC可以用来做时钟,这一点后来会稍微提到一点;
   AEC作为临时marker不需要清除,只需要设定一个很小的Duration即可;

  AEC可能会是继AS之后又一实体之王,其应用将来可能会比AS更加广泛——让我们持续关注吧23333
  如果大家有什么疑问,不妨在下方提出。

  感谢@chyx @pca006132 和其他我不记得你们ID的小伙伴们!

  翻页可以看时钟。


2021.12 数据,可能有更多内容  大家好,今天我向大家隆重推荐1.9新的实体之王——AreaEffectCloud。字面的意思就是区域效果云,俗称药水云。
  顺便,咱来对比一下盔甲架(AS)和药水云(AEC)作为marker的优点和缺点。


  在进入正文以前,我先把一些简称稍微列一下吧,这些写法可以参考pca的这篇帖子:http://www.mcbbs.net/thread-522757-1-1.html


gt: gametick,游戏刻,一般为0.05秒,为MC里最小的时间单位(微观延迟就是1gt内的执行顺序)
scb: scoreboard,记分板
cb: command block,命令方块
icb: impulse command block,特指普通命令方块
ccb: chain command block,连锁CB
rcb: repeating command block,循环CB(会自动激活)
AS: ArmorStand,盔甲架,经常用于标记坐标


例子中可能用到的格式(其实是我生成器的格式来的)
icb:/rcb: 该命令是放在icb/rcb里
mark:名字 tag : 以一个指定名字、tag的AS来标记下一个CB的位置
init: 该指令只是在生成OCS的时候执行
cond: conditional,1.9CB的模式

在此基础上进行补充
    AEC:AreaEffectCloud,(滞留的)药水云


1. 什么是Marker


  对于CBer来说,在编写指令的时候,考虑到移植性的问题,通常要尽可能避免在CB中出现绝对坐标,并且如果可以减少相对坐标中出现的数字,那自然是更好的。这就是为什么我们越来越重视marker这一概念。
  例如,当我们需要激活一个远处的指令串的时候,我们可以使用这样的指令来激活

代码:

  1. /blockdata x y z {auto:1}

  显然,如果使用绝对坐标的话,就不便于移植,使用相对偏移坐标的话,就需要考虑方位的问题。因此我们会考虑在(x,y,z)处放置一个不可动的实体来作为定位,例如上述指令,假设放置了一个tag=module的marker以后:

代码:

  1. execute @e[tag=module1] ~ ~ ~ blockdata ~ ~ ~ {auto:1}

  2. mark:module1
  3. icb:blockdata ~ ~ ~ {auto:0}
  4. blah blah blah...

  可以看到,所有的坐标都是以~ ~ ~表示的,这样的话,会方便移植和调用,虽然看上去好像是麻烦了,实际上却是对思维和逻辑的一种简化和规范。


2. 什么样的实体适合充当Marker


  在明确了marker的作用以后,我们来探讨一下什么样的实体适合充当marker。显然候选人便是AS和AEC了。前两天chyx提出“AEC作为marker不卡”这一事实以后,我们几个人就开始了对aec marker的研究——不知道以前有没有人专门发过这样的帖子,如果有,纯属巧合,嗯√


 2.1 盔甲架:AS, ArmorStand


  首先,大家都比较熟悉的AS,作为marker,不考虑name和tag的话,它需要设定这样的NBT


代码:

  1. {Marker:1,NoGravity:1,Invisible:1}

  AS作为marker,平时是看不见的,只有当切换旁观者模式以后才能看得见,这样设定的好处就是,在编写的时候,不会因为看见它们而感觉很烦,而debug的时候,则可以很方便的发现它们。缺点就是:当大规模使用AS marker的时候,由于需要渲染AS的模型,计算机会额外消耗很多资源。我曾经做过一个小测试,在一个点生成了500个AS marker,帧率从满帧直接掉到个位数……同样的测试也在AEC身上做了,结果稍后说,想必各位也是猜到了的。
  而且,AS要写的NBT挺麻烦的……


 2.2 药水云:AEC, AreaEffectCloud


  AEC是1.9新增的实体,之前我们很多人也没有想到拿它作为marker,最近开始研究才发现其实是很棒的一个东西。首先我们来看看它作为marker的两个重要的NBT——其实Age在marker中用处几乎为0,但是要顺带讲……


    Age:指AEC存在了的时间,单位是gt。也就是说每gt自动+1
    Duration:指AEC能存在的时间,单位也是gt。这是一个固有值,当Age达到这个数值的时候,AEC会消失。Duration最大值是2147483647,即2^31-1,超过这数字会溢出——注意:这个数值大概是3年4个月,对于一个MC存档来说,几乎等价于永久marker了


  这两个NBT如果默认的话,就是0,也就是说,如果没有指定AEC的Duration的话,AEC会存在短短的一瞬间。
  这就意味着,如果使用AEC作为临时的Marker的话,不需要我们使用kill/tp之类的指令来清除它。


  显然用于Marker的AEC,我们只需要考虑一个标签,那就是Duration。
  这里给出一条生成永久marker的指令,用2100000000(8个0)是因为懒得打2147483647,Duration:2100000000的AEC持续时间大约是3年3月,你们觉得一个CB存档可能运行3年吗(笑)?

代码:

  1. /summon AreaEffectCloud x y z {Duration:2100000000,CustomName:"xxx",Tags:["a","b"]}

  对于单点放置,可以用tab补全x y z,对于大量放置,可以用下面的指令:

代码:

  1. icb:/fill x1 y1 z1 x2 y2 z2 command_block 0 replace {auto:1,Command:"/summon AreaEffectCloud ~ ~ ~ {Duration:2100000000,CustomName:"xxx",Tags:["a","b"]}"}

  
  预计大型显示屏设备会井喷,放置这么多AEC并不会卡,但是同时执行指令的话,需要斟酌……


  可能会有很多人觉得AS更加稳妥一些,其实我觉得将来AEC完全可以取代AS成为新的marker之王,不过这并不意味着AS就失去了意义。我们应该明确一下它们各自的优缺点,了解它们分别用在什么场合更加合适。



AS
AEC
是否需要重置装置
理论上需要,实际上当Duration设定足够长的话就不需要了
作为临时marker的便捷性
需要手动清除
可以自动清除
消耗资源
G3下可见,因此有一定消耗
完全不可见,消耗资源极少
debug便捷性
比较便捷
不太方便,需要F3+b
相关NBT
Marker,Invisible,NoGravity
Duration

  下面对AEC稍微作一下总结,AS由于大家都比较了解了就不说了……
   AEC消耗的资源是很少的,我们在测试的时候放置了1万个AEC,帧数一点都没有降,如果是AS,早就崩MC了估计……
   AEC如果不打开F3+b的话,不便于debug,这一点是毋庸置疑的;
   AEC可以用来做时钟,这一点后来会稍微提到一点;
   AEC作为临时marker不需要清除,只需要设定一个很小的Duration即可;


  AEC可能会是继AS之后又一实体之王,其应用将来可能会比AS更加广泛——让我们持续关注吧23333
  如果大家有什么疑问,不妨在下方提出。


  感谢@chyx @pca006132 和其他我不记得你们ID的小伙伴们!


  翻页可以看时钟。





  关于AEC时钟,我一向是这样的——假设朝东放置,其他朝向自己修改第二条指令的参数

代码:

  1. rcb:/testfor @e[r=0] {Age:1200}
  2. cond:/entitydata @e[dx=-1,r=1] {Age:0}
  3. cond:/say pha~

  然后,在RCB的位置执行这样的指令(可以指着rcb然后用tab补全坐标)

代码:

  1. /summon AreaEffectCloud x y z {Duration:999999}

  这里的Duraion比前面Age的数字大就可以了。
  这样,每隔1分钟(=1200 gt),就会显示一次[@] pha,其他指令同理……


  上面是一种偷懒的写法,可能会是一个不太好的习惯,避免冲突的话,可以给AEC指定一个name或者tag,然后改成像下面这样(举例)

代码:

  1. mark:aecTimer
  2. rcb:/testfor @e[name=aecTimer,type=AreaEffectCloud] {Age:20}
  3. cond:say 1秒钟过去了……
  4. /testfor @e[name=aceTimer,type=AreaEffectCloud] {Age:40}
  5. cond:say 2秒钟过去了……
  6. /testfor @e[name=aecTimer,type=AreaEffectCloud] {Age:1200}
  7. cond:/entitydata @e[name=aecTimer,type=AreaEffectCloud] {Age:0}
  8. cond:/say 1分钟到!重置时钟

  好了,本次讨论到此结束~

青格大D
原来是CBL的,为何不领勋章?

zzppq2012
新人路过帮顶

秋一
青格大D 发表于 2015-11-28 20:15
原来是CBL的,为何不领勋章?

我不怎么玩论坛,不会领……

949889780
acordome 发表于 2015-11-28 20:26
我不怎么玩论坛,不会领……

到快捷方式里面
有个勋章
点进去

chyx
我居然成了国内aec神教领袖。。。
其实想debug只需按下f3+b

秋一
chyx 发表于 2015-11-28 22:15
我居然成了国内aec神教领袖。。。
其实想debug只需按下f3+b

F3+b是真理

pca006132
此特性被发现之后,各种大量实体标记位置的系统就相继出现,实体数破万不是梦!
(然而每个命令可能要执行上万次,请小心使用,尤其是在服务器,我就是一个失败的例子)

下一页 最后一页