User Tools

Site Tools


zh_cn:tutorial:blockentity

This is an old revision of the document!


添加一个方块实体

介绍

BlockEntity主要用于在块内存储数据。 在创建一个之前,您需要一个 Block。 本教程将介绍BlockEntity类的创建及其注册。

创建一个方块实体

最简单的块实体仅扩展BlockEntity,并使用默认构造函数。 这是完全有效的,但不会为您的块授予任何特殊功能。

public class DemoBlockEntity extends BlockEntity {
   public DemoBlockEntity() {
      super(ExampleMod.DEMO_BLOCK_ENTITY);
   }
}

Bellow将向您展示如何创建ExampleMod.DEMO_BLOCK_ENTITY字段。

您可以简单地向此准系统类添加变量,或实现诸如TickableInventory之类的接口以添加更多功能。Tickable提供了一个单独的tick()方法,该滴答对世界上每个已加载的Block实例每滴答被调用一次。而``Inventory则允许您的BlockEntity与自动化进行交互,例如 料斗-稍后可能会有专门针对此界面的单独教程。 ===== 注册你的方块实体 ===== 一旦创建了BlockEntity类,您将需要对其进行注册以使其起作用。 此过程的第一步是创建一个BlockEntityType,它将BlockBlockEntity链接在一起。 假设您的Block已创建并保存到本地变量DEMO_BLOCK,则将在下面的行中创建匹配的BlockEntityTypemodid:demo应替换为您的Mod ID和您要在其下注册BlockEntity的名称。 BlockEntityType应在您的onInitialize方法中注册,以确保它在正确的时候被注册。 <code java> public static BlockEntityType<DemoBlockEntity> DEMO_BLOCK_ENTITY; @Override public void onInitialize() { DEMO_BLOCK_ENTITY = Registry.register(Registry.BLOCK_ENTITY, “modid:demo”, BlockEntityType.Builder.create(DemoBlockEntity::new, DEMO_BLOCK).build(null)); } </code> 如上所示,一旦创建并注册了BlockEntityType,就可以在Block类中简单地实现BlockEntityProvider: <code java> @Override public BlockEntity createBlockEntity(BlockView blockView) { return new DemoBlockEntity(); } </code> ===== 序列化数据 ===== If you want to store any data in your BlockEntity, you will need to save and load it, or it will only be held while the BlockEntity is loaded, and the data will reset whenever you come back to it. Luckily, saving and loading is quite simple - you only need to override toTag() and fromTag(). toTag() returns a CompoundTag, which should contain all of the data in your BlockEntity. This data is saved to the disk and also send through packets if you need to sync your BlockEntity data with clients. It is very important to call the default implementation of toTag, as it saves “Identifying Data” (position and ID) to the tag. Without this, any further data you try and save will be lost as it is not associated with a position and BlockEntityType. Knowing this, the example below demonstrates saving an integer from your BlockEntity to the tag. In the example, the integer is saved under the key “number” - you can replace this with any string, but you can only have one entry for each key in your tag, and you will need to remember the key in order to retrieve the data later. <code java> public class DemoBlockEntity extends BlockEntity { Store the current value of the number private int number = 7; public DemoBlockEntity() { super(ExampleMod.DEMO_BLOCK_ENTITY); } Serialize the BlockEntity public CompoundTag toTag(CompoundTag tag) { super.toTag(tag); Save the current value of the number to the tag tag.putInt(“number”, number); return tag; } } </code> In order to retrieve the data later, you will also need to override fromTag. This method is the opposite of toTag - instead of saving your data to a CompoundTag, you are given the tag which you saved earlier, enabling you to retrieve any data that you need. As with toTag, it is essential that you call super.fromTag, and you will need to use the same keys to retrieve data that you saved. To retrieve, the number we saved earlier, see the example below. <code java> Deserialize the BlockEntity public void fromTag(CompoundTag tag) { super.fromTag(tag); number = tag.getInt(“number”); } </code> Once you have implemented the toTag and fromTag methods, you simply need to ensure that they are called at the right time. Whenever your BlockEntity data changes and needs to be saved, call markDirty(). This will force the toTag method to be called when the world is next saved by marking the chunk which your block is in as dirty. As a general rule of thumb, simply call markDirty() whenever you change any custom variable in your BlockEntity class. If you need to sync some of your BlockEntity data to the client, for purposes such as rendering, you should implement BlockEntityClientSerializable from the Fabric API. This class provides the fromClientTag and toClientTag methods, which work much the same as the previously discussed fromTag and toTag methods, except that they are used specifically for sending to and receiving data on the client. ===== Overview ===== You should now have your very own BlockEntity, which you can expand in various ways to suit your needs. You registered a BlockEntityType, and used it to connect your Block and BlockEntity classes together. Then, you implemented BlockEntityProvider in your Block class, and used the interface to provide an instance of your new BlockEntity. Finally, you learned how to save data to your BlockEntity'', and how to retrieve for use later.

zh_cn/tutorial/blockentity.1576732308.txt.gz · Last modified: 2019/12/19 05:11 by lightcolour