开启辅助访问     
收藏本站

站内搜索

搜索

Minecraft(我的世界)苦力怕论坛

[BE教程] 附加包教程:48.自定义组件(三)

 发表于 2024-8-22 09:21:36 来自手机|显示全部楼层|阅读模式 IP:山西省
本帖最后由 Cat_Anchor 于 2024-10-6 10:34 编辑

注意:此页面所述功能是方块和物品事件的新版本,也就是假日创作者实验移除后的正式特性。由于作者刚学 JavaScript,内容可能有误。


前言
上期,我们演示了自定义组件的一些例子。这期,我们将继续列举自定义组件的例子,同时这期是自定义组件三部曲的最后一期。
生成实体
来看下面的代码。
  1. const blockComponents = [{
  2.   id: "supplementary:tower2_block",
  3.   trigger: {
  4.     onPlace: (e) => { ... }
  5.   }
  6. },{
  7.   id: "supplementary:select_rock_shape",
  8.   trigger: {
  9.     onPlace: (e) => { ... }
  10.   }
  11. },{
  12.   id: "supplementary:sacred_geometry_particle",
  13.   trigger: {
  14.     onTick: (e) => { ... }
  15.   }
  16. }];
复制代码

这期,我们就要讲解这三个自定义组件。首先是第一个,它的作用是放置方块后立刻生成一个实体。

生成实体可以用 dimension 类中的 spawnEntity 方法,但是它需要一个位置,所以我们先定义生成的位置。
  1. const spawnLocation = {
  2.   x: e.block.location.x,
  3.   y: e.block.location.y - 1.125,
  4.   z: e.block.location.z
  5. };
复制代码

这串代码中,定义了 spawnLocation 这个常量,它是一个矢量。其中 e.block 是事件涉及到的方块,而 location 可以获取这个方块的位置。它有三个属性 x y z,分别代表 X Y Z 轴。其中 e.block.location.y,也就是方块的 Y 轴坐标,减去了 1.125,会导致生成实体的位置低于方块 1.125 格。

然后就能用 spawnEntity 方法了,如下:
  1. e.block.dimension.spawnEntity('supplementary:tower2_display', spawnLocation);
复制代码

spawnEntity 有两个必填的参数,第一个是实体的 ID,第二个是生成的位置,这里就是之前定义的 spawnLocation。所以方块被放置后会触发 onPlace 触发器,然后生成实体。
随机状态
接下来看第二个自定义组件,它的作用是随机选择并设置一种方块状态,方块状态的值是 1 和 5 之间的一个整数(包含)。

所以和上期一样,我们首先获取这个方块状态的值,赋值给 stateValue。
  1. const stateValue = e.block.permutation.getState('supplementary:rock_shape');
复制代码

接下来是一个问题,如何生成随机的值?在 Molang 里,我们有 math.random 之类的数学函数;在 JavaScript 里,我们照样有 Math.random 这个函数,不过它没有任何参数,只能写成 Math.random() 这样的。那么它的作用是什么?其实就是生成 0 和 1 之间的随机浮点数。
  1. const randomValue = Math.random();
复制代码

所以,为了生成 1..5 这样的值,我们要对返回值乘 4,这样变成了 0..4 的随机数。
  1. const randomValue = Math.random() * 4;
复制代码

然后再加 1,这样就是 1..5 的随机数了。
  1. const randomValue = Math.random() * 4 + 1;
复制代码

不过会生成浮点数,我们要用 Math.round 函数取整,如下:
  1. const randomValue = Math.round(Math.random() * 4 + 1);
复制代码

接下来是一些防止异常的判断。
  1. if (e.player === undefined || stateValue === undefined || typeof stateValue !== 'number') return;
复制代码

如果玩家未定义,或者方块状态未定义或不是数字类型的,那么直接停止执行。

接下来我们可以设置方块状态了。
  1. e.block.setPermutation(e.block.permutation.withState('supplementary:rock_shape', randomValue));
复制代码

与以前一样,我们用 withState 方法获取方块状态,然后用 setPermutation 设置,值就是刚才定义的 randomValue。
生成粒子
现在我们来看第三个自定义组件,它的作用是通过计划刻生成两种粒子。

生成粒子和生成实体相似,可以用 dimension 类中的 spawnParticle 方法,但是它也需要一个位置,我们先定义粒子生成的位置。
  1. const spawnParticleLocation = {
  2.   x: e.block.location.x,
  3.   y: e.block.location.y + 0.25,
  4.   z: e.block.location.z
  5. };
复制代码

现在我们定义了 spawnParticleLocation 这个矢量,其中 e.block 是事件涉及到的方块,而 location 获取这个方块的位置。我们在 Y 轴上加上 0.25 这个数字,导致生成粒子的位置高于方块 0.25 格。

然后我们使用 spawnParticle 方法生成粒子,如下:
  1. e.block.dimension.spawnParticle('supplementary:sacred_geometry_dust_particle', spawnParticleLocation);
复制代码

spawnParticle 方法,与 spawnEntity 方法类似,有两个必填的参数,第一个是粒子的 ID,第二个是生成的位置。这行代码导致指定粒子生成在刚才定义的位置。
当然,也可以再生成一个粒子,如下:
  1. e.block.dimension.spawnParticle('supplementary:sacred_geometry_dust_particle', spawnParticleLocation);
  2. e.block.dimension.spawnParticle('supplementary:sacred_geometry_activated_particle', spawnParticleLocation);
复制代码

现在我们可以生成两个粒子了。
这三个自定义组件的全部代码,按照上上期的方法写在数组里,如下:
  1. const blockComponents = [{
  2.   id: "supplementary:tower2_block",
  3.   trigger: {
  4.     onPlace: (e) => {
  5.       const spawnLocation = {
  6.         x: e.block.location.x,
  7.         y: e.block.location.y - 1.125,
  8.         z: e.block.location.z
  9.       };
  10.       e.block.dimension.spawnEntity('supplementary:tower2_display', spawnLocation);
  11.     }
  12.   }
  13. },{
  14.   id: "supplementary:select_rock_shape",
  15.   trigger: {
  16.     onPlace: (e) => {
  17.       const randomValue = Math.round(Math.random() * 4 + 1);
  18.       const stateValue = e.block.permutation.getState('supplementary:rock_shape');
  19.       if (e.player === undefined || stateValue === undefined || typeof stateValue !== 'number') return;
  20.       e.block.setPermutation(e.block.permutation.withState('supplementary:rock_shape', randomValue));
  21.     }
  22.   }
  23. },{
  24.   id: "supplementary:sacred_geometry_particle",
  25.   trigger: {
  26.     onTick: (e) => {
  27.       const spawnParticleLocation = {
  28.         x: e.block.location.x,
  29.         y: e.block.location.y + 0.25,
  30.         z: e.block.location.z
  31.       };
  32.       e.block.dimension.spawnParticle('supplementary:sacred_geometry_dust_particle', spawnParticleLocation);
  33.       e.block.dimension.spawnParticle('supplementary:sacred_geometry_activated_particle', spawnParticleLocation);
  34.     }
  35.   }
  36. }]
复制代码
总结
这一期,我解释了三个自定义组件。自定义组件就是这样,用脚本实现一些或简单或复杂的逻辑。
这是自定义组件系列的第三期,自定义组件教程即将结束了,但如果你们觉得还有什么自定义组件需要做教程,欢迎在下方留言,我会尽力做出教程。
我的代码可能有误,或者不完善,或者可以优化,欢迎指出错误并提出建议。


苦力怕论坛,感谢有您~
 发表于 2024-8-22 14:41:58 来自手机|显示全部楼层 IP:江西省
shssgddndveudhfyrn
4#2024-8-22 14:41:58回复收起回复
苦力怕论坛,感谢有您~
回复支持

使用道具举报

 发表于 2024-8-22 12:15:31 来自手机|显示全部楼层 IP:山西省
本帖最后由 指令凋灵 于 2024-8-22 12:21 编辑

文中向量数组建议改成object或坐标对象或直接称矢量(vector)
(第二章呢?)
3#2024-8-22 12:15:31收起回复
Cat_Anchor2024-8-22 13:42IP:山西省
回复举报
感谢建议,已修改。
另外,我修改了第二章之后它又进审核了,现在应该能看见了
指令凋灵回复Cat_Anchor2024-8-22 22:39IP:山西省
回复举报
提个知识,我在第二章提到Block、BlockEvents等模块,具体什么时候import呢?在需要new的时候,如new ItemStack("minecraft:stick", 1);
这时候就需要导入ItemStack模块
指令凋灵回复指令凋灵2024-8-22 22:41IP:山西省
回复举报
还有一种情况,比如world这种类,也需要import
Cat_Anchor回复指令凋灵2024-8-23 08:27IP:山西省
回复举报
好的,感谢提醒
苦力怕论坛,感谢有您~
回复支持

使用道具举报

 发表于 2024-8-22 09:39:29 来自手机|显示全部楼层 IP:山东省
感谢教程,不过后面还会有关于script api的附加包教程了吗
2#2024-8-22 09:39:29收起回复
Cat_Anchor2024-8-22 13:46IP:山西省
回复举报
会,但我这些教程建立于实际需求上,我要是开发一个附加包用到了SAPI就可能会出教程,但我28日开学,所以最近出教程的希望不大
Cat_Anchor2024-8-22 13:48IP:山西省
回复举报
比如我要开发一个附加包,需要用到动态属性,那我大概率会出教程,但目前我几乎没在开发任何附加包
苦力怕论坛,感谢有您~
回复支持

使用道具举报

本版积分规则

本站
关于我们
联系我们
坛史纲要
官方
哔哩哔哩
技术博客
下载
网易版
安卓版
JAVA
反馈
意见建议
教程中心
更多
捐助本站
QQ群
QQ群

QQ群

访问手机版

访问手机版

手机版|小黑屋|系统状态|klpbbs.com

粤公网安备 44200002445329号 | 由 木韩网络 提供支持 | GMT+8, 2024-12-15 14:43

声明:本站与Mojang以及微软公司没有从属关系

Powered by Discuz! X3.4 粤ICP备2023071842号-3