找回密码
 立即注册
查看: 340|回复: 2

【游戏开发随笔】使用联机对战引擎实现1v1联机对战(上 ...

[复制链接]
发表于 2022-1-4 07:48 | 显示全部楼层 |阅读模式
腾讯云提供了游戏联机对战引擎服务(以下简称对战引擎MGOBE),为小游戏提供房间管理、玩家匹配、游戏同步功能,借助它可以快速实现多人游戏功能(如回合制的棋牌类、实时画面的你画我猜等)。MGOBE能够帮开发者省去繁琐的服务器、网络通信细节,开发者只需注重游戏逻辑的实现。
目前网上的相关实战教程较少,腾讯云官方文档虽然提供了详实的接口细节,但文档的组织方式不利于新上手的开发者快速理解使用MGOBE。本文使用对战引擎实现了最简单的1v1随机匹配机制,通过案例实战,能够帮助开发者更好地理解其实现原理并应用于自己的游戏中。
由于内容较多,本教程分为上下两篇。上篇(本文)实现了基本1v1联机匹配和消息通信;下篇则将基于该机制完成联机游戏的逻辑设计。
开始操作之前,您需要有一个已经创建好的游戏项目(本文采用的开发工具是Cocos Creator,其他游戏引擎或微信原生开发工具也适用),并且已开启对战引擎服务(本文是在Cocos Creator内的第三方服务面板一键开启[1])。
联机匹配架构概览



基于对战引擎的联机匹配机制如上图。在整个流程中,开发者需要做的主要包括两方面:为服务器设置匹配规则(即开房条件),和向服务器发起匹配
<hr/>配置匹配规则

此部分更多细节请参考对战引擎规则集配置页面[2]。
1. 登录腾讯云MGOBE控制台,选择左侧菜单【匹配管理】>【匹配规则集】,单击【新建规则集】。
2. 填写规则集名称,选定一个类型的匹配规则,将自动生成一个JSON模板。


在这里可以看到联机对战引擎支持1v1和多v多、对称匹配和非对称匹配的多种类型,这里我们只需实现1v1即可。
对战引擎还提供了自定义匹配分段和误差大小的能力,例如500分的玩家和100分的玩家水平不一致,不应该匹配。此规则可以在playerAttributes和rules字段进行定义。本案例中不需要这样的匹配规则,所以这两项空缺即可。
规则集中的timeout字段规定了匹配超时失败的时长,这里我设为60(单位为秒)。当发生超时后,游戏可以退出匹配页面,由玩家决定是否再次搜索对手;当然,对战引擎也提供了机器人填充!我们可以在下一步中设置是否启用机器人填充,关于机器人的更多内容可以参考文档[3]。
注意,MGOBE 仅会在匹配中指定机器人的席位和属性,机器人行为逻辑需要开发者在实时服务器或客户端自行实现。此内容会在下一篇展开讨论。
关于规则集设计的参数详解请参考文档的规则脚本设计页面[4]和规则脚本示例[5]。
3. 规则集内容设置完成后,单击【验证规则集】,验证成功后,出现提示“规则集验证通过”。
4. 最后单击【提交规则集】,新建规则集完成。
创建匹配配置

此部分更多细节请参考匹配配置页面[6]。
1. 选择左侧菜单【匹配管理】>【在线匹配】。进入在线匹配页面,单击【新建匹配】。填写匹配名称,选择匹配规则集和是否开启机器人。
2. 选择规则集后,可“预览”相应的规则脚本配置。
3. 单击【确定】。新建匹配后,在【在线匹配】页面,就会生成相应的匹配 code。该code之后需要填入到代码中。


实现在线匹配

完成匹配规则设计和配置后,就可以实现两个客户端程序进行匹配了。本部分代码整理改编自文档[7]。
在游戏脚本中合适位置插入以下代码,作用是初始化对战引擎启动网络监听
// 1.游戏配置
const gameInfo = {
  gameId: 'obg-sample', // 从游戏联机对战引擎后台获取的 游戏ID
  secretKey: 'secretKeySample',  // 从游戏联机对战引擎后台获取的 游戏key
  openId: "openid_test" + Math.floor(Math.random()*100).toString(), // 玩家 ID,可自定义
};
const config = {
  url: 'sample.wxlagame.com',   // 从游戏联机对战引擎后台获取的 域名
  reconnectMaxTimes: 5,
  reconnectInterval: 1000,
  resendInterval: 1000,
  resendTimeout: 10000,
};

// 2.定义房间匹配参数
const playerInfo = {
  name: "Tom",    // 自定义昵称
  customPlayerStatus: 1,  // 自定义玩家状态
  // matchAttributes: []  // 我们的匹配规则未使用playerAttributes,不需要传此项
};
// 匹配时需要的参数
this.matchPlayersPara = {
  playerInfo,
  matchCode: "match-sample" // 上一步完成匹配配置后,得到的匹配 code
}
// 取消匹配需要的参数
this.cancelMatchPara = {
  matchType: MGOBE.ENUM.MatchType.PLAYER_COMPLEX,
}

// 实例化 Room 对象(Cocos Creator内调用方法为MGOBE.Room(),微信原生工具直接Room()即可)
this.room = new MGOBE.Room();

// 初始化Listener,并给房间添加监听
var self = this;
MGOBE.Listener.init(gameInfo, config, event => {
  if (event.code === 0) {
    console.log("MGOBE初始化成功。");
    // 初始化成功之后才能调用其他 API(如添加各类监听)
    MGOBE.Listener.add(self.room);
    // #6. 客户端-服务器通信# 部分要插入的代码位置
  } else {
    console.log("MGOBE初始化失败。");
  }
});
然后,我们可以为一个“开始匹配”按钮绑定点击事件,使之被点击后触发开始匹配的函数:
startMatch () {
  console.log("开始匹配");
  var self = this;
  this.room.matchPlayers(this.matchPlayersPara, event => {
    if (event.code === 0) {
      console.log("匹配成功", self.room.roomInfo);
      // #6. 客户端-服务器通信# 部分要插入的代码位置
      // Cocos Creator可选:前往自定义的battle场景
      // cc.director.loadScene("battle");
    } else {
      console.log("匹配失败", event.code);
    }
  });
},
在等待匹配时,还可以添加一个“取消匹配”的按钮,用于玩家突然想取消匹配的情况:
cancelMatch () {
  console.log("取消匹配");
  this.room.cancelPlayerMatch(this.cancelMatchPara, event => {
    console.log(event);
  });
},
开始调试:打开两个模拟窗口,两边相继点击“匹配按钮”,等待一段时间就可以看到两边的控制台都打印“匹配成功”的消息了!一同打印的还有room.roomInfo,即匹配的房间对象信息,展开可以查阅房间id、玩家信息、房主等信息。


创建实时服务器  

以上仅仅实现了两个玩家进行匹配、进入同一房间的场景,这一功能由MGOBE系统代为完成。但是匹配成功后,在玩家之间一定是需要同步游戏数据,甚至互相发送文字消息的。这些功能需要我们的小游戏有一个专门的服务端逻辑,即实时服务器,从而可以自定义如何响应玩家的动作、如何转发玩家的消息。
关于帧同步状态同步两种游戏数据同步方式,将在下一篇中讲解。
实时服务器的最简要求和示例代码在状态同步页面[8]已给出。创建实时服务器以及更加强大的模板代码可以通过以下两种方式之一完成:
1. 使用Cocos在MGOBE面板直接启用[1](此为后文采用的服务器代码模板);
2. 或者在腾讯云后台自行开启[9],其中也给出了具有齐全的事件监听的代码模板。
客户端-服务器通信  

编写客户端代码。在startMatch()的指定位置添加以下代码,使其在成功匹配后向服务器发送消息。
// 要发送给服务器的自定义数据(例如,cmd为1可表示玩家要向右移动1格)
const sendToGameServerPara = {
  data: {
    cmd: 1,
  },
};
// 向服务器发送消息
self.room.sendToGameSvr(sendToGameServerPara, event => console.log(event));
服务端中的onRecFromClient()是接收并处理来自客户端的消息的函数,我们对其作下列修改,使其向所有房内玩家广播一条消息,告知收到一条来自某玩家的消息:
const gameServer = {
  // 消息模式
  mode: 'sync',
  // 初始化游戏数据
  onInitGameData: function () {
    return {};
  },
  // 监听客户端数据(重点)
  onRecvFromClient: function onRecvFromClient({ sender, actionData, gameData, SDK, room, exports }) {
    // 接收到的参数为 ActionArgs 类型,详见 https://cloud.tencent.com/document/product/1038/34992
    // 自定义回信内容
    const response = {
      msg: "已收到玩家"+sender+"发送的消息",  // sender 是发信者id
      data: actionData,   // actionData是发信内容,即上一代码块中的sendToGameServerPara.data
      timestamp: new Date().toISOString()
    }
    // 发送消息给客户端(playerIdList为空表示广播给所有房内玩家)
    SDK.sendData({ playerIdList: [], data: response }, { timeout: 2000, maxTry: 3 });
    // 显式结束 onRecvFromClient 方法
    SDK.exitAction();
  },
  // 其他监听函数,如onJoinRoom,onLeaveRoom
  // ...
}
最后,当服务端把回复消息发往客户端时,客户端也需要有一个接收消息的监听函数才能收到。在客户端初始化Listener部分的代码中的指定位置添加这个监听函数:
// 服务器消息回调
self.room.onRecvFromGameSvr = event => console.log("新自定义服务消息", event);
这样一来,消息在客户端和服务器之间便可以双向传递了。再次启动两个窗口查看运行效果。
双方点击匹配按钮后,等待匹配完成。此时每个客户端的console中应该会收到至少三条消息:一条是消息发送成功的回调消息对象,表示发送的消息成功送达服务器;其余两条一样的,则是服务器分别收到两个客户端消息后广播的回复。
注意,由于服务器收到两个客户端各一条消息,所以共广播了两遍。若服务器需要指定回复的玩家,只需在SDK.sendData()的参数playerIdList列表中给出指定的id(即sender)即可。


服务器所有监听函数的参数都是一个ActionArgs结构,我们可以从中读取所需的数据(如sender,actionData,SDK)。ActionArgs会在第二篇中更详细地讲解,您也可以查阅官方文档中的GameServer对象[10]和 ActionArgs 类型[11]。
凭借以上已讲解的内容,我们已经可以实现“房间消息”的功能了!例如,玩家A向服务器发送一条消息”hello”,服务器收到后向另一个玩家B转发该消息,玩家B的客户端程序收到服务器的消息后再将文本显示在屏幕上。
<hr/>至此,我们已经成功搭建了一个房间,并实现了1v1匹配的基本环境,还实现了两个客户端在房间内的消息通信。在下一篇中,我们将基于已实现的匹配房间和消息通信框架,正式实现状态同步框架下的游戏逻辑
欢迎关注我的微信公众号“焕焕骑士”,分享我的游戏资讯,以及有用的开发经验!
参考


  • ^ab游戏联机对战引擎(腾讯云)快速入门https://service.cocos.com/document/zh/mgobe.html
  • ^规则集配置https://cloud.tencent.com/document/product/1038/47280
  • ^匹配机制说明https://cloud.tencent.com/document/product/1038/47281
  • ^规则脚本设计https://cloud.tencent.com/document/product/1038/34952
  • ^规则脚本示例https://cloud.tencent.com/document/product/1038/34953
  • ^匹配配置https://cloud.tencent.com/document/product/1038/34949
  • ^在线匹配https://cloud.tencent.com/document/product/1038/37754
  • ^状态同步https://cloud.tencent.com/document/product/1038/37758
  • ^实时服务器https://cloud.tencent.com/document/product/1038/34950
  • ^GameServer.IGameServer 对象https://cloud.tencent.com/document/product/1038/34991
  • ^ActionArgs 类型https://cloud.tencent.com/document/product/1038/34992

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2022-1-4 07:53 | 显示全部楼层
老哥,下篇什么时候抽空写一下哈
发表于 2022-1-4 07:54 | 显示全部楼层
安排!
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2025-5-14 18:36 , Processed in 0.138887 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表