首页 > 解决方案 > 如何从排行榜中获取用户的分数?- 斯威夫特

问题描述

我正在开发一款与排行榜和最佳玩家分数相冲突的游戏。我希望当他进入应用程序时,它会与他保存在排行榜中的分数同步,但我没有找到任何可以简单地将值返回给我的东西。

我知道如何定义:

public func setHighScore(score:Int) ->Void {
    if (self.localUser.isAuthenticated) {
        GKLeaderboard.submitScore(score, context: 0, player: self.localUser, leaderboardIDs: ["lbHighScore"], completionHandler: {error in} )
    }
}

我想要的是这样的:

public func getHighScore() ->Int{
    if (self.localUser.isAuthenticated) {
        return GKLeaderboardScore      // <- this is the score svaed on leaderboard as integer
    }
    return 0
}

标签: swiftgame-centergamekit

解决方案


经过大量工作,我终于找到了!1

开始吧:

它在访问游戏中心时的工作方式是异步的,即并行的。为避免接收和保存信息时出现错误和“延迟”,我建议保存为UserDefault. 因此,当您获取数据时,它将保存在全局变量中。一旦你得到它,你不能只返回值,因为它在 a 内completionHandler,返回的地方是Void

要访问用户信息,您需要访问具有保存在排行榜上显示的分数GKLeaderboard.Entry的方法的类。.score但是访问此方法的唯一方法是使用标准函数,当用户通过参数传递时,该函数将返回此信息。

.

第一步:使用该GKLeaderboard.loadLeaderboards功能访问排行榜。在此函数中,作为参数:

  • 列出将要访问的排行榜的 id

除了completionHandlerwhich 将返回两个实例:

  • 排行榜列表
  • 错误处理变量 ( Error)
class func loadLeaderboards(
    IDs leaderboardIDs: [String]?, 
    completionHandler: @escaping ([GKLeaderboard]?, Error?) -> Void
)

.

第二步:访问排行榜数据。为此,我们将使用该GKLeaderboard.loadEntries方法。在其中,我们将作为参数传递:

  • 我们将访问的用户列表
  • 在排行榜的哪个时期将被访问

除了completionHandlerwhich 将返回两个实例:

  • .Entry本地用户的类(正是我想要的)
  • .Entry如果有多个用户,则包含类的列表
  • 错误处理变量 ( Error)
func loadEntries(
    for players: [GKPlayer], 
    timeScope: GKLeaderboard.TimeScope, 
    completionHandler: @escaping (GKLeaderboard.Entry?,[GKLeaderboard.Entry]?, Error?) -> Void
)

.

因此,混合这两个类,在给定排行榜中获取用户分数的函数是:

// Function that takes information and saves it to UserDefault
func getHighScoreFromLeadboard() ->Void {
    // Check if the user is authenticated
    if (GKLocalPlayer.local.isAuthenticated) {
        // Load the leaderboards that will be accessed
        GKLeaderboard.loadLeaderboards(
                        IDs: ["idLeaderboard"]          // Leaderboards'id  that will be accessed
                        ) { leaderboards, _ in          // completionHandler 01: .loadLeaderboards 
                        
            // Access the first leaderboard
            leaderboards?[0].loadEntries(
                                for: [GKLocalPlayer.local], // User who will be accessed within the leaderboard, in this case the local user
                                timeScope: .allTime)        // Choose which period of the leaderboard you will access (all time, weekly, daily...)
                                { player, _, _ in           // completionHandler 02: .loadEntries
                                
                // Save on UserDefault
                UserDefaults.standard.set(player?.score, forKey: "score")
            }
        }
    }
}


推荐阅读