实时对战小游戏状态同步开发实践——《答题游戏》

1
实时对战小游戏状态同步开发实践—《答题游戏》demo源码
4
腾讯产业互联网学堂热门学习路径,0基础上手
1
实时对战小游戏状态同步开发实践-课程PPT
  • 1
    关注“腾讯产业互联网学堂”公众号加群互动有好礼相送
  • 2
    向学习君回复口令 “小游戏”
  • 3
    获得课程福利包
腾讯产业互联网学堂微信公众号
“腾讯产业互联网学堂”微信公众号

讲师简介

刘亚奇

腾讯云Web前端工程师

毕业于武汉大学遥感信息工程学院,拥有扎实的前端开发基础。加入腾讯云后从事Web前端开发工作,主要负责小游戏联机对战引擎客户端SDK开发。

简介

小游戏联机对战引擎(Mini Game Online Battle Engine,MGOBE)为游戏提供房间管理、在线匹配、帧同步、状态同步等网络通信服务,帮助开发者快速搭建多人交互游戏。本次课程将介绍 MGOBE 游戏 Server 的主要接口,并以一个多人组队答题游戏为例,讲解如何使用 MGOBE 快速开发状态同步游戏。

课程概述

课程收益

1、了解MGOBE状态同步概念及应用

2、实现答题游戏开发案例

课程内容

1、 MGOBE 游戏 Server 简介

2、用状态同步构建实时对战游戏-答题游戏demo实践

玩法场景:

邀请他人一起玩

适用棋牌、回合制/策略、实时会话类的游戏。创建一个房间,将房间 ID 生成到邀请链接,发送给朋友,朋友加入一起玩,加入房间即可。游戏不同客户端的通信可以使用帧同步,也可以直接按需发送信息。例如棋牌创建一个私有房间,可以设置邀请码、牌局总数、以及其他参数等,然后邀请好友进来玩。

自由匹配一起玩

例如欢乐斗地主,可以加入一个初级、中级、高级牌局,快速匹配队友。初级、中级、高级等类型由房间类型定义,使用在线匹配,可以匹配到合适的队友。例如王者荣耀、球球大作战等。

实践案例背景

  • 状态同步游戏 - 答题游戏

答题游戏是一款使用MGOBE实时服务器实现的状态同步的组队答题类游戏。玩家通过随机匹配组成对局,然后与实时服务器进行交互,获取游戏状态(题目信息、玩家信息)。demo包含六个页面:授权页、首页、匹配页、房间页、答题页、结算页。玩家在首页通过三种匹配方式(1V1、2V2、3V3)进入房间,玩家向实时服务器发送准备指令后会进入答题页。选择答案后提交到实时服务器,由实时服务器的逻辑判断答案的正误,并且下发新的游戏状态给每个玩家。

涉及到的MGOBE接口有玩家匹配(matchPlayers)、查询指定房间信息(getRoomByRoomId)、退出房间(leaveRoom)、发送实时服务器消息(sendToGameSvr)、实时服务器广播(onRecvFromGameSvr)。

MGOBE 简介

小游戏联机对战引擎(Mini Game Online Battle Engine,MGOBE)主要为小游戏提供多人联机对战服务,帮助开发者快速搭建多人交互小游戏。依托腾讯云强大的网络、硬件资源,开发者无需关注游戏底层网络架构、网络通信、服务器扩缩容、运维,只需要通过 SDK 调用 MGOBE 后台服务,即可获得就近接入、低延迟、实时扩容的高性能联机对战服务。

目前 MGOBE 具备了房间管理、玩家匹配、房间消息、帧同步、状态同步、实时服务器等服务能力,开发者只需要在小游戏中调用 SDK 接口,就能轻松接入联机对战,让玩家在网络上互通、对战、自由畅玩。

接口概览

MGOBE 客户端 SDK 的接口可以分为五类,包括房间管理、匹配、消息发送、帧同步、广播接口。

房间管理类的接口主要是用于将不同玩家组成一个对局,这个过程中可以通过创建房间、邀请他人加入房间等方式将玩家聚合在一起。此外,还提供了如踢人、修改房间属性、查询房间信息等基本的房间管理方法。

匹配类的接口主要是用于将不同玩家通过匹配的方式组成对局,开发者可以根据需要定制匹配规则,实现根据玩家等级、积分进行匹配。

帧同步和消息发送接口可以用于玩家消息的交互,通过帧同步、状态同步方式实现玩家游戏逻辑的同步。

广播类接口主要是用于处理上述接口调用产生的广播事件,比如玩家加房、退房广播、帧消息广播等等。

客户端 SDK 使用流程

客户端在使用SDK时的主要流程有4步,可以参考官网文档

  • 导入SDK,在微信小游戏环境中可以使用 import 或者 require 语法。
// 使用 import/from
import * as MGOBE from "./js/libs/MGOBE.js";
const { Room, Listener, ErrCode, ENUM, DebuggerLog } = MGOBE;
// 使用 require
const MGOBE = require("./js/libs/MGOBE.js");
const { Room, Listener, ErrCode, ENUM, DebuggerLog } = MGOBE;
  • 初始化 Listener 对象。
const gameInfo = {
    openId: 'xxxxxx',
    gameId: "xxxxxx",// 替换为控制台上的“游戏ID”
    secretKey: 'xxxxxx',// 替换为控制台上的“密钥”
};
const config = {
    url: 'xxx.wxlagame.com',// 替换为控制台上的“域名”
    reconnectMaxTimes: 5,
    reconnectInterval: 1000,
    resendInterval: 1000,
    resendTimeout: 10000,
};
Listener.init(gameInfo, config, event => {
    if (event.code === 0) {
        // 初始化成功
        // 继续在此添加代码
        // ...
    }
});
  • 实例化 Room 对象,加入到监听。
const room = new Room();
// 监听
Listener.add(room);
  • 通过 room 实例调用方法,并处理广播回调。
// 创建房间
room.createRoom(para, callback);
// 监听加房广播
room.onJoinRoom = event => console.log("有玩家加入");

房间管理

在将各个玩家加到同一个房间形成对局的过程中,需要用到创建房间、踢人、修改房间信息等操作。以微信小戏平台**邀请玩家**为例,整个流程如下:

其中,“生成邀请链接”、“分享”都是使用微信的接口实现,“创建房间”、“加入房间”使用 MGOBE 相应接口实现。在这个过程中,房间信息可能会由于多次操作引起多次更新,比如玩家进房、退房、修改状态等。为了方便管理房间信息更新,可以使用 onUpdate 接口:

const room = new Room();
room.onUpdate = () => {
    console.log("房间信息已更新", room.roomInfo);
    // 渲染画面
    // ...
};

在处理应用重启的场景时,需要在打开应用时检查玩家是否在房间中、是否在游戏中等信息,可以通过 getRoomDetail 接口查询:

// 查询玩家自己的房间
room.initRoom();
room.getRoomDetail(event => {
    if (event.code === 0) {
        console.log("玩家已在房间内:", event.data.roomInfo.name);
        // 继续判断玩家是否在游戏中
        // ...
        return;
    }
    if (event.code === 20011) {
        console.log("玩家不在房间内");
        return;
    }
});

玩家匹配

MGOBE 为开发者提供了两种匹配方式:matchRoom 和 matchPlayers,分别表示房间匹配和玩家匹配。在两次分享课程中分别以猪猪对战答题游戏为例介绍了这两种匹配方式的用法。

  • matchRoom

房间匹配是以 maxPlayers 和 roomType 为参数,寻找 maxPlayers、roomType 属性值一致的房间,如果存在这种房间,则将玩家加入,否为为玩家创建一个新房间。适合需要快速加房的场景,用法如下:

 const playerInfo = {
        name: "Tom",
        customPlayerStatus: 1,
        customProfile: "https://xxx.com/icon.png",
    };
    const matchRoomPara = {
        playerInfo,
        maxPlayers: 5,
        roomType: "1",
    };
    room.matchRoom(matchRoomPara, event => {
        if (event.code !== 0) {
            console.log("匹配失败", event.code);
        }
    });
  • matchPlayers

玩家匹配更加灵活,开发者需要在控制台上创建匹配规则,得到匹配Code作为该接口参数。玩家触发该接口后会与其他玩家进行匹配,满足匹配规则的玩家会被匹配在一起。

  • 示例1。四人随机匹配:
{
    "version": "V1.0",
    "teams": [
        {
            "name": "4人房间",
            "maxPlayers": 4,
            "minPlayers": 4,
            "number": 1
        }
    ]
}
  • 示例2。3V3 根据玩家段位(level)进行匹配,并且玩家 level 属性值在 1 ~ 100 内的不同玩家才能匹配在一起,规则如下:
{
    "version": "V1.0",
    "teams": [
        {
            "name": "3v3",
            "maxPlayers": 3,
            "minPlayers": 3,
            "number": 2
        }
    ],
    "playerAttributes": [
        {
            "name": "level",
            "type": "number"
        }
    ],
    "rules": [
        {
            "type": "segment",
            "expression": "teams[i].players.level",
            "value": [
                [
                    1,
                    100
                ]
            ]
        }
    ]
}

客户端 SDK 调用方法:

    const playerInfo = {
        name: "Tom",
        customPlayerStatus: 1,
        customProfile: "https://xxx.com/icon.png",
        matchAttributes: [{
            name: "level",
            value: 99,
        }]
    };
    const matchPlayersPara = {
        playerInfo,
        // 匹配Code 需要从控制台配置获取
        matchCode: "match-xxx",
    };
    // 发起匹配
    room.matchPlayers(matchPlayersPara, event => {
        if (event.code === 0) {
            console.log("匹配成功", room.roomInfo);
        } else {
            console.log("匹配失败", event.code);
        }
    });

状态同步应用

状态同步类型联机游戏的特点是游戏逻辑状态在服务端计算。为了实现状态同步,MGOBE 为开发者提供了实时服务器功能,开发者可以上传代码部署到实时服务器上,并且与客户端 SDK、房间服务进行交互。

实时服务器实现了对客户端游戏逻辑的扩展。玩家进入房间之后,对房间进行的任何操作,都会通过房间服务器同步给实时服务器,那这样实时服务器上也能拿到最新的房间状态,比如玩家进房、退房、掉线、开始帧同步等等。

客户端可以通过 sendToGameSvr请求接口、onRecvFromGameSvr广播接口实现和实时服务器进行交互。

  • 客户端代码
// 发送消息给实时服务器
room.sendToGameSvr({data: { cmd: 1 }}, event => console.log(event));
// 接收实时服务器广播
room.onRecvFromGameSvr = event => {
    console.log("新自定义服务消息", event);
    // 更新游戏画面
    // ...
}
  • 实时服务器代码
// 接收客户端消息
onRecvFromClient = args => {
    // 客户端消息
    const data = args.actionData;
    // 计算游戏状态 gameData
    // ...
    // 发送游戏状态给客户端
    args.SDK.sendData({ playerIdList: [], data: { gameData } });
    args.SDK.exitAction();
};

通过这种方式,开发者可以把玩家的游戏输入全部发送给实时服务器,然后由实时服务器计算游戏状态,并且广播给每个客户端,实现游戏状态同步。

常见问题

Q:createRoom、matchRoom、matchPlayers接口主要区别是什么?

A:createRoom 创建房间并且加入到该房间。matchRoom 根据参数匹配到一样的房间,并且进入。如果没有合适的房间,按照该参数创建新房间。matchPlayers 需要在控制台上配置匹配规则,拿到匹配code,以此为参数进行匹配。匹配成功后进入房间。

Q:创建房间后需要调用joinRoom吗?

A:不需要,调用 createRoom 后玩家会自动进入房间。不需要,匹配成功玩家会自动进入房间。开发者可能开通了实时服务器,但是没有正常运行,比如没有发布代码。新版本即将支持 H5原生环境,可以直接在浏览器中运行。检查 room 实例是否加入到 Listener。

Q:匹配成功后需要创建房间吗?

A:创建房间或匹配的时候出现40010、40011错误

Q:如何在浏览器中进行调试?

A:SDK 没有收到广播

结语

MGOBE 能为开发者快速实现游戏房间管理、在线匹配、联网对战等功能,大家可以到腾讯云官网产品页中搜索“MGOBE”进一步了解。也欢迎大家扫码加入开发者群交流。

全部评论
讲师/助教

评论

直播日历