本帖最后由 空伊伊 于 2023-11-8 16:52 编辑
事件通信的应用场景
目录
1.什么是事件通信?
2.本地通信的应用
案例1:脚本A通知脚本B执行逻辑
案例2:UI脚本通知脚本A执行逻辑
3.客户端和服务端通信的应用
案例1:客户端通知服务端存储数据
案例2:客户端向服务端请求数据
案例3:服务端向房间内所有客户端进行广播
4.使用事件通信的注意事项
1.什么是事件通信?
在口袋方舟中,如果你正确使用下列API进行逻辑处理,就是使用事件通信。
- 监听事件
- Event.addLocalListener 本地监听(监听本地发送来的事件)
- Event.addClientListener 客户端监听(监听客户端发送来的事件)
- Event.addServerListener 服务端监听(监听服务端发送来的事件)
- 派发事件
- Events.dispatchToLocal 向本地发送事件
- Events.dispatchToServer 向服务端发送事件
- Events.dispatchToClient 向指定客户端发送事件
- Events.dispatchToAllClient 向所有客户端发送事件
下方的视频展示了本节课的内容:(注:视频是旧版本录制的,视频中出现的代码是旧的,最新代码以文档为准)
<video controls src="https://forum.ark.online/forum.php?mod=attachment&aid=MjE4OXw3MWVkZjI4NnwxNjk2OTI0NjIxfDExM3wxNTcx&noupdate=yes"></video>
2.本地通信的应用
当脚本A和脚本B在同一个客户端或服务端中运行时,它们之间需要进行交互。这时候,你可以使用本地通信来实现它们之间的数据传输和协作。
案例1:脚本A通知脚本B执行逻辑
这个案例很常用,脚本之间互相调用、互相传值都可以通过这个方式来进行
脚本B监听本地事件 MyEvent
@Component
export default class ScriptB extends Script {
protected onStart(): void {
// 监听本地事件"MyEvent"
Event.addLocalListener("MyEvent", (value: string) => {
// 收到事件时,把收到的值传给sayHellow并执行
this.sayHellow(value)
})
}
public sayHellow(otherName: string) {
console.log("Hello" + otherName + "I am ScriptB")
}
}
脚本A派发本地事件 MyEvent
@Component
export default class ScriptA extends Script {
protected onStart(): void {
// 延迟5秒(原因是,需要等事件接收方准备好再派发事件,才能保证事件发送成功)
setTimeout(() => {
// 派发"MyEvent"事件,参数为"ScriptA"
Event.dispatchToLocal("MyEvent", "ScriptA")
}, 5000);
}
}
案例2:UI脚本通知脚本A执行逻辑
游戏开发过程中,经常出现这样的需求:点击按钮,然后某个脚本执行对应的逻辑,我们可以像下面这样做
在 GameStart 里监听事件 MyEvent2
@Component
export default class GameStart extends Script {
protected onStart(): void {
Event.addLocalListener("MyEvent2", () => {
console.log("按钮被点击了")
})
}
}
在 DefaultUI 中 JumpBtn 的点击事件中派发事件 MyEvent2
//点击跳跃按钮,异步获取人物后执行跳跃
jumpBtn.onPressed.add(()=>{
if (this.character) {
this.character.jump();
} else {
Player.asyncGetLocalPlayer().then((player) => {
this.character = player.character;
//角色执行跳跃功能
this.character.jump();
});
}
// 派发事件“MyEvent2”
Event.dispatchToLocal("MyEvent2")
})
3.客户端和服务端通信的应用
由于客户端和服务端之间不能直接调用,所以需要使用相互抛事件的方式来进行通信
案例1:客户端通知服务端存储数据
这个例子在数据存储中很常见,因为需要持久化存储的数据只能在服务端进行存储,所以客户端想要存储数据,就需要先将数据发送到服务端,然后服务端再把数据进行存储
服务端脚本通过监听SendData事件来接收客户端发送来的数据并进行存储
@Component
export default class ServerScript extends Script {
protected onStart(): void {
// 在服务端设置存储环境
DataStorage.setTemporaryStorage(SystemUtil.isPIE)
// 监听事件SendData,作用是将player发送来的数据data存储为玩家数据
Event.addClientListener("SendData", (player: Player, data) => {
DataStorage.asyncSetData("key_" + player.playerId, data)
})
}
}
客户端脚本在启动5秒后,将数据233666发送给服务端进行存储
@Component
export default class ClientScript extends Script {
protected onStart(): void {
// 延迟5秒
setTimeout(() => {
// 将233666这个数据通过SendData事件发送给服务端
Event.dispatchToServer("SendData", 233666)
}, 5000);
}
}
案例2:客户端向服务端请求数据
接着上一点,我们需要存储数据,当然也需要获取数据。因为需要持久化存储的数据只能存放在服务端,所以客户端想要使用数据,就需要先通知服务端,然后服务端再把数据发送给客户端才行
服务端脚本通过监听ReqData事件来获取对应客户端的数据并发送给对应客户端
@Component
export default class ServerScript extends Script {
protected onStart(): void {
// 在服务端设置存储环境
DataStorage.setTemporaryStorage(SystemUtil.isPIE)
// 监听事件ReqData,作用是获取player的玩家数据,并发送给player
Event.addClientListener("ReqData", async (player: Player) => {
// 获取player的数据
let result = await DataStorage.asyncGetData("key_" + player.playerId)
// 如果数据存在
if (result.data) {
// 将数据data通过GetData事件发送给客户端player
Event.dispatchToClient(player, "GetData", esult.data)
}
})
}
}
客户端脚本在启动5秒后向服务端请求数据,并将请求到的数据进行打印
@Component
export default class ClientScript extends Script {
protected onStart(): void {
// 客户端启动5秒后
setTimeout(() => {
// 向服务端发送事件ReqData,以请求数据
Event.dispatchToServer("ReqData")
}, 5000);
// 监听服务端事件GetData,作用是接收服务端发送过来的数据
Event.addServerListener("GetData", (data) => {
// 打印数据
console.log(data)
})
}
}
案例3:服务端向房间内所有客户端进行广播
服务端脚本每隔3秒向房间内的所有客户端发送BroadCast事件,并传递一个0~100的随机数
@Component
export default class ServerScript extends Script {
protected onStart(): void {
// 每隔3秒
setInterval(() => {
// 向所有客户端发送BroadCast事件,同时传递一个0~100的随机数
Event.dispatchToAllClient("BroadCast", Math.random() * 100)
}, 3000)
}
}
客户端监听BroadCast事件,并将接收到的值进行打印
@Component
export default class ClientScript extends Script {
protected onStart(): void {
Event.addServerListener("BroadCast", (value: string) => {
console.log("服务端传来的随机数:" + value)
})
}
}
4.使用事件通信的注意事项