UID 82897 性别 保密 经验 EP 铁粒 粒 回帖 0 主题 精华 在线时间 小时 注册时间 2021-7-23 最后登录 1970-1-1
本帖最后由 Cat_Anchor 于 2024-10-6 10:34 编辑 注意:此页面所述功能是方块和物品事件的新版本,也就是假日创作者实验移除后的正式特性。由于作者刚学 JavaScript,内容可能有误。
前言
上期,我们演示了自定义组件的一些例子。这期,我们将继续列举自定义组件的例子,同时这期是自定义组件三部曲的最后一期。 生成实体
来看下面的代码。const blockComponents = [{ id: "supplementary:tower2_block", trigger: { onPlace: (e) => { ... } } },{ id: "supplementary:select_rock_shape", trigger: { onPlace: (e) => { ... } } },{ id: "supplementary:sacred_geometry_particle", trigger: { onTick: (e) => { ... } } }]; 复制代码
这期,我们就要讲解这三个自定义组件。首先是第一个,它的作用是放置方块后立刻生成一个实体。
生成实体可以用 dimension 类中的 spawnEntity 方法,但是它需要一个位置,所以我们先定义生成的位置。const spawnLocation = { x: e.block.location.x, y: e.block.location.y - 1.125, z: e.block.location.z }; 复制代码
这串代码中,定义了 spawnLocation 这个常量,它是一个矢量。其中 e.block 是事件涉及到的方块,而 location 可以获取这个方块的位置。它有三个属性 x y z,分别代表 X Y Z 轴。其中 e.block.location.y,也就是方块的 Y 轴坐标,减去了 1.125,会导致生成实体的位置低于方块 1.125 格。
然后就能用 spawnEntity 方法了,如下:e.block.dimension.spawnEntity('supplementary:tower2_display', spawnLocation); 复制代码
spawnEntity 有两个必填的参数,第一个是实体的 ID,第二个是生成的位置,这里就是之前定义的 spawnLocation。所以方块被放置后会触发 onPlace 触发器,然后生成实体。 随机状态
接下来看第二个自定义组件,它的作用是随机选择并设置一种方块状态,方块状态的值是 1 和 5 之间的一个整数(包含)。
所以和上期一样,我们首先获取这个方块状态的值,赋值给 stateValue。const stateValue = e.block.permutation.getState('supplementary:rock_shape'); 复制代码
接下来是一个问题,如何生成随机的值?在 Molang 里,我们有 math.random 之类的数学函数;在 JavaScript 里,我们照样有 Math.random 这个函数,不过它没有任何参数,只能写成 Math.random() 这样的。那么它的作用是什么?其实就是生成 0 和 1 之间的随机浮点数。const randomValue = Math.random(); 复制代码
所以,为了生成 1..5 这样的值,我们要对返回值乘 4,这样变成了 0..4 的随机数。const randomValue = Math.random() * 4; 复制代码
然后再加 1,这样就是 1..5 的随机数了。const randomValue = Math.random() * 4 + 1; 复制代码
不过会生成浮点数,我们要用 Math.round 函数取整,如下:const randomValue = Math.round(Math.random() * 4 + 1); 复制代码
接下来是一些防止异常的判断。if (e.player === undefined || stateValue === undefined || typeof stateValue !== 'number') return; 复制代码
如果玩家未定义,或者方块状态未定义或不是数字类型的,那么直接停止执行。
接下来我们可以设置方块状态了。e.block.setPermutation(e.block.permutation.withState('supplementary:rock_shape', randomValue)); 复制代码
与以前一样,我们用 withState 方法获取方块状态,然后用 setPermutation 设置,值就是刚才定义的 randomValue。 生成粒子
现在我们来看第三个自定义组件,它的作用是通过计划刻生成两种粒子。
生成粒子和生成实体相似,可以用 dimension 类中的 spawnParticle 方法,但是它也需要一个位置,我们先定义粒子生成的位置。const spawnParticleLocation = { x: e.block.location.x, y: e.block.location.y + 0.25, z: e.block.location.z }; 复制代码
现在我们定义了 spawnParticleLocation 这个矢量,其中 e.block 是事件涉及到的方块,而 location 获取这个方块的位置。我们在 Y 轴上加上 0.25 这个数字,导致生成粒子的位置高于方块 0.25 格。
然后我们使用 spawnParticle 方法生成粒子,如下:e.block.dimension.spawnParticle('supplementary:sacred_geometry_dust_particle', spawnParticleLocation); 复制代码
spawnParticle 方法,与 spawnEntity 方法类似,有两个必填的参数,第一个是粒子的 ID,第二个是生成的位置。这行代码导致指定粒子生成在刚才定义的位置。
当然,也可以再生成一个粒子,如下:e.block.dimension.spawnParticle('supplementary:sacred_geometry_dust_particle', spawnParticleLocation); e.block.dimension.spawnParticle('supplementary:sacred_geometry_activated_particle', spawnParticleLocation); 复制代码
现在我们可以生成两个粒子了。
这三个自定义组件的全部代码,按照上上期的方法写在数组里,如下:const blockComponents = [{ id: "supplementary:tower2_block", trigger: { onPlace: (e) => { const spawnLocation = { x: e.block.location.x, y: e.block.location.y - 1.125, z: e.block.location.z }; e.block.dimension.spawnEntity('supplementary:tower2_display', spawnLocation); } } },{ id: "supplementary:select_rock_shape", trigger: { onPlace: (e) => { const randomValue = Math.round(Math.random() * 4 + 1); const stateValue = e.block.permutation.getState('supplementary:rock_shape'); if (e.player === undefined || stateValue === undefined || typeof stateValue !== 'number') return; e.block.setPermutation(e.block.permutation.withState('supplementary:rock_shape', randomValue)); } } },{ id: "supplementary:sacred_geometry_particle", trigger: { onTick: (e) => { const spawnParticleLocation = { x: e.block.location.x, y: e.block.location.y + 0.25, z: e.block.location.z }; e.block.dimension.spawnParticle('supplementary:sacred_geometry_dust_particle', spawnParticleLocation); e.block.dimension.spawnParticle('supplementary:sacred_geometry_activated_particle', spawnParticleLocation); } } }] 复制代码 总结
这一期,我解释了三个自定义组件。自定义组件就是这样,用脚本实现一些或简单或复杂的逻辑。
这是自定义组件系列的第三期,自定义组件教程即将结束了,但如果你们觉得还有什么自定义组件需要做教程,欢迎在下方留言,我会尽力做出教程。
我的代码可能有误,或者不完善,或者可以优化,欢迎指出错误并提出建议。