跳到主要内容
版本:v4

快速接入

功能概述

  • 多人联机提供了一套稳定、易接入的多人实时对战能力,覆盖房间管理玩家管理实时消息通信等核心功能,适用于休闲对战、竞技对战及强一致性实时游戏等场景。
  • 更详细的功能介绍请参考多人联机功能介绍

集成步骤

  • 本文档以 C++ 为例演示多人联机功能集成步骤,其他语言可参考相应的 DLL 调用方式。
  • 在集成多人联机之前,请先阅读快速开始了解基本的集成流程,并完成 SDK 初始化与启动校验。
详细接口文档

本文仅介绍集成流程,接口的详细说明和枚举、结构体定义等,请阅读多人联机 API 参考

流程简介

多人联机主要流程如下图,开发者可根据该流程图把握各接口的调用时机:

  1. 游戏启动:完成 C++ SDK 初始化与启动校验
  2. 游戏大厅:和多人联机服务端建立连接,连接成功后再进行房间相关操作
  3. 进入房间:通过创建房间匹配房间拉取房间列表后加入任一方式进入房间
  4. 房间内:更新玩家自定义状态/属性房间属性踢人;使用自定义消息做状态同步游戏,或使用帧同步做实时要求高的格斗、MOBA 游戏
  5. 结束:离开房间、断开连接

多人联机流�程示意

建立连接

进入大厅后,需要先与多人联机服务建立长连接,之后才能发起创建房间、匹配房间、加入房间等请求。

注册回调并每帧驱动

多人联机的异步请求结果和服务端主动通知均通过同一回调处理。建议在游戏主循环中每帧调用TapOnlineGame_RunCallbacks(),并在回调里根据event_id分发到不同逻辑。

#include "taptap_onlinegame.h" // 包含多人联机头文件

static int64_t gRequestID = 0;

void HandleOnlineGameEvent(const TapOnlineGameEvent* event) {
// 注意:event 及其引用内存会在回调返回后被 SDK 释放,如需长期使用请自行复制
switch (event->event_id) {
case TapOnlineGameEventID_ConnectResponse: {
if (event->error) {
// 请求失败,可根据 event->error->code 处理
return;
}

auto* resp = static_cast<const TapOnlineGameConnectResponse*>(event->event_data);
if (resp) {
// 建连成功,resp->player_id 为当前玩家 ID,此后可发起创建/匹配/加入房间
}
break;
}
case TapOnlineGameEventID_CreateRoomResponse:
// 创建房间结果,event_data 为 TapOnlineGameCreateRoomResponse*
break;
case TapOnlineGameEventID_MatchRoomResponse:
// 匹配房间结果,event_data 为 TapOnlineGameMatchRoomResponse*
break;
case TapOnlineGameEventID_JoinRoomResponse:
// 加入房间结果,event_data 为 TapOnlineGameJoinRoomResponse*
break;
case TapOnlineGameEventID_EnterRoomNotification:
// 有玩家进入房间,event_data 为 TapOnlineGamePlayerEnterRoomNotification*
break;
case TapOnlineGameEventID_LeaveRoomNotification:
// 有玩家离开房间,event_data 为 TapOnlineGamePlayerLeaveRoomNotification*
break;
case TapOnlineGameEventID_CustomMessageNotification:
// 收到自定义消息,event_data 为 TapOnlineGameCustomMessageNotification*
break;
case TapOnlineGameEventID_FrameSyncStartNotification:
// 帧同步开始,event_data 为 TapOnlineGameFrameSyncStartNotification*(含 seed)
break;
case TapOnlineGameEventID_FrameNotification:
// 收到帧同步数据,event_data 为 TapOnlineGameFrame*
break;
case TapOnlineGameEventID_FrameSyncStopNotification:
// 帧同步结束
break;
case TapOnlineGameEventID_DisconnectNotification:
// 被踢或异常断线,可根据 event->error 决定是否重连(被踢建议不重连)
break;
// 其他事件见 API 参考
default:
break;
}
}

int main() {
// 假设已完成 TapSDK_Init 初始化

// 1. 发起建连
TapSDK_Result ret = TapOnlineGame_AsyncConnect(TapOnlineGame(), ++gRequestID);
if (ret != TapSDK_Result_OK) {
// 发起失败,不会触发回调
return -1;
}

// 2. 主循环中每帧处理多人联机事件
bool running = true;
while (running) {
uint32_t left = 0;
auto handledEvents = TapOnlineGame_RunCallbacks( // 返回本次调用处理了的事件个数
TapOnlineGame(),
HandleOnlineGameEvent, // 用于处理事件的回调函数
10, // 本次调用最多处理的事件个数,传 0 则处理所有待处理事件。一般传 10 即可。
&left // 返回队列中未处理的事件个数,可根据该值决定是否需要循环调用 TapOnlineGame_RunCallbacks()
);

TapSDK_RunCallbacks();

// 游戏逻辑...

Sleep(33);
}

TapSDK_Shutdown();
return 0;
}

断开连接

用户离开大厅,或不再使用多人联机时,可调用TapOnlineGame_AsyncDisconnect()和服务端断开连接。断连后,再次TapOnlineGame_AsyncConnect()成功前,无法发起创建/匹配/加入房间等请求。

TapOnlineGame_AsyncDisconnect(TapOnlineGame(), ++gRequestID);

进入房间

房间概述

  • 房间:玩家联机的虚拟空间,每个房间有唯一的房间 ID。
  • 房主:创建房间的玩家,拥有踢人、修改房间属性等权限;房主离开后,服务端会自动选择房间内一个玩家为新房主。
  • 监听回调:玩家进入或离开房间时,SDK 通过TapOnlineGameEventID_EnterRoomNotificationTapOnlineGameEventID_LeaveRoomNotification事件通知其他玩家。

进入方式

进入房间有三种方式:创建房间匹配房间拉取房间列表后加入

房间流程

创建房间

创建房间成功后,自动成为房主。

TapOnlineGameCreateRoomRequest req = {};
req.room_cfg.max_player_count = 4;
req.room_cfg.room_type = "ranked";
req.room_cfg.name = "MyRoom";
req.room_cfg.custom_properties = "{}";
req.player_cfg.custom_status = 0;
req.player_cfg.custom_properties = "{}";

TapSDK_Result ret = TapOnlineGame_AsyncCreateRoom(TapOnlineGame(), ++gRequestID, &req);
// 结果在 TapOnlineGameEventID_CreateRoomResponse 中返回,event_data 为 TapOnlineGameCreateRoomResponse*

匹配房间

  • 匹配时使用的房间配置、玩家配置与创建房间一致;若无满足条件的房间则会自动创建新房间,且自动成为房主。
  • room_cfg.max_player_count + room_cfg.room_type + room_cfg.match_params 和创建房间的取值一致,才会匹配上。
TapOnlineGameMatchRoomRequest req = {};
req.room_cfg.max_player_count = 4;
req.room_cfg.room_type = "ranked";
req.room_cfg.name = "MyRoom"; // 用于匹配不到房间时,创建新房间使用
req.room_cfg.custom_properties = "{}"; // 用于匹配不到房间时,创建新房间使用
req.player_cfg.custom_status = 0;
req.player_cfg.custom_properties = "{}";

TapOnlineGame_AsyncMatchRoom(TapOnlineGame(), ++gRequestID, &req);
// 结果在 TapOnlineGameEventID_MatchRoomResponse 中返回;如果匹配到已有房间,房间内其他玩家会收到 TapOnlineGameEventID_EnterRoomNotification

拉取房间列表并加入

先按房间类型拉取列表(可翻页),再根据房间 ID 加入。

// 拉取列表
TapOnlineGameGetRoomListRequest listReq = {};
listReq.room_type = "ranked"; // 不填则拉取全部类型
listReq.offset = 0; // 首次请求传 0,翻页时使用上次返回的 offset
listReq.limit = 20;
TapOnlineGame_AsyncGetRoomList(TapOnlineGame(), ++gRequestID, &listReq);
// 结果在 TapOnlineGameEventID_GetRoomListResponse,含 rooms、offset、has_more

// 加入指定房间(room_id 来自拉取列表的结果)
TapOnlineGameJoinRoomRequest joinReq = {};
joinReq.room_id = "room_id_from_list";
joinReq.player_cfg.custom_status = 0;
joinReq.player_cfg.custom_properties = "{}";
TapOnlineGame_AsyncJoinRoom(TapOnlineGame(), ++gRequestID, &joinReq);
// 结果在 TapOnlineGameEventID_JoinRoomResponse;房间内其他玩家会收到 TapOnlineGameEventID_EnterRoomNotification
房间信息
  • 成功进入房间后,可通过返回的TapOnlineGameRoomInfo获取房间内玩家列表、房主、房间属性等。
  • 其他玩家进入/离开房间会通过TapOnlineGameEventID_EnterRoomNotification/TapOnlineGameEventID_LeaveRoomNotification通知。

管理房间

更新玩家自定义状态

用于表示“未就绪/已就绪”等,房间内所有玩家会收到 TapOnlineGameEventID_PlayerCustomStatusNotification

// 例如 0 未就绪 1 已就绪
TapOnlineGame_AsyncUpdatePlayerCustomStatus(TapOnlineGame(), ++gRequestID, 1);
// 结果在 TapOnlineGameEventID_UpdatePlayerCustomStatusResponse

更新玩家自定义属性

每个玩家均可更新自己的自定义属性(如昵称、等级等),房间内所有玩家会收到TapOnlineGameEventID_PlayerCustomPropertiesNotification

const char* properties = "{\"nick\":\"Alice\",\"level\":10}";  // UTF-8,最大 2048 字节,允许空
TapOnlineGame_AsyncUpdatePlayerCustomProperties(TapOnlineGame(), ++gRequestID, properties);
// 结果在 TapOnlineGameEventID_UpdatePlayerCustomPropertiesResponse

更新房间属性

  • 仅限房主,且未开始帧同步
  • 更新房间名称、自定义属性等,房间内所有玩家会收到 TapOnlineGameEventID_RoomPropertiesNotification
TapOnlineGameUpdateRoomPropertiesRequest req = {};
req.name = "NewRoomName";
req.custom_properties = "{}";
TapOnlineGame_AsyncUpdateRoomProperties(TapOnlineGame(), ++gRequestID, &req);
// 结果在 TapOnlineGameEventID_UpdateRoomPropertiesResponse

把玩家踢出房间

  • 仅限房主,且未开始帧同步
  • 玩家被踢后,房间内所有玩家会收到TapOnlineGameEventID_RoomPlayerKickedNotification
TapOnlineGame_AsyncKickRoomPlayer(TapOnlineGame(), ++gRequestID, "player_id_to_kick");
// 结果在 TapOnlineGameEventID_KickRoomPlayerResponse

离开房间

未开始帧同步时,玩家可以随时离开房间,房间内其他玩家会收到TapOnlineGameEventID_LeaveRoomNotification。若离开的是房主,服务端会自动选择其他玩家为新房主。

TapOnlineGame_AsyncLeaveRoom(TapOnlineGame(), ++gRequestID);
// 结果在 TapOnlineGameEventID_LeaveRoomResponse

房间内数据传输

进入房间后,可通过发送自定义消息或者发送帧输入(房主开启帧同步后)来实现游戏数据传输。这两种数据传输方式适合的游戏类型如下。

  • 自定义消息:可用于实现状态同步,适合回合制、棋牌等对实时性要求不高的场景。
  • 帧同步:适合格斗、MOBA 等高实时性游戏。

详细使用方式请参考数据传输

错误码

  • 接口调用返回值均为TapSDK_Result,可根据该值做提示或重试。详见TapSDK_Result
    • 返回值非TapSDK_Result_OK时,表示调用失败,后续不会触发回调。
  • 回调函数中event->error非空时,表示请求失败,可根据TapSDK_ErrorCode做提示或重试。详见TapSDK_ErrorCode
    • 需要处理的错误码枚举前缀为TapSDK_ErrorCode_(通用错误码)和TapSDK_ErrorCode_OnlineGame_(多人联机专用错误码)。