2013-03-25 67 views
6

我正在通过gamecenter实现基于回合制的多人模式游戏。我有2个设备(1个iPad,1个iPhone)在沙箱模式下测试,这些模式运行良好,但最近它已开始在自动匹配过程中挣扎。在我从一个用户发送第一个回合后,其他设备不会立即识别该游戏,而是开启自己的新游戏。在能够立即发现在其他设备上开始的游戏之前,配对相当简单。我不记得改变任何与配对有关的部分(NSCoding,GKTurnBasedEventHandlerGKTurnBasedMatchmakerViewControllerDelegate委托方法等)。Game Center Matchmaking GKTurnBasedMatch有显着的延迟(〜1分钟)

现在我发送一个设备的第一个回合,需要等待大约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

游戏中心可能有看似任意的滞后。从来不知道是因为我们自己的网络,还是Apple的一方。 – 2013-04-15 18:20:25

+0

我在过去的2-3周里一直有这种滞后现象。现在它变得更糟或更好。请问您是否在使用2台设备上的沙箱帐户测试您的应用程序时遇到此类延迟?如果其他开发人员也拥有它,那么我将停止搜索解决方案;继续进行测试。 – guenis 2013-04-15 21:41:24

+0

我在使用GC沙箱时也经历了显着的延迟。从工作会议到工作会议似乎也有很大不同。 – crgt 2013-04-22 22:41:39

回答

0

至于你的问题:

我自己在比赛中心进行了很多比赛,经历了很长时间的滞后,这已经被证明不是由我的网站造成的,而是由苹果游戏中心服务器造成的。

至于其他指导:

至于我可以看到你目前的做法牵线搭桥的设备上是:

看,如果有匹配我可以连接到 - >如果是要求GAMEDATA并连接到比赛ELSE开始自己的比赛和广播matchdata

从我的经验,更好的做法是先从matchrequestbroadcasts,等到你找不到第二个的球员,定义服务器设备(例如,通过较低的校验游戏中心名称),然后开始该设备上的游戏。