# 自定义方块实体

# 概念

方块实体的概念详见官方wiki (opens new window)

# 添加自定义方块实体

需要添加netease:block_entity组件才能为自定义方块添加自定义方块实体。

类型 默认值 解释
tick bool false 为true时,当玩家进入方块tick范围时,该方块每秒会发送20次ServerBlockEntityTickEvent事件
为false时,该方块不会发送ServerBlockEntityTickEvent事件
client_tick bool false 为true时,当玩家进入方块tick范围时,该方块每秒会发送20次ModBlockEntityTickClientEvent事件
为false时,该方块不会发送ModBlockEntityTickClientEvent事件
movable bool true 为true时,该方块可被粘性活塞拉回
为false时,该方块不可被粘性活塞拉回
  • 对于已有方块实体的方块,如自定义刷怪箱,将无法再添加自定义方块实体。

  • 添加了自定义方块实体的方块,可通过服务端blockEntityData组件来管理方块实体内的数据。

# 相关组件与事件

  • GetBlockEntityData接口

    可用于管理方块实体内的数据。

  • ServerPlaceBlockEntityEvent事件

    当玩家手动放置含自定义方块实体的自定义方块时触发,此时可向该方块实体中存储数据。

  • ChunkGeneratedServerEvent事件

    通过自定义特征放置含自定义方块实体的自定义方块时,在区块生成完毕时触发,其中包含了该区块中自定义方块实体信息列表,此时可向该方块实体中存储数据。

  • ServerBlockEntityTickEvent事件

    若在netease:block_entity组件中配置tick为true,则当该自定义方块位于模拟范围内时触发。该事件触发频率为每秒20次

# demo解释

  • 方块配置

    CustomBlocksMod中,customblocks:customblocks_test_block_entity方块配置了自定义方块实体,具体配置如下:

    即该方块在距离玩家不远时会每秒发送20次ServerBlockEntityTickEvent事件,且无法被粘性活塞拉回。

block_entity_1

  • 方块放置

    customBlocksServer.py中注册了对ServerPlaceBlockEntityEvent事件的监听,在回调里通过blockEntityData组件向每个由玩家手动创建的自定义方块实体中写入数据:

    def ServerPlaceBlockEntityEvent(self, args):
    		print 'ServerPlaceBlockEntityEvent  ', args
    		dimension = args['dimension']  # 该自定义方块实体所在的维度
    		blockPos = (args['posX'], args['posY'], args['posZ'])  # 该自定义方块实体所处位置
    		blockName = args['blockName']  # 含该自定义方块实体的方块名称
            
            # 创建blockEntityData组件
    		comp = self.CreateComponent(self.levelId, "Minecraft", "blockEntityData")
            # 获取可操作该自定义方块实体的对象
    		blockEntityData = comp.GetBlockEntityData(dimension, blockPos)
            # 在对自定义方块实体内数据进行操作前,要先进行判空处理
            if blockEntityData:
                # 使用与dict类似的操作方式存入键为"abc"、值为{"1":True,"2":None,"3":"123"}的数据
    			blockEntityData['abc'] = {"1": True, "2": None, "3": "123"}
    
  • 方块交互

    监听了ServerBlockUseEvent,在其中判断玩家是否在与customblocks:customblocks_test_block_entity方块进行交互。是则向其中写入数据:

    def ServerBlockUseEvent(self, args):
    		blockName = args['blockName']  					# 方块名称
    		blockPos = (args['x'], args['y'], args['z'])    # 方块位置
    		playerId = args['playerId']						# 玩家id
    		dimensionComp = serverApi.CreateComponent(playerId, "Minecraft", "dimension")
    		dimension = dimensionComp.GetPlayerDimensionId() # 获取玩家所在维度
            # 判断交互的方块类型
    		if blockName == 'customblocks:customblocks_test_block_entity':
    			comp = self.CreateComponent(self.levelId, "Minecraft", "blockEntityData")
    			blockEntityData = comp.GetBlockEntityData(dimension, blockPos)
                if blockEntityData:
                    # 向方块实体中写入键为"key"、值为[1, 2, 3]的数据
    				blockEntityData['key'] = [1, 2, 3]
    
  • 方块实体tick

    def OnBlockEntityTick(self, args):
    		# 避免在Tick中频繁打印输出,易造成卡顿
    		# print 'blockEntityTick ', args
    		pass
    

    监听了ServerBlockEntityTickEvent事件,netease:block_entity组件中配置tick为true的自定义方块每秒会触发20次其自定义方块实体tick事件。

    • 应避免在诸如tick事件回调等高频函数中进行打印输出,易造成卡顿。

    • 应避免在地图中放置过多netease:block_entity组件配置tick为true的自定义方块,频繁事件调用也可能造成卡顿

  • 方块销毁

    监听了ServerPlayerTryDestroyBlockEvent事件,当有玩家尝试摧毁customblocks:customblocks_test_block_entity方块时,会尝试从其自定义方块实体中读取数据并输出。

    def ServerPlayerTryDestroyBlockEvent(self, args):
    		pos = (args["x"], args["y"], args["z"])
    		playerId = args['playerId']
    		dimensionComp = serverApi.CreateComponent(playerId, "Minecraft", "dimension")
    		dimension = dimensionComp.GetPlayerDimensionId()
    		comp = self.CreateComponent(self.levelId, "Minecraft", "blockEntityData")
    		blockEntityData = comp.GetBlockEntityData(dimension, pos)
    		if blockEntityData:
                # 根据key获取方块实体中对应的value
                value1 = blockEntityData['key']
                value2 = blockEntityData['abc']
                print 'value of "key" is', value1
                print 'value of "abc" is', value2
    
    • 对于从未进行过交互的customblocks:customblocks_test_block_entity方块,当玩家尝试摧毁它时,会输出:

      # 不存在于方块实体中的数据将返回None
      'value of "key" is None'
      'value of "abc" is {"1": True, "2": None, "3": "123"}'
      
    • 若玩家曾经与该方块进行过交互,会输出:

      'value of "key" is [1, 2, 3]'
      'value of "abc" is {"1": True, "2": None, "3": "123"}'