使用更多排行榜执行操作

在本教程中,我们将介绍该服务必须提供的高级功能,例如创建多列排行榜、增强的分线以及查询排行榜的多种方式。

对于此示例,我们将假定 此处创建基本排行榜 中呈现的所有内容都已熟悉。 我们将从竞争激烈的射击游戏开始,作为这些新功能如何帮助我们解决一些问题的示例。 在此游戏中,有一种称为团队死亡比赛的模式,由两支球队组成。 谁先获得75个淘汰赛,谁就是赢家。 现在,这个游戏不是基于单个分数来排名玩家:相反,它基于消除、协助和死亡的数量来定义谁是最好的。

创建多列排行榜定义

首先,我们需要创建一个比之前更复杂的排行榜定义。 我们将定义多个列来映射游戏的关键方面:淘汰、助攻和死亡。 以下示例演示如何使用 C# SDK 创建排行榜定义。

public static async Task CreateLeaderboardDefinitionAsync(PlayFabAuthenticationContext context, string leaderboardName)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    CreateLeaderboardDefinitionRequest leaderboardDefinitionRequest = new CreateLeaderboardDefinitionRequest()
    {
        AuthenticationContext = context,
        Name = leaderboardName,
        SizeLimit = 1000,
        EntityType = "title_player_account",
        VersionConfiguration = new VersionConfiguration()
        {
            MaxQueryableVersions = 1,
            ResetInterval = ResetInterval.Manual,
        },
        Columns = new List<LeaderboardColumn>()
        {
            new LeaderboardColumn()
            {
                Name = "Eliminations",
                SortDirection = LeaderboardSortDirection.Descending,
            },
            new LeaderboardColumn()
            {
                Name = "Assists",
                SortDirection = LeaderboardSortDirection.Descending,
            }
            new LeaderboardColumn()
            {
                Name = "Deaths",
                SortDirection = LeaderboardSortDirection.Ascending,
            }         
        }
    };

    PlayFabResult<PlayFab.LeaderboardsModels.EmptyResponse> createLbDefinitionResult = await leaderboardsAPI.CreateLeaderboardDefinitionAsync(leaderboardDefinitionRequest);
}

现在,让我们解释一下此示例的一些关键元素:

  • SizeLimit:此参数用于限制排行榜可能具有的行数。 此处的值只是一个示例。
  • VersionConfiguration:此参数允许我们对排行榜进行版本控制。 有关详细信息,请参阅此页: 季节性排行榜
  • Columns:此参数允许我们定义多个列。 正如你所看到的,我们设置了消除,辅助和死亡。 此处的一个重要元素是 SortDirection 参数,它允许我们确定排行榜的排序。 在此示例中,如果玩家有更多的淘汰和助攻 (SortDirection = 降序) 和更少的死亡 (SortDirection = 升序) ,则排名更高。

有关其他参数或如何管理排行榜定义的详细信息,请参阅 创建基本排行榜

引入外部实体

排行榜服务可用作独立组件,支持引入仅在游戏上下文中有意义的外部实体。 如果你的玩家标识未与 PlayFab 登录名绑定,你仍然可以使用排行榜服务。 PlayFab 系统外部排行榜上条目的实体类型必须为 外部。 然后,entityId 是系统中玩家的标识。 在这些情况下,排行榜上 的所有 条目都必须是 外部 实体。

将数据添加到排行榜

创建排行榜后,接下来添加数据。 与之前关于此主题的教程main区别在于,现在我们需要在同一行中添加三个不同的分数。 以下示例演示如何使用 C# SDK 将数据添加到排行榜。

public static async Task UpdateLeaderboardForPlayer(PlayFabAuthenticationContext context, string leaderboardName, string entityId, int score)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    UpdateLeaderboardEntriesRequest updateLeaderboardRequest = new UpdateLeaderboardEntriesRequest()
    {
        Entries = new List<LeaderboardEntryUpdate>()
        {
            new LeaderboardEntryUpdate()
            {
                EntityId = entityId,
                Scores = new List<string> { score.ToString(), (score + 1).ToString(), (score + 2).ToString() },
                Metadata = "metadata",
            }
        },
        AuthenticationContext = context,
        LeaderboardName = leaderboardName,
    };

    PlayFabResult<PlayFab.LeaderboardsModels.EmptyResponse> updateResult = await leaderboardsAPI.UpdateLeaderboardEntriesAsync(updateLeaderboardRequest);
}

需要注意的是,Scores 参数被赋予了三个值。 为任何条目指定的分数列表的长度必须与排行榜定义的列数匹配。 每个值必须是有效的 64 位整数, (字符串表示形式只是为了确保所有客户端都可以) 处理 64 位值。

从排行榜检索数据

现在,我们将学习查询排行榜的不同方法。 它们都有一个特定目的,旨在帮助开发人员获取他们所需的玩家,以便在游戏中显示。

获取实体周围的排行榜

这种查询排行榜的特定方式使我们能够获取靠近特定实体的排行榜部分。 查看此场景的一种实用方法是,只要我们有一个巨大的排行榜,并且我们只想向在游戏中处于活动状态的玩家显示相关信息。 如果玩家位于 1000 位置,我们可以显示近邻而不是顶级玩家。 以下示例演示如何使用 C# SDK 围绕实体查询排行榜。

public static async Task<List<EntityLeaderboardEntry>> GetLeaderboardAroundEntity(PlayFabAuthenticationContext context, string leaderboardName, string entityId)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    GetLeaderboardAroundEntityRequest getLbRequest = new GetLeaderboardAroundEntityRequest()
    {
        LeaderboardName = leaderboardName,
        AuthenticationContext = context,
        Entity = new PlayFab.LeaderboardsModels.EntityKey()
        {
            Id = entityId,
            Type = EntityType
        },
        MaxSurroundingEntries = 20,
    };

    PlayFabResult<GetEntityLeaderboardResponse> lbResponse = await leaderboardsAPI.GetLeaderboardAroundEntityAsync(getLbRequest);
    
    return lbResponse.Result.Rankings;

}

此处最重要的元素是 MaxSurroundingEntries,它允许我们从排行榜中提取围绕特定实体排名的实体。 例如,如果我们在位置 100 中有一个玩家,并且使用 MaxSurroundingEntries = 20,则它会从位置 90 检索到 110 的玩家。 如果玩家位于排行榜的顶部,它将检索前 20 个结果。 如果玩家位于底部,它将检索最后 20 个结果。 除了排行榜顶部和底部的位置,API 会尝试确保请求排名的实体位于检索到的位置的中心。

获取实体的排行榜

此 API 提供了另一种查询排行榜的方法。 每当我们想要在排行榜中搜索多个实体并对其进行排序时,它就有效。 以下示例演示如何使用 C# SDK 在排行榜上查询实体列表。

public static async Task<List<EntityLeaderboardEntry>> GetLeaderboardForEntities(PlayFabAuthenticationContext context, string leaderboardName, List<string> entityIds)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    GetLeaderboardForEntitiesRequest getLbRequest = new GetLeaderboardForEntitiesRequest()
    {
        LeaderboardName = leaderboardName,
        AuthenticationContext = context,
        EntityIds = entityIds,
    };

    PlayFabResult<GetEntityLeaderboardResponse> lbResponse = await leaderboardsAPI.GetLeaderboardForEntitiesAsync(getLbRequest);

    return lbResponse.Result.Rankings;
}

获取好友排行榜

在某些情况下,一些休闲玩家会来玩一场游戏。 他们可能远离排行榜的顶部,但在他们的朋友中,他们有一个竞争正在进行。 使用此 API,我们可以查询排行榜并查找玩家的朋友。

public static async Task<List<EntityLeaderboardEntry>> GetFriendLeaderboardForEntity(PlayFabAuthenticationContext context, string leaderboardName, string entityId)
{
    PlayFabProgressionInstanceAPI leaderboardsAPI = new PlayFabProgressionInstanceAPI(context);
    GetFriendLeaderboardForEntityRequest getLbRequest = new GetFriendLeaderboardForEntityRequest()
    {
       LeaderboardName = leaderboardName,
       Entity = new PlayFab.LeaderboardsModels.EntityKey()
       {
           Id = entityId,
           Type = EntityType
       },
    };

    PlayFabResult<GetEntityLeaderboardResponse> lbResponse = await leaderboardsAPI.GetFriendLeaderboardForEntityAsync(getLbRequest);
  
    return lbResponse.Result.Rankings;
}

可通过多种方式从 PlayFab 服务中获取好友。 有关可用参数的详细信息,请参阅 API 参考

增强断线

考虑到我们高度竞争的射手示例,在某些情况下,多个玩家的淘汰次数可能相同。 对于这些方案,我们需要采用不同的方法来打破这些案例。 在这种情况下,增强的捆绑中断功能将发挥作用。

创建排行榜定义时,可以有多个列。 添加它们的方式决定了我们将如何对某些方案进行排序和中断。 有一个优先顺序,其中添加的第一列是最重要的,然后是第二列,依此类推。 此方案将转换为我们的示例,即每当淘汰中存在平局时,第二个标准是助攻数,最后一个标准是死亡。 在平局仍然存在的极端情况下,它默认为时间戳,无论谁先获得得分。

排名 实体 ID 消除 协助 死亡 LastUpdated
1 “玩家 3” 103 24 15 “2024-08-27T20:24:36.738Z”
2 “玩家 2” 102 30 20 “2024-08-27T20:24:29.251Z”
3 “玩家 1” 100 25 18 “2024-08-27T19:52:26.642Z”
4 “玩家 4” 100 25 18 “2024-08-27T20:24:44.552Z”
4 “玩家 5” 100 25 19 “2024-08-27T20:25:47.552Z”

在此示例中,我们有三个玩家之间的平局:

  • “玩家 5”:尽管淘汰和助攻数量相同,但他们的死亡更多,这意味着他们处于排行榜的底部。
  • “玩家 4”:此玩家的死亡次数比“玩家 5”少,与“玩家 1”相同,但玩家 1 先获得这些数字。
  • “玩家 1”:尽管数字与“玩家 4”相同,但该玩家是第一个在游戏中取得此分数的球员,因此,他们在此平局场景中排名更高。

结论

在本教程中,我们学习了如何执行以下操作:

  • 创建多列排行榜。
  • 检查多种查询方式。
  • 了解增强的断接机制。

另请参阅