本帖最后由 SPE__HaiKuo 于 2022-9-18 22:47 编辑
看到AE、TR、EIO等等的管道网络,是否十分心动,也想要在自己的Mod里面添加属于自己的线缆网络?
那么这篇教程将会阐述如何在1.18.2 Fabric中添加一个 简单、可拓展、可移植 的线缆网络!
本教程为进阶教程,不包含基础方面如如何添加 Block 和 BlockEntity 等,基础教程请移步 Fabric Wiki
本教程中具体实现和Fabric特性关系不大,用Forge只需稍作修改即可!
前期准备
构建网络类
构建网络相关服务
建立网络
实际效果
后续
看到AE、TR、EIO等等的管道网络,是否十分心动,也想要在自己的Mod里面添加属于自己的线缆网络?
那么这篇教程将会阐述如何在1.18.2 Fabric中添加一个 简单、可拓展、可移植 的线缆网络!
本教程为进阶教程,不包含基础方面如如何添加 Block 和 BlockEntity 等,基础教程请移步 Fabric Wiki
本教程中具体实现和Fabric特性关系不大,用Forge只需稍作修改即可!
前期准备
|
网络最重要的特征是线缆,我们首先要创建一个线缆方块。
下图是需要先创建的 Block 和 BlockEntity : 图中说明了继承关系,其中:
|
构建网络类
|
我们先将网络从Minecraft中抽离出来。
其实 网络也就只是一种数据结构——图 ,这和是不是在Minecraft中没有关系。 因此,我们可以先脱离框架,构建网络类。 对于网络,可以构建一个 Network 类,对于网络的每个结点,可以构建一个 NetworkNode 类。 一个 Network 中包含许多个 NetworkNode 结点,因此用 Set<NetworkNode> 来存储各个结点。 具体代码如下:
在 NetworkNode 中添加:
|
构建网络相关服务
|
我们采用集中式而非并行式的方法来管理网络和网络寻路,需要两个服务,一个是管理网络的服务
NetworkService
,另一个是网络寻路的服务
PathService
。所有服务都在服务端运行。
集中式服务管理经常用到以下事件:
因为要监听事件,所以服务要注册事件,就可以继承Fabric的 ModInitializer 接口,将事件注册放在 onInitialize 中。 NetworkService 我们先构建 NetworkService ,用于管理网络:
之后再构建 PathService ,用来网络寻路:
|
建立网络
|
建立网络其实就是一个图遍历问题:
将所有相邻的网络结点存放在同一个网络之中
。
那么图遍历问题的一个经典做法就是 广度优先遍历(BFS) ,这里我们也就用BFS来建立网络。 看到这里的小伙伴们可能就会有疑问: onServerEndTick 是用来干什么的呢? 其实方块加载/卸载都是在一个TICK中的异步过程,而Minecraft框架提供的 ServerTickEvents.END_SERVER_TICK 则是在一个TICK结束时的同步过程。 因此,我们用一个队列来存储异步过程中需要进行寻路的结点,在同步过程中进行寻路处理即可! 声明一个处理队列,并在服务端启动时进行初始化:
我们先关注 getPossibleConnection ,即所有可能的连接。 在 BaseBlockEntity 中添加:
在 NetworkNode 中添加:
最后是 mergeNetwork ,即合并两个网络,这里采用一种启发式的方法来高效合并两个网络,即将小的网络合并到大的网络。 在 Network 中添加:
|
实际效果
|
大功告成:3! |
后续
|
如果想要对构建后的网络做些什么,也很简单。
可以继续创建一个服务,用来负责处理网络功能,可以与事件 ServerTickEvents.START_SERVER_TICK 绑定,之后想怎么弄就怎么弄了! 之后或许会再出个线缆渲染的教程,看情况吧_(:з)∠)_ |
