首页 > 解决方案 > 多人游戏的 Game Center 回合超时

问题描述

我使用 Swift 和 Game Center 创建了一个基于回合的多人棋盘游戏,效果很好。我想补充的最后一项是一种防止玩家在知道自己会输的情况下在接近尾声时放弃游戏的方法。似乎 endTurn 函数的 turnTimeout 部分是专门为此目的而内置的,但我无法让它工作。我的 endTurn 函数如下:

func endTurn(_ model: GameModel, completion: @escaping CompletionBlock) {
    guard let match = currentMatch else {
        completion(GameCenterHelperError.matchNotFound)
        return
    }
    
    do {
        let currenParticipantIndex: Int = (match.participants.firstIndex(of: match.currentParticipant!))!
        let nextPerson = [match.participants[(currenParticipantIndex+1) % match.participants.count]]
        
        print("end turn, next participant \(String(describing: nextPerson[0].player?.alias))")
        match.endTurn(
            withNextParticipants: nextPerson,
            turnTimeout: 15,
            match: try JSONEncoder().encode(model),
            completionHandler: completion
        )
    } catch {completion(error)}
}

此函数考虑了 Anton 在对此问题的答案的评论中的建议: 尝试在我的 Game Center 游戏上设置时间限制 以更新 nextParticipant 玩家的数组,以便永远不会到达数组的末尾。在我的测试中,我还尝试通过让玩家 1 和玩家 2 都延迟轮到结束以查看它是否会触发来解决此问题(该游戏仅是 2 人游戏)

这也应该回答这个问题: Game Center turn timeouts

文档说:

timeoutDate:玩家在放弃回合之前必须采取行动的时间。你的游戏决定当一个回合被没收时会发生什么。对于某些游戏,被没收的回合可能会结束比赛。对于其他游戏,您可能会为玩家选择一组合理的默认操作,或者干脆什么都不做。 https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/GameKit_Guide/ImplementingaTurn-BasedMatch/ImplementingaTurn-BasedMatch.html

不幸的是,我根本无法启动 turnTimeout 函数。我做了相当多的研究,但我没有找到关于什么函数在触发时实际调用的明确答案(即玩家需要比分配的时间更长的时间来轮到他们)。我希望调用与 endTurn 函数的常规调用相同的函数进行超时,并调用以下播放器侦听器:

func player(_ player: GKPlayer, receivedTurnEventFor match: GKTurnBasedMatch, didBecomeActive: Bool) {
    if let vc = currentMatchmakerVC {
        currentMatchmakerVC = nil
        vc.dismiss(animated: true)
    }

    print("received turn event")
    if !didBecomeActive {
        print("\n\n\n player listener did become active")
        print("match did change")
        NotificationCenter.default.post(name: .matchDidChange, object: match)
    } else if didBecomeActive {
        print("present game")
        NotificationCenter.default.post(name: .presentGame, object: match)
    }
}

当从游戏中专门调用 endTurn 时,我能够让玩家侦听器(接收到的转弯事件)触发,但我看不到在 turnTimeout 事件触发时调用的任何内容。如果是播放器侦听器,我会在控制台中看到打印语句以及下一个播放器设备上的通知。

GKTurnTimeoutDefault 是 604,800,是一个时间间隔,我对其进行了一些研究并得出结论,它以秒为单位,即 7 天。我将其更改为 0.00001、15、2000 和介于两者之间的一些值,但我无法让它触发。

我还找到了以下内容,但第一个没有答案,第二个只说轮到超时可能需要自己的完整答案:

Game Center 回合制游戏回合超时

如何在 iOS9 中检测 Game Center 回合制比赛何时结束?

我在想我的错误可能是我无法找到在轮流超时触发时调用的函数,尽管我可能会误认为我在那里输入的时间间隔值。

感谢您花时间审查我的问题 :)

标签: swiftgame-centermultiplayer

解决方案


推荐阅读