多人在线对战开发指南 · JavaScript
前言
多人在线对战是一款基于 JavaScript 编写的游戏 SDK,它为有强联网需求的网络游戏提供了一整套的客户端 SDK 解决方案,因此开发团队不再需要自建服务端,从而节省大部分开发和运维成本。多人在线对战提供的主要功能如下:
- 获取房间列表
- 创建房间
- 加入房间
- 随机加入(符合条件的)房间
- 获取房间玩家
- 获取、设置、同步房间的属性
- 获取、设置、同步玩家的属性
- 发送和接收「自定义事件」
- 离开房间
SDK 导入
请阅读 安装指南,获取 JS 库文件。
初始化
首先,需要引入 SDK 中常用的类型和常量。
const {
// SDK
Client,
// Play SDK 事件常量
Event,
// 事件接收组
ReceiverGroup,
// 创建房间标志
CreateRoomFlag,
} = Play;
注意:Cocos Creator 在构建「微信小游戏」项目时,无法将 Play
正常加载到全局变量中,因此需要先导入 Play
模块。
const Play = require("./play");
接着我们需要实例化一个在线对战 SDK 的客户端对象。
const client = new Client({
appId: 'your-client-id', // 游戏的 Client ID
appKey: 'your-client-token', // 游戏的 Client Token
playServer: 'https://your_server_url', // 游戏的 API 域名
userId: 'tarara', // 设置用户 id
gameVersion: '0.0.1' // 设置游戏版本号,选填,默认 0.0.1,不同版本的玩家不会匹配到同一个房间
});
- 在 开发者中心 > 你的游戏 > 游戏服务 > 应用配置 可以查看游戏的
Client ID
和Client Token
。 - API 域名在 应用配置 > 域名配置 > API 处查看,参考文档关于域名的说明。
其中,
userId
作为客户端的唯一标识连接至服务器。
需要注意,这个 userId
有如下限制:
- 只允许英文、数字与下划线
- 长度不能超过 32 个字符
- 一个应用内全局唯一
gameVersion
表示客户端的版本号,如果允许多个版本的游戏共存,则可以根据这个版本号路由到不同的游戏服务器。
连接
建立连接
通过下面的代码将当前玩家连接到多人对战服务:
client
.connect()
.then(() => {
// 连接成功
})
.catch((error) => {
// 连接失败
console.error(error.code, error.detail);
});
大厅
我们推荐您**「不要」将玩家加入大厅**,因为在大厅中,服务端会不停地下发最新的全量房间列表,由玩家自行选择其中一个房间进行游戏,这种方式不仅对玩家体验不友好,同时来会带来很大的带宽压力。 我们推荐您像现在的绝大部分手游一样,直接通过房间匹配的方式,快速匹配开始游戏。
如果您有特殊的游戏场景需要获取房间列表,可以调用以下方法:
client
.joinLobby()
.then(() => {
// 加入大厅成功
})
.catch((error) => {
// 加入大厅失败
console.error(error.code, error.detail);
});
当玩家加入到大厅后,服务端会将当前大厅的房间列表推送给客户端,开发者可以根据需求显示房间列表,或加入房间参与游戏。
client.on(Event.LOBBY_ROOM_LIST_UPDATED, () => {
const roomList = client.lobbyRoomList;
// TODO 可以做房间列表展示的逻辑
});
更多关于 LobbyRoom
,请参考 API 文档。
相关事件
事件 | 参数 | 描述 |
---|---|---|
LOBBY_ROOM_LIST_UPDATED | 无 | 大厅房间列表更新 |
房间匹配
房间,是指产生玩家「战斗交互」的单位。比如斗地主的牌桌、MMO 的副本、微信游戏的对战等,广义上都属于房间的范畴。 玩家之间的战斗交互都是在房间内完成的。所以,玩家「如何进入房间」就成了房间匹配的关键。下面我们将从「创建房间」和「加入房间」两方面来分析一下常用的「房间匹配」功能。
创建房间
我们可以这样简单地创建一个房间。创建房间的玩家为房主(MasterClient),房主在创建房间成功的同时也意味着成功加入了该房间。
client
.createRoom()
.then(() => {
// 创建房间成功也意味着自己已经成功加入了该房间
})
.catch((error) => {
// 创建房间失败
console.error(error.code, error.detail);
});
我们也可以创建一个设定相关信息的房间。
// 房间的自定义属性
const props = {
title: "room title",
level: 2,
};
const options = {
// 房间不可见
visible: false,
// 房间空后保留的时间,单位:秒
emptyRoomTtl: 300,
// 允许的最大玩家数量
maxPlayerCount: 2,
// 玩家离线后,保留玩家数据的时间,单位:秒
playerTtl: 300,
customRoomProperties: props,
// 用于做房间匹配的自定义属性键,即房间匹配条件为 level = 2
customRoomPropertyKeysForLobby: ["level"],
// 给 MasterClient 设置权限
flag:
CreateRoomFlag.MasterSetMaster | CreateRoomFlag.MasterUpdateRoomProperties,
};
const expectedUserIds = ["world"];
client
.createRoom({
roomName,
roomOptions: options,
expectedUserIds: expectedUserIds,
})
.then(() => {
// 创建房间成功也意味着自己已经成功加入了该房间
})
.catch((error) => {
console.error(error.code, error.detail);
});
其中 roomName
、roomOptions
和 expectedUserIds
这些参数都是可选参数。
roomName
房间名称必须保证唯一;如果不设置,则由服务端生成唯一房间 Id 并返回。
roomOptions
创建房间时的指定参数,包括:
opened
:房间是否开放。如果设置为 false,则不允许其他玩家加入。visible
:房间是否可见。如果设置为 false,则不会出现在大厅的房间列表中,但是 其他玩家可以通过指定「房间名称」加入房间。emptyRoomTtl
:当房间中没有玩家时,房间保留的时间(单位:秒)。默认为 0,即 房间中没有玩家时,立即销毁房间数据。最大值为 300,即 5 分钟。playerTtl
:当玩家掉线时,保留玩家在房间内的数据的时间(单位:秒)。默认为 0,即 玩家掉线后,立即销毁玩家数据。最大值为 300,即 5 分钟。maxPlayerCount
:房间允许的最大玩家数量。customRoomProperties
:房间的自定义属性。customRoomPropertyKeysForLobby
:房间的自定义属性customRoomProperties
中「键」的数组,包含在customRoomPropertyKeysForLobby
中的属性将会出现在大厅的房间属性中(client.lobbyRoomList
),而全部属性要在加入房间后的room.customProperties
中查看。这些属性将会在匹配房间时用到。flag
:创建房间标志位,详情请看下文中 MasterClient 掉线不转移,指定其他成员为 MasterClient,只允许 MasterClient 修改房间属性。
expectedUserIds
指定的玩家 ID 数组。这个参数主要用于为某些能加入到房间中的特定玩家「占位」。
注意:这些「特定的玩家」并不会真地加入到房间里来,而只会在房间的「空位」上预留出位置,只允许「特定的玩家」加入。如果开发者要做「邀请加入」的功能,还需要通过其他途径,例如 IM、微信分享等将「房间名称」发送给好友,好友再通过 joinRoom(roomName)
接口加入房间。
更多关于 createRoom
,请参考 API 文档。
加入房间
当房间创建好后,其他的玩家可以通过「加入房间」参与到游戏中。
加入指定房间
通过指定「房间名称」加入房间。
// 玩家在加入 'LiLeiRoom' 房间
client
.joinRoom("LiLeiRoom")
.then(() => {
// 加入房间成功
})
.catch((error) => {
// 加入房间失败
console.error(error.code, error.detail);
});
在加入房间时,也可以为其他玩家占位,如果房间剩余空位小于占位数量,会加入房间失败。
const expectedUserIds = ["LiLei", "Jim"];
// 玩家在加入 'game' 房间,并为 hello 和 world 玩家占位
client
.joinRoom("game", {
expectedUserIds,
})
.then(() => {
// 加入房间成功
})
.catch((error) => {
// 加入房间失败
console.error(error.code, error.detail);
});
更多关于 joinRoom