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方法中注册,以确保它在正确的时候被注册。

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));
}

如上所示,一旦创建并注册了BlockEntityType,就可以在Block类中简单地实现BlockEntityProvider

@Override
public BlockEntity createBlockEntity(BlockView blockView) {
   return new DemoBlockEntity();
}

序列化数据

如果要将任何数据存储在BlockEntity中,则需要保存并加载,或者仅在加载BlockEntity时保留,并且只要您返回到它。幸运的是,保存和加载非常简单-您只需要覆盖toTag()fromTag()即可。

toTag()返回一个CompoundTag,其中应包含BlockEntity中的所有数据。如果您需要将BlockEntity数据与客户端同步,则此数据将保存到磁盘并通过数据包发送。调用toTag的默认实现非常重要,因为它将“标识数据(位置和ID)保存到标签中。否则,您尝试保存的所有其他数据都将丢失,因为它与头寸和BlockEntityType不相关。知道了这一点,下面的示例演示了如何将BlockEntity中的整数保存到标签中。在此示例中,整数保存在键数字下-您可以将其替换为任何字符串,但是标签中的每个键只能有一个条目,并且需要记住该键以便以后检索数据。

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;
   }
}

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.

// Deserialize the BlockEntity
public void fromTag(CompoundTag tag) {
   super.fromTag(tag);
   number = tag.getInt("number");
}

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.1576732470.txt.gz · Last modified: 2019/12/19 05:14 by lightcolour