04 方块实体
1 方块实体的概念与内容
1.1 什么是方块实体?
方块本身通过预定义的有限 BlockState 集合保存数据;通过默认的方块渲染行为渲染模型;通过更新系统、计划系统等决定执行逻辑。
但是,这样的模式具有局限性, 无法直接满足在游戏交互中一些方块的功能。
因此,我们需要一种专门帮助特定方块存储数据,实时处理逻辑,进行额外渲染的组件。我们叫它们方块实体。
方块实体相为普通方块提供了三个重要的额外功能: 使用 NBT 存储数据、自定义的渲染行为 和 在每一次 tick 中进行更新。
方块实体通过 NBT 来存储数据,和实体一样。而且,与方块状态不同,
方块实体的数据不会自动同步到客户端: 方块实体必须自己声明何时同步以及同步哪些数据。
1.2 方块实体的内容
方块实体是因方块而异的,但一个抽象的,基本的方块实体含有以下基本信息与功能:
1.2.1 携带的信息
- type 类型
- world 所在的世界
- pos 位置
- removed 是否已被移除
- cachedState 缓存的,对应方块的状态;
1.2.2 提供的重要功能
- readNbt 读入 NBT 数据
- writeNbt 写出 NBT 数据
- tick 在服务器 tick 中执行逻辑
- render 进行自定义的渲染
1.3 带有方块实体的方块
方块实体与世界绑定,每个方块位置仅有一个方块实体实例。
2 重要的带有方块实体的方块
2.1 漏斗
在 Minecraft 中,漏斗是一种重要的方块实体,主要用于物品的自动化传输。
2.1.1 漏斗方块实体携带的信息
一个可爱的漏斗方块实体携带以下基本信息:
inventory储存空间(5 格)transferCooldown冷却(默认为 - 1)lastTickTime上一 tick 的世界时间facing朝向
2.1.2 漏斗方块实体的功能
- 将物品传输到目标容器
- 从容器中吸取物品
- 尝试吸取物品实体
2.1.3 漏斗方块实体的工作流程
每个游戏刻(tick),漏斗都会执行以下步骤:
-
减少冷却时间(cd, Cooldown)
现在,让我们移步到尝试拉取和输出的具体的逻辑。
当漏斗确定自己需要做些什么时,它会先尝试向指向的容器输出。随后,它会尝试从上方吸取物品。最后,如果吸取和输出中有任意一方成功了,它就会设置冷却,并更新同步自己的数据。
我们分别来看输出和拉取的逻辑。
先看输出...
输出输出操作由 insert() 方法完成,它的作用是将物品从漏斗传输到目标容器,并返回一个布尔值来表示是否成功传输。如果传输成功,则漏斗进入冷却状态。
输出的基本逻辑:
-
确认目标容器是否可用
- 如果目标容器已满,则输出失败。
- 如果目标容器有可用槽位,则尝试传输物品。
-
尝试输出物品
- 遍历漏斗中的物品槽,逐个尝试传输物品到目标容器。
- 只要有一次传输成功,就返回 “成功”;否则返回 “失败”。
当调用 transfer() 方法尝试传输物品时,transfer() 方法会返回一个物品组:
- 若返回值为空,则说明物品已完全传输,输出成功。
- 若返回值不为空,则说明物品未能全部传输,输出失败。
到此,输出的部分已经完成,接下来,我们来看看拉取的部分。
拉取物品的逻辑与输出类似,但方向相反:
- 输出 时:漏斗
transfer()物品至目标容器。 - 拉取 时:某个容器
transfer()物品至漏斗。
由于 transfer() 方法的逻辑马上会详细解释,因此这里不再赘述。
transfer() 是漏斗实现物品传输的核心方法。它接收以下参数:
- from:物品来源(可以是漏斗或其他容器)
- to:传输目标(可以是容器或另一个漏斗)
- itemStack:希望传输的物品组
- slot:目标容器中的目标槽位
执行流程如下:
到此,你已经完全了解了漏斗的基本运作机制。相信这将会对之后的篇章理解提供很大的帮助。
2.1.4 移动中的活塞
另外一个及其重要的方块叫 moving_piston,移动的活塞,俗称 b36。
2.1.5 移动的活塞方块实体携带的信息
一个移动活塞方块实体携带一下基本信息:
pushedBlock存储的方块facing朝向extending是否在伸出(与动画播放的方向有关)source是否是收回中的活塞本体progress当前的移动进度
2.1.6 移动的活塞方块实体的功能
- 处理活塞推送实体
- 更新动画进度
- 如果
progress>=1,则将 MOVING_PISTON 替换为pushedBlock中存储的方块 - 在客户端渲染动画
2.1.7 移动的活塞方块实体的工作流程
详情见。





