聊天功能是多人在线游戏最常见也是最基础的功能. Colyseus 内置了许多方便的工具用来实现多人在线游戏的信息互递.
而 Cocos Creator 作为游戏客户端可以方便地集成 Colyseus 提供的功能. 下面通过实现一个聊天室来展示 Colyseus 的迷人之处.
客户端 (Cocos Creator 3)
启动 Cocos Creator, 新建一个名为 "CocosColyseusChat" 的 2D 项目. 然后参考这篇文章开启 Colyseus 插件.
客户端由两个场景构成并且包含三个脚本.
场景
-
login 场景
(点击打开大图)登录场景非常简单, 提示用户输入网名, 点击登录按钮. 场景脚本 loginScript 控制客户端节点 ClientNode 连接登入聊天服务器.
需要注意的是 ClientNode 作为 Colyseus 客户端节点, 包含客户端控制脚本, 而且是各个场景公用的, 所以一开始就要将它列为持久节点.if (this.clientNode && !game.isPersistRootNode(this.clientNode)) game.addPersistRootNode(this.clientNode);
-
room 场景
(点击打开大图)
聊天室场景分为大厅公屏和用户输入两个部分. 用户输入的信息通过 Colyseus 客户端发送至服务器然后广播给聊天室里的所有客户端 (包括自己), 并输出在公屏上.
脚本
- clientScript
ClientNode空节点上的脚本, 代表 Colyseus 客户端, 负责登录服务器, 发送和接收聊天消息.
async connect (userName:string="") {
this.client = new Colyseus.Client(`${this.useSSL ? "wss" : "ws"}://${this.hostname}${([443, 80].includes(this.port) || this.useSSL) ? "" : `:${this.port}`}`);
try {
this.room = await this.client.joinOrCreate("lobby", {userName:userName});
this.room.onMessage("messages", (message) => {
this.node.emit("messages", message);
});
} catch (e) {
console.error(e);
}
}
send (message:string="")
{
this.room.send("message", message);
}
关于 Colyseus 客户端的使用请参考官方文档.
- loginScript
登录场景使用的脚本. 确保用户输入网名之后才可以登录.
if (this.nameBox.string.length>0 && !this.okButton.interactable)
this.okButton.interactable = true;
else if (this.nameBox.string.length == 0 && this.okButton.interactable)
this.okButton.interactable = false;
- roomScript
聊天室场景使用的脚本, 负责聊天消息的接收和发送.
this.clientNode.on("messages", (message)=>{
this.lobbyBox.string+=message+"\n";
});
if (this.sendButton.interactable && this.messageBox.string.length>0)
{
this.sendButton.interactable = false;
this.clientNode.getComponent<ClientScript>(ClientScript).send(this.messageBox.string);
this.messageBox.string = "";
}
服务端 (Colyseus)
Colyseus 内置了 LobbyRoom
这个大厅聊天室脚本, 是不是很贴心?
我们可以直接继承这个大厅脚本, 然后扩展它的功能. 比如, 把用户名存在客户端的 userData
里.
import {Client, LobbyRoom, Room} from "colyseus";
export class CocosLobbyRoom extends LobbyRoom {
// this room supports only 4 clients connected
maxClients = 4;
// @ts-ignore
onCreate (options: any): Promise<void> {
console.log("ChatRoom created!", options);
this.onMessage("message", (client, message) => {
console.log("ChatRoom received message from", client.sessionId, ":", message);
this.broadcast("messages", `(${client.userData}): ${message}`);
});
}
onJoin (client: Client, options: any) {
client.userData = options.userName;
this.broadcast("messages", `${ client.userData } joined.`);
}
onLeave (client: Client) {
this.broadcast("messages", `${ client.userData } left.`);
}
onDispose () {
console.log("Dispose ChatRoom");
}
}
到这里我们的聊天室就全部完成了, 当然商用时还需加入错误检查, 单词过滤等等功能, 这里为了简介起见就都省略了. 有兴趣可以自己尝试实现更多功能.
我们可以看到, 使用 Colyseus, 条理清晰, 逻辑明确, 短短几行代码就实现了从客户端到服务器的开发工作. 方便, 稳定, 扩展容易是 Colyseus 的特色.