2013-03-25 9 views
6

Wdrażam grę turową z trybem multiplayer poprzez gamecenter. Mam 2 urządzenia (1 ipad, 1 iphone) do przetestowania w trybie piaskownicy, które działały dobrze, ale ostatnio zaczęło się zmagać w automatycznym procesie kojarzenia. Po wysłaniu pierwszego zwrotu od jednego użytkownika, drugie urządzenie nie rozpoznaje natychmiast tej gry, ale otwiera własną świeżą grę. Zanim udało się od razu zorientować się, że gra zaczęła się w drugim urządzeniu, kojarzenie było dość proste. Nie pamiętam też żadnych części związanych z dopasowywaniem (NSCoding, GKTurnBasedEventHandler, GKTurnBasedMatchmakerViewControllerDelegate przekazać metody itp.).Game Matchmaking GKTurnBasedMatch ma znaczące opóźnienie (~ 1 min)

Teraz wysyłam pierwszą turę z jednego urządzenia i muszę poczekać około 1 minuty, aby drugie urządzenie mogło połączyć się z tą grą. Po nawiązaniu połączenia funkcje endTurnWithMatchData działają bez żadnych problemów, mogą wysyłać i odbierać dane w ciągu 1-2 sekund. Ale to nie będzie dobry UX, jeśli użytkownicy zaczną świeżą grę i będą musieli poczekać 1 minutę, aby inny użytkownik mógł połączyć się z jego grą. Czy ktoś doświadczał znacznego opóźnienia w automatycznym doborze partnera? Nie zaimplementowałem jeszcze zaproszeń, więc nie mogę tego sprawdzić. Zapisane przeze mnie dane z NSKeyedArchiver wydawały się dość duże, 3396 bajtów, nawet w przypadku nowej gry z prawie żadnymi danymi. A oto odpowiednie części mojego kodu:

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

Game Center może mieć pozornie arbitralne opóźnienia. Nigdy nie wiadomo, czy to ze względu na naszą własną sieć, czy coś ze strony Apple. –

+0

Mam opóźnienie od ostatnich 2-3 tygodni. Teraz było gorzej albo lepiej. Czy mogę prosić o takie opóźnienia podczas testowania aplikacji na kontach Sandbox na 2 urządzeniach. Jeśli inni deweloperzy również go mają, to przestanę szukać rozwiązania; kontynuować testowanie, tak jak jest. – guenis

+0

Doświadczyłem również znacznego opóźnienia podczas pracy z piaskownicą GC. Wydaje się również, że różni się on znacznie od sesji roboczych do sesji roboczych. – crgt

Odpowiedz

0

Co do Twojego pytania:

Ja sam hartowałem się z zapałkami nad Game Center, a także dość często doświadczałem opóźnień, o których dowiedziono, że nie zostały spowodowane przez moją stronę, ale przez serwery centrów gier.

Co do dodatkowych wytycznych:

miarę widzę swoje obecne podejście do kojarzeń w urządzeniu wynosi:

wygląd jeśli jest mecz mogę połączyć się z -> Jeśli TAK Żądaj gamedata i połącz się z meczem ELSE rozpocznij swój własny mecz i transmisj meczowej wartości

Z mojego doświadczenia wynika, że ​​lepiej zacząć od matchrequestbroadcasts, poczekać, aż znajdziesz drugiego gracza, zdefiniować urządzenie serwerowe (np. przez niższą sumę kontrolną nazwy centrum gier), a następnie zacznij gra na tym urządzeniu.

Powiązane problemy