游戏中心对接GKTurnBasedMatch有显着滞后(约1分钟)

时间:2013-03-25 13:48:41

标签: iphone ios objective-c ipad game-center

我正在通过游戏中心实现多人模式的回合制游戏。我有2个设备(1个ipad,1个iphone)在沙盒模式下进行测试,这些设备工作正常,但最近它开始在汽车配对过程中挣扎。在我从一个用户发送第一个回合后,另一个设备不会立即识别该游戏,而是打开自己的新游戏。之前它能够立即发现在其他设备上开始的游戏,并且配对相当简单。而且我不记得更改与配对相关的任何部分(NSCodingGKTurnBasedEventHandlerGKTurnBasedMatchmakerViewControllerDelegate委托方法等)。

现在我从一个设备发送第一个转弯,需要等待大约1分钟,以便其他设备可以成功连接到该游戏。连接发生后,endTurnWithMatchData调用没有任何问题,它可以在1-2秒内发送和接收数据。但如果用户开始新游戏并且必须等待1分钟以便其他用户可以连接到他的游戏,那么它将不是一个好的用户体验。有没有人在汽车配对过程中遇到重大延迟?我还没有实现邀请,所以我无法检查。我与NSKeyedArchiver存档的matchdata似乎相当大,3396字节,即使对于几乎没有数据的新游戏。这是我的代码的相关部分:

GameOptionsViewController

- (void)turnBasedMatchmakerViewControllerWasCancelled:(GKTurnBasedMatchmakerViewController *)viewController
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController didFailWithError:(NSError *)error
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController didFindMatch:(GKTurnBasedMatch *)match
{
    [self dismissViewControllerAnimated:NO completion:nil];
    self.gcMatch = match;
    [self performSegueWithIdentifier:@"GameMultiplayer" sender:self];
}

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"GameMultiplayer"])
    {
        GameViewController *GameVC = (GameViewController *)segue.destinationViewController;

        [GameVC setGameMode:GAMEMODE_MULTIPLAYER_SAMEDEVICE];

        //Multiplayer game it is
        if(self.gcMatch != nil)
        {
            [GameVC setGameMode:GAMEMODE_MULTIPLAYER_GAMECENTER];
            GameVC.gcMatchDelegate = self;
            GameVC.gcMatch = self.gcMatch;
            NSLog(@"Game OVC Segue: Match ID | %@", self.gcMatch.matchID);

        }
    }
    else
    {
       ...
    }
}

GameViewController

//This method is called according to user actions
//It's the only method I use to send data to other participant
-(void) sendCurrentGameDataWithNewTurn:(BOOL) newTurn
{
    NSLog(@"Sending game data current participant : %@", gcMatch.currentParticipant.playerID);

    //Update match data if it is corrupted anyhow
    if (gcMatch.currentParticipant == nil)
    {
    [GKTurnBasedMatch loadMatchWithID:gcMatch.matchID withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error)
     {
         if (error != nil)
         {
             NSLog(@"Error :%@", error);
             return ;
         }
         [self sendCurrentGameDataWithNewTurn:newTurn];
     }];
}
else
{
    NSData *matchData = [NSKeyedArchiver archivedDataWithRootObject:game];

    //Game advances to new player, buttons are disabled
    if(newTurn)
    {
        NSLog(@"SENDING NEW TURN");

        NSUInteger currentIndex = [gcMatch.participants
                                   indexOfObject:gcMatch.currentParticipant];

        GKTurnBasedParticipant *nextParticipant;
        nextParticipant = [gcMatch.participants objectAtIndex:
                           ((currentIndex + 1) % [gcMatch.participants count])];

        [gcMatch endTurnWithNextParticipants:[NSArray arrayWithObject:nextParticipant] turnTimeout:GC_TURN_TIMEOUT matchData:matchData completionHandler:^(NSError *error) {
            NSLog(@"Sent");
            if (error) {
                NSLog(@"SNT - %@", error);
            }
        }];
    }
    else
    {
        NSLog(@"ONLY UPDATING DATA");
        [gcMatch saveCurrentTurnWithMatchData:matchData completionHandler:^(NSError *error) {
            NSLog(@"Sent");
            if (error) {
                NSLog(@"OUD - %@", error);
            }
        }];
    }
}

}

-(void) updateGameDataWithGCMatch
{
    //Update whole game data
    self.game = [NSKeyedUnarchiver unarchiveObjectWithData:self.gcMatch.matchData];

    //Update game ui
    ...
}

-(void) handleTurnEventForMatch:(GKTurnBasedMatch *)match didBecomeActive:(BOOL)didBecomeActive
{
    //Check if I got data for the currently active match that options vc forwarded me here, if not do some debug print and return
    if(![self.gcMatch.matchID isEqual:match.matchID])
    {
        //For debugging reasons I skip if i get info for any previous match (other player quit etc)
        NSLog(@"GCMatch matchID: %@ match matchID:  %@",self.gcMatch.matchID,match.matchID);
        return;
    }

    NSLog(@"Turn event handle");

    self.gcMatch = match;

    if([match.currentParticipant.playerID isEqualToString: [GKLocalPlayer localPlayer].playerID ])
    {
        //Disable field buttons
        [self setFieldButtonsEnabled:TRUE];
        [self turnChangeAnimationFromLeftToRight:FALSE];
    }

    [self updateGameDataWithGCMatch];
}

1 个答案:

答案 0 :(得分:0)

至于你的问题:

我自己在游戏中心的配对上做了相当多的调整,并经常经历滞后,这已被证明不是由我的网站引起的,而是由苹果游戏中心服务器引起的。

至于其他指导:

据我所知,您目前在设备上进行配对的方法是:

查看我可以连接的匹配项 - >如果YES请求gamedata并连接到比赛ELSE开始你自己的比赛并广播matchdata

根据我的经验,最好从matchrequestbroadcasts开始,等到你找到第二个玩家,定义服务器设备(例如通过游戏中心名称的较低校验和),然后在该设备上启动游戏。