Files
netease-bedrock-wiki/mconline/20-玩法地图教程/第08章:在开头添加引导关卡/课程03.使用生物寻路和粒子实现自然的转场效果.md
2025-08-25 18:36:29 +08:00

189 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
front: https://nie.res.netease.com/r/pic/20210730/ee109f39-8987-46e0-9fe7-40ebb23060fa.png
hard: 进阶
time: 40分钟
---
# 制作小船带玩家离开新手岛
完成新手引导后,玩家需要乘船离开岛屿,先制作一个小船使其可以漂浮在水上并且具有寻路的组件:
```json
{
"format_version":"1.16.0",
"minecraft:entity":{
"description":{
"identifier":"farm:guide_boat",
"is_spawnable":true,
"is_summonable":true,
"is_experimental":false
},
"components": {
"minecraft:buoyant": { //使实体可以像船一样漂浮在水面上
"apply_gravity": true,
"base_buoyancy": 1.0,
"simulate_waves": true,
"big_wave_probability": 0.03,
"big_wave_speed": 10.0,
"drag_down_on_buoyancy_removed": 0,
"liquid_blocks": ["water"]
},
"minecraft:underwater_movement": { //水中的移动速度
"value": 0.25
},
"minecraft:navigation.walk": { //寻路组件(不会沉底)
"can_sink": false
},
"minecraft:rideable": { //玩家可以骑乘实体
"seat_count": 1,
"family_types": ["player"],
"interact_text": "action.interact.enter_boat",
"seats": {
"position": [0, 0.5, 0]
}
},
"minecraft:follow_range": {
"value": 64,
"max": 64
},
"minecraft:health": {
"value": 10,
"max": 10
},
"minecraft:movement": {
"value": 0.25
},
"minecraft:movement.basic": {},
"minecraft:collision_box": {
"width": 1,
"height": 1
},
"minecraft:physics": {}
},
"component_groups":{
"boat_finding":{ //通过py添加的组件组使船可以寻找特定的方块并移动至方块位置
"minecraft:behavior.move_to_block": {
"priority": 0,
"tick_interval": 1,
"start_chance": 1.0,
"search_range": 64,
"search_height": 10,
"goal_radius": 1.0,
"stay_duration": 999.0,
"target_selection_method": "nearest",
"target_offset": [
0,
0,
0
],
"target_blocks": [ //寻找的方块
"minecraft:double_wooden_slab:1"
],
"on_reach": [ //到达附近触发的事件
{
"event": "reach_boat",
"target": "self"
}
]
}
}
},
"events":{
"start_boat":{ //添加组件组的事件
"add":{
"component_groups":["boat_finding"]
}
},
"reach_boat":{ //船到达目的地触发的事件py将监听此事件
}
}
}
}
```
在"minecraft:behavior.move_to_block"中,设置小船寻找的方块为**"minecraft:double_wooden_slab:1"**,这个方块是双层的云杉木半砖,所以我们需要对地图做一些简单的修改,将码头最外侧的一个云杉木板改为双层云杉木半砖,外观上完全一致,并且可以让小船寻找这个方块前往码头:
<img src="./images/6.gif" alt="6" style="zoom:115%;" />
玩家完成引导任务后会创建船的实体需要使用py检测玩家坐上船后触发船的组件并且监听船到达目的地的事件
```python
leveldatacomp = serverApi.GetEngineCompFactory().CreateExtraData(serverApi.GetLevelId())
timecomp = serverApi.GetEngineCompFactory().CreateTime(serverApi.GetLevelId())
class FarmServerSystem(ServerSystem):
def __init__(self, namespace, systemName):
ServerSystem.__init__(self, namespace, systemName)
# 监听EntityStartRidingEvent事件
self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(),
"EntityStartRidingEvent", self, self.Start_Gam
)
# 监听EntityDefinitionsEventServerEvent事件
self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(),
'EntityDefinitionsEventServerEvent',
self, self.EntityEvent)
# ···
def Start_Game(self, args):
# 通过事件获取玩家id和船的id
self.start_playerid = args["id"]
boatid = args["rideId"]
# 获取数据player_guide
self.guide_dialogue = leveldatacomp.GetExtraData("player_guide")
# 如果guide_dialogue的dialogue值等于5说明玩家已经完成新手引导
if self.guide_dialogue等于5["dialogue"] == 5:
# 创建触发实体事件的组件
entityeventcomp = serverApi.GetEngineCompFactory().CreateEntityEvent(boatid)
# 触发小船的"start_boat"事件
result = entityeventcomp.TriggerCustomEvent(boatid, "start_boat")
def EntityEvent(self,args):
# 获取的实体触发的事件名
eventname = args['eventName']
# 如果事件名不是"reach_boat"就返回
if eventname != "reach_boat":
return
# 获取被骑乘者(船)的id
entityid = args['entityId']
# 获取乘船玩家的id
rider_id = serverApi.GetEngineCompFactory().CreateRide(entityid).GetEntityRider()
# 执行创建数据的函数并将玩家id作为参数
self.start_game_data(rider_id)
# 创建传送玩家的接口
playertpcomp = serverApi.GetEngineCompFactory().CreatePos(self.start_playerid)
# 传送玩家到坐标位置
playertpcomp.SetPos((55, 63, 131))
# 销毁船
self.DestroyEntity(entityid)
# 重置世界时间为0
timecomp.SetTime(0)
# 新手引导结束,开始游戏触发的函数
def start_game_data(self, playerid):
# 设置初始数据玩家钱数为100
leveldatacomp.SetExtraData("player_coin", 100)
# 设置初始数据玩家家具为0
leveldatacomp.SetExtraData("player_furniture", 0)
# 将初始数据存放在event变量中并发送事件到客户端创建数据ui
event = {"playerid": playerid, "player_data_coin": leveldatacomp.GetExtraData("player_coin"),
"player_data_furniture": leveldatacomp.GetExtraData("player_furniture")}
self.NotifyToClient(self.playername, "create_data_ui", event)
```
<img src="./images/7.gif" alt="7" style="zoom:115%;" />
现在,《海滨小岛》已经有了一个完整的新手引导,玩家在乘船登上新岛屿后就可以开始正常的游戏了,当然我们也可以继续添加引导使玩家对玩法更加清晰,比如在图书馆里放置一个指引书供玩家阅览。
![8](./images/8.png)