Tap into Game Center: Leaderboards, Achievements, and Multiplayer
Graphics & Games 进阶 25m

接入 Game Center:排行榜、成就和多人游戏

Tap into Game Center: Leaderboards, Achievements, and Multiplayer

2020年6月25日

在 Apple 官方观看视频

一句话判断

排行榜、成就和多人匹配——Game Center 提供了完整的社交游戏基础设施,你不需要自己搭建后端就能拥有这些能力。

这场 Session 讲了什么

这场 Session 是 Game Center 系列的第二部分,聚焦于三个核心游戏功能的 API 使用:Leaderboards(排行榜)、Achievements(成就)和 Multiplayer(多人游戏)。与第一部分(Dashboard UI)不同,这场更偏重后端 API 的使用方式。

排行榜部分介绍了新的 GKLeaderboard API。你可以按时间范围(今天、本周、所有时间)查询排名,也可以按社交范围(全局、仅好友)过滤。2020 年的更新增加了对 “Recurring Leaderboards” 的支持——你可以设置每周或每月自动重置的排行榜,鼓励玩家持续参与。

成就部分讲解了 GKAchievement 的提交和追踪。每个成就有一个唯一 ID、一个完成百分比(0-100%)和一个显示状态(是否已向好友展示)。你可以为成就设置隐藏状态——玩家在达成之前看不到具体要求,这增加了探索乐趣。

多人游戏部分是最重要的更新。Apple 引入了基于邀请的实时多人匹配(Real-Time Multiplayer)的改进,以及新的 Turn-Based Multiplayer API。Session 重点讲解了如何处理匹配流程、玩家状态同步、以及断线重连。

值得深挖的点

  • Recurring Leaderboard 的设计价值:传统的全局排行榜有一个致命问题——新玩家永远追不上老玩家的高分,逐渐失去参与动力。Recurring Leaderboard 通过定期重置解决了这个问题。每周重置的排行榜让所有玩家每周都有争夺第一名的机会。
  • Turn-Based Multiplayer 的使用场景:回合制多人游戏不需要所有玩家同时在线。Apple 的 Game Center 提供了完整的回合管理:推送通知提醒轮到谁了、处理玩家退出、自动判定超时。这比自建回合系统简单得多。

代码片段

// 加载排行榜数据
func loadLeaderboard() {
    GKLeaderboard.loadLeaderboards(IDs: ["weekly_score"]) { leaderboards, error in
        guard let leaderboard = leaderboards?.first else { return }

        // 加载全球前 10 名
        leaderboard.loadEntries(
            for: .global,
            timeScope: .week,
            range: NSRange(1...10)
        ) { entries, totalPlayers, error in
            for entry in entries ?? [] {
                print("\(entry.player.alias): \(entry.score)")
            }
        }

        // 加载好友排名
        leaderboard.loadEntries(
            for: .friendsOnly,
            timeScope: .week,
            range: NSRange(1...25)
        ) { entries, _, _ in
            self.displayFriendScores(entries)
        }
    }
}
// 提交成就进度
func unlockAchievement(id: String, percent: Double = 100.0) {
    let achievement = GKAchievement(identifier: id)
    achievement.percentComplete = percent
    achievement.showsCompletionBanner = true  // 完成时显示横幅

    GKAchievement.report([achievement]) { error in
        if let error = error {
            print("成就提交失败: \(error)")
        }
    }
}

// 渐进式成就(如"收集 50 个金币")
func onCoinCollected(total: Int) {
    let percent = min(Double(total) / 50.0 * 100.0, 100.0)
    unlockAchievement(id: "collect_50_coins", percent: percent)
}
// 实时多人匹配
func startMultiplayerMatch() {
    let request = GKMatchRequest()
    request.minPlayers = 2
    request.maxPlayers = 4
    request.inviteMessage = "来一起玩吧!"

    let matchmaker = GKMatchmakerViewController(matchRequest: request)
    matchmaker?.matchmakerDelegate = self
    present(matchmaker!, animated: true)
}

// 匹配成功后处理
func matchmaker(
    _ viewController: GKMatchmakerViewController,
    didFind match: GKMatch
) {
    match.delegate = self
    viewController.dismiss(animated: true)

    // 通过 match.sendData 发送游戏数据
    let gameData = encodeGameState()
    try? match.sendData(
        gameData,
        to: match.players,
        dataMode: .reliable
    )
}

最佳实践

  • 排行榜分数提交不要太频繁,在合适的时机(如关卡结束时)批量提交
  • 成就设计要有梯度:简单成就给新手成就感,困难成就给核心玩家挑战
  • 多人匹配时提供 AI 填充选项,匹配不到真人时用 AI 替代
  • 处理断线重连逻辑,网络不稳定时不要让玩家直接丢失进度
  • 测试时使用沙盒账号验证排行榜和成就的正确性

还有什么值得关注

  • Game Center 的服务端 API 允许你在自己的服务器上验证分数和成就的合法性
  • “Tap into Game Center: Dashboard, Access Point, and Profile” 是这个系列的第一部分,介绍 UI 集成
  • 如果你在做跨平台多人游戏,需要考虑 Game Center 玩家与其他平台玩家的互通问题
WWDC 2020