斯威夫特 - GKMatchDelegate

时间:2017-07-12 18:55:34

标签: ios swift game-center gkmatchmaker

我是Swift的新手,最近开始开发我自己的应用程序。我一直在努力实现Game Center多人游戏。我项目的当前结构是(标准游戏中心结构):

  • GameViewController - UIViewController,GKGameCenterControllerDelegate
  • GameKitHelper - NSObject,GKGameCenterControllerDelegate,GKMatchmakerViewControllerDelegate,GKMatchDelegate
  • GameKitHelperDelegate - protocol(matchStarted,matchEnded,match)
  • MultiplayerNetwork - GameKitHelperDelegate(用于发送和处理消息)

我面临的问题是在多人游戏生成的最初阶段。在GameViewController上,我有以下代码来触发多人游戏:

    func playMultiGame(){
    var gameScene = GameSceneMultiPlayer(size:CGSize(width: 2048, height: 1536))

    let networkingEngine = MultiplayerNetworking()
    networkingEngine.delegate = gameScene
    gameScene.networkingEngine = networkingEngine
    GameKitHelper.SharedGameKitHelperInstance.findMatchWithMinPlayers(minPlayers: 2, maxPlayers: 2, viewController: self, delegate: networkingEngine)

    let skView = self.view as! SKView

    gameScene.scaleMode = .fill
    skView.presentScene(gameScene)        

}

上面触发的findMatchWithMinPlayers方法如下:

func findMatchWithMinPlayers(minPlayers:Int, maxPlayers:Int, viewController:UIViewController, delegate:GameKitHelperDelegate) {

    if(!_enableGameCenter) {
        return;
    }

    _matchStarted = false
    self._match = nil
    _delegate = delegate
    viewController.dismiss(animated: false, completion: nil)

    //GKmatch request
    let request = GKMatchRequest()
    request.minPlayers = minPlayers
    request.maxPlayers = maxPlayers

    let mmvc = GKMatchmakerViewController(matchRequest: request)
    mmvc?.matchmakerDelegate = self
    viewController.present(mmvc!, animated: true, completion: nil)
}

上面的方法在GameKitHelper中,它有以下方法:

class GameKitHelper : NSObject, GKGameCenterControllerDelegate, GKMatchmakerViewControllerDelegate, GKMatchDelegate {
var _enableGameCenter : Bool
var _matchStarted : Bool
var _match : GKMatch!
var _delegate : GameKitHelperDelegate?
var authenticationViewController: UIViewController?
var lastError : NSError?
var playersDict : NSMutableDictionary?

class var SharedGameKitHelperIntance:GameKitHelper {
    return _GameKitHelperSharedInstace
}

override init() {
    self._enableGameCenter = true
    self._matchStarted = false
    super.init()
}

func authenticateLocalPlayer() {
   [...]
}

func setAuthenticationViewController(authViewController:UIViewController!) {
   [...]     
}

func findMatchWithMinPlayers(minPlayers:Int, maxPlayers:Int, viewController:UIViewController, delegate:GameKitHelperDelegate) {
  [...]
}

func lookupPlayers() {
   [...]
}

/* Implementing delegate GKMatchmakerViewControllerDelegate methods */
func matchmakerViewControllerWasCancelled(_ viewController:GKMatchmakerViewController) {
    viewController.dismiss(animated: true, completion: nil)
    print("canceling multiplayer view")
    _delegate?.matchEnded()
}


func matchmakerViewController(_ viewController: GKMatchmakerViewController,
                              didFailWithError error: Error) {
    viewController.dismiss(animated: true, completion: nil)
    NSLog("Error finding match: %@", error.localizedDescription)
}

func matchmakerViewController(_ viewController: GKMatchmakerViewController,
                                       didFind match: GKMatch!) {

    viewController.dismiss(animated: true, completion: nil)
    match.delegate = self
    _match = match

    if(!_matchStarted && match.expectedPlayerCount==0) {
        NSLog("Ready to start match")
        self.lookupPlayers()
    }
}

/* Implementing delegate GKMatchDelegate methods */
func match(match: GKMatch!, didReceiveData data: NSData!, fromPlayer playerID: NSString!) {
    if(_match != match) {
        return
    }

    _delegate?.match(match: match, didReceiveData: data, fromPlayer: playerID)
}

func match(match: GKMatch!,  player: String!, didChangeState state: GKPlayerConnectionState) {

    if(_match != match) {
        return
    }

    switch(state) {
    case GKPlayerConnectionState.stateConnected:
        if(!_matchStarted && match.expectedPlayerCount == 0) {
            NSLog("Ready to start match!")
            self.lookupPlayers()
        }

    case GKPlayerConnectionState.stateDisconnected:
        NSLog("Player disconnected!")
        _matchStarted = false
        _delegate?.matchEnded()
    default:
        break
    }


}

func match(match: GKMatch!, connectionWithPlayerFailed:String!, withError error:NSError!) {

    if(_match != match) {
        return
    }
    NSLog("Failed to connect to player with error: %@", error.localizedDescription)
    _matchStarted = false
    _delegate?.matchEnded()

}

func match(match: GKMatch!, didFailWithError error: NSError!) {

    if(_match != match) {
        return
    }
    NSLog("Match failed with error: %@", error.localizedDescription)
    _matchStarted = false
    _delegate?.matchEnded()

}

func gameCenterViewControllerDidFinish(_ gameCenterViewController: GKGameCenterViewController)
{
    gameCenterViewController.dismiss(animated: true, completion: nil)
}

一旦两个用户配对并且游戏准备启动,只要GKMatchmakerViewController被解除,应用程序就会在执行此操作的matchmakerViewController方法中崩溃:

func matchmakerViewController(_ viewController: GKMatchmakerViewController,
                                       didFind match: GKMatch!) {

    viewController.dismiss(animated: true, completion: nil)
    _match.delegate = self
    _match = match

    if(!_matchStarted && match.expectedPlayerCount==0) {
        NSLog("Ready to start match")
        self.lookupPlayers()
    }
}

通过异常断点,我发现造成上述问题的确切行如下:

    _match.delegate = self

我得到的错误如下:

  

2017-07-12 19:15:47.472473 + 0100 xxx [2653:492023] - [xxx.GameKitHelper   match:didReceiveData:fromPlayer:]:发送到无法识别的选择器   实例0x17047a600 2017-07-12 19:15:47.507642 + 0100 xxx [2653:492023]   ***由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:' - [xxx.GameKitHelper   match:didReceiveData:fromPlayer:]:发送到无法识别的选择器   实例0x17047a600'

任何可能导致此问题的想法?我已经尝试了一切。

0 个答案:

没有答案