feat:上传mcguide-开发指南部份
This commit is contained in:
154
mcguide/20-玩法开发/15-自定义游戏内容/2-自定义方块/4-自定义方块实体.md
Normal file
154
mcguide/20-玩法开发/15-自定义游戏内容/2-自定义方块/4-自定义方块实体.md
Normal file
@@ -0,0 +1,154 @@
|
||||
---
|
||||
front:
|
||||
hard: 入门
|
||||
time: 分钟
|
||||
---
|
||||
|
||||
# 自定义方块实体
|
||||
|
||||
## 概念
|
||||
|
||||
方块实体的概念详见[官方wiki](https://minecraft-zh.gamepedia.com/方块实体)
|
||||
|
||||
|
||||
|
||||
## 添加自定义方块实体
|
||||
|
||||
需要添加netease:block_entity组件才能为自定义方块添加自定义方块实体。
|
||||
|
||||
| 键 | 类型 | 默认值 | 解释 |
|
||||
| ------- | ---- | ------ | ------------------------------------------------------------ |
|
||||
| tick | bool | false | 为true时,当玩家进入方块tick范围时,该方块每秒会发送**20次**ServerBlockEntityTickEvent事件<br>为false时,该方块不会发送ServerBlockEntityTickEvent事件 |
|
||||
| client_tick | bool | false | 为true时,当玩家进入方块tick范围时,该方块每秒会发送**20次**ModBlockEntityTickClientEvent事件<br>为false时,该方块不会发送ModBlockEntityTickClientEvent事件 |
|
||||
| movable | bool | true | 为true时,该方块可被粘性活塞拉回<br>为false时,该方块不可被粘性活塞拉回 |
|
||||
|
||||
- **对于已有方块实体的方块,如[自定义刷怪箱](./3-特殊方块/1-自定义刷怪箱.md),将无法再添加自定义方块实体。**
|
||||
|
||||
- 添加了自定义方块实体的方块,可通过**服务端blockEntityData组件**来管理方块实体内的数据。
|
||||
|
||||
|
||||
|
||||
## 相关组件与事件
|
||||
|
||||
- <a href="../../../../mcdocs/1-ModAPI/接口/方块/方块实体.html#getblockentitydata" rel="noopenner"> GetBlockEntityData接口 </a>
|
||||
|
||||
可用于管理方块实体内的数据。
|
||||
|
||||
- <a href="../../../../mcdocs/1-ModAPI/事件/方块.html#serverplaceblockentityevent" rel="noopenner"> ServerPlaceBlockEntityEvent事件 </a>
|
||||
|
||||
当玩家手动放置含自定义方块实体的自定义方块时触发,此时可向该方块实体中存储数据。
|
||||
|
||||
- <a href="../../../../mcdocs/1-ModAPI/事件/世界.html#chunkgeneratedserverevent" rel="noopenner"> ChunkGeneratedServerEvent事件 </a>
|
||||
|
||||
通过自定义特征放置含自定义方块实体的自定义方块时,在区块生成完毕时触发,其中包含了该区块中自定义方块实体信息列表,此时可向该方块实体中存储数据。
|
||||
|
||||
- <a href="../../../../mcdocs/1-ModAPI/事件/方块.html#serverblockentitytickevent" rel="noopenner"> ServerBlockEntityTickEvent事件 </a>
|
||||
|
||||
若在netease:block_entity组件中配置tick为true,则当该自定义方块位于模拟范围内时触发。该事件触发频率为**每秒20次**
|
||||
|
||||
|
||||
|
||||
<span id="demo"></span>
|
||||
## demo解释
|
||||
|
||||
- 方块配置
|
||||
|
||||
[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)中,`customblocks:customblocks_test_block_entity`方块配置了自定义方块实体,具体配置如下:
|
||||
|
||||
即该方块在距离玩家不远时会每秒发送20次ServerBlockEntityTickEvent事件,且无法被粘性活塞拉回。
|
||||
|
||||

|
||||
|
||||
- 方块放置
|
||||
|
||||
customBlocksServer.py中注册了对ServerPlaceBlockEntityEvent事件的监听,在回调里通过blockEntityData组件向每个由玩家手动创建的自定义方块实体中写入数据:
|
||||
|
||||
```python
|
||||
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方块进行交互。是则向其中写入数据:
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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方块时,会尝试从其自定义方块实体中读取数据并输出。
|
||||
|
||||
```python
|
||||
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方块,当玩家尝试摧毁它时,会输出:
|
||||
|
||||
```python
|
||||
# 不存在于方块实体中的数据将返回None
|
||||
'value of "key" is None'
|
||||
'value of "abc" is {"1": True, "2": None, "3": "123"}'
|
||||
```
|
||||
|
||||
- 若玩家曾经与该方块进行过交互,会输出:
|
||||
|
||||
```python
|
||||
'value of "key" is [1, 2, 3]'
|
||||
'value of "abc" is {"1": True, "2": None, "3": "123"}'
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user