2013-03-25 15 views
7

Próbuję zaimplementować w czasie rzeczywistym grę wieloosobową z niestandardowym interfejsem użytkownika (bez GKMatchMakerViewController). Używam startBrowsingForNearbyPlayersWithReachableHandler:^(NSString * playerID, BOOL osiągalny), aby znaleźć lokalnego gracza, a następnie inicjowanie polecenia dopasowania z singleton GKMatchmaker (który już zainicjowałem).iOS Game Center GameKit Programmatic Invite Matchmaking

Oto, gdzie mam problem. Kiedy wysyłam żądanie, obsługa zakończenia jest uruchamiana niemal natychmiast, bez błędu, a mecz, który zwraca, ma oczekiwaną liczbę graczy równą zero. Tymczasem drugi gracz na pewno nie zareagował na prośbę

odpowiedni kod:

- (void) findMatch { 
    GKMatchRequest *request = [[GKMatchRequest alloc] init]; 
    request.minPlayers = NUM_PLAYERS_PER_MATCH; //2 
    request.maxPlayers = NUM_PLAYERS_PER_MATCH; //2 
    if (nil != self.playersToInvite) { 
    // we always successfully get in this if-statement 
    request.playersToInvite = self.playersToInvite; 
    request.inviteeResponseHandler = ^(NSString *playerID, GKInviteeResponse response) { 
     [self.delegate updateUIForPlayer: playerID accepted: (response == GKInviteeResponseAccepted)]; 
    }; 
} 
request.inviteMessage = @"Let's Play!"; 

[self.matchmaker findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error) { 
    if (error) { 
    // Print the error 
    NSLog(@"%@", error.localizedDescription); 
    } else 
    if (match != nil) { 
     self.currentMatch = match; 
     self.currentMatch.delegate = self; 

     // All players are connected 
     if (match.expectedPlayerCount == 0) { 
     // start match 
     [self startMatch]; 
     } 
     [self stopLookingForPlayers]; 
     } 
    }]; 
} 

znam z poprzedniego pytania (iOS Gamecenter Programmatic Matchmaking), że muszę to tak:

- (void)matchForInvite:(GKInvite *)invite completionHandler:(void (^)(GKMatch *match, NSError *error))completionHandler 

w powyższy kod, ale nie wiem, gdzie to powinno być zawarte. Próbowałem go zarówno GKMatchRequest inviteeResponseHandler, jak i matchmaker finMatchForRequest: withCompletionHandler bezskutecznie. Zachodzi takie zachowanie, że zwycięzca natychmiast zwraca mecz (nawet przed zaproszeniem zaproszonej osoby), a matchRequest inviteeResponseHandler nigdy nie jest wywoływany, nawet gdy zaproszona dotknie zaproszenia zapałek.

Czy ktoś może udzielić porady w tej sprawie? Dziękuję Ci.

... Jim

+0

Skąd otrzymałeś startBrowsingForNearbyPla yersWithReachableHandler do pracy? Nigdy nie otrzymałem od niego żadnego połączenia zwrotnego? – bobmoff

Odpowiedz

15

Właśnie nad tym pracuję nad dzisiejszą grą. Jest więcej negocjacji, które musisz zrobić, aby uzyskać konfigurację kanału komunikacyjnego. Początkowy mecz powracający do zapraszającego czeka na zaproszenie do odpowiedzi ... Oto mój proces z tylko dwoma graczami. Oto wszystkie kroki, jakie wykonuje moja gra komunikacyjna. Oczywiście, nie ma prawdziwych obsługa błędów zawarte tutaj:

Najpierw uwierzytelnić gracz

drugie, zaraz po uwierzytelnieniu ustawiony inviteHandler. Coś takiego:

[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite* acceptedInvite, NSArray *playersToInvite) 
{ 
    if(acceptedInvite != nil) 
    { 
     // Get a match for the invite we obtained... 
     [[GKMatchmaker sharedMatchmaker] matchForInvite:acceptedInvite completionHandler:^(GKMatch *match, NSError *error) 
     { 
      if(match != nil) 
      { 
       [self disconnectMatch]; 
       // Record the new match... 
       self.MM_gameCenterCurrentMatch = match; 
       self.MM_gameCenterCurrentMatch.delegate = self; 
      } 
      else if(error != nil) 
      { 
       NSLog(@"ERROR: From matchForInvite: %@", [error description]); 
      } 
      else 
      { 
       NSLog(@"ERROR: Unexpected return from matchForInvite..."); 
      } 
     }]; 
    } 
}; 

Po trzecie, Uzyskaj listę znajomych playerIds (nie alias).

czwarte Skonfiguruj GKMatchRequest coś takiego ... Ja tylko zaprosić jednego przyjaciela:

// Initialize the match request - Just targeting iOS 6 for now... 
GKMatchRequest* request = [[GKMatchRequest alloc] init]; 
request.minPlayers = 2; 
request.maxPlayers = 2; 
request.playersToInvite = [NSArray arrayWithObject:player.playerID]; 
request.inviteMessage = @"Let's play!"; 
// This gets called when somebody accepts 
request.inviteeResponseHandler = ^(NSString *playerID, GKInviteeResponse response) 
{ 
    if (response == GKInviteeResponseAccepted) 
    { 
     //NSLog(@"DEBUG: Player Accepted: %@", playerID); 
     // Tell the infrastructure we are don matching and will start using the match 
     [[GKMatchmaker sharedMatchmaker] finishMatchmakingForMatch:self.MM_gameCenterCurrentMatch]; 
    } 
}; 

piąte, należy użyć żądania zadzwonić findMatchForRequest: withCompletionHandler: coś takiego ...

[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch* match, NSError *error) { 
    if (error) 
    { 
     NSLog(@"ERROR: Error makeMatch: %@", [error description]); 
     [self disconnectMatch]; 
    } 
    else if (match != nil) 
    { 
     // Record the new match and set me up as the delegate... 
     self.MM_gameCenterCurrentMatch = match; 
     self.MM_gameCenterCurrentMatch.delegate = self; 
     // There will be no players until the players accept... 
    } 
}]; 

Po szóste, wysyła żądanie do drugiego gracza i jeśli akceptuje "inviteHandler" z drugiego kroku zostaje wywołany.

Po siódme, "inviteHandler" z drugiego kroku zostaje dopasowany do GKInvite!

Po ósme, zostaje wywołany "inviteeResponseHandler" z czwartego kroku, który zakończył mecz!

Po dziewiąte, utwórz didChangeState z GKMatchDelegate, aby obsłużyć finalizację dopasowania.Coś takiego:

- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state{ 
switch (state) 
{ 
    case GKPlayerStateConnected: 
     // Handle a new player connection. 
     break; 
    case GKPlayerStateDisconnected: 
     // A player just disconnected. 
     break; 
} 
if (!self.matchStarted && match.expectedPlayerCount == 0) 
{ 
    self.matchStarted = YES; 
    // Handle initial match negotiation. 
    if (self.iAmHost && !self.sentInitialResponse) 
    { 
     self.sentInitialResponse = true; 
     // Send a hello log entry 
     [self sendMessage: [NSString stringWithFormat:@"Message from friend, 'Hello, thanks for accepting, you have connected with %@'", self.MM_gameCenterLocalPlayer.alias] toPlayersInMatch: [NSArray arrayWithObject:playerID]]; 
    } 
}} 

dziesiąte, tu jest mój sendMessage:

- (void) sendMessage:(NSString*)action toPlayersInMatch:(NSArray*) playerIds{ 
NSError* err = nil; 
if (![self.MM_gameCenterCurrentMatch sendData:[action dataUsingEncoding:NSUTF8StringEncoding] toPlayers:playerIds withDataMode:GKMatchSendDataReliable error:&err]) 
{ 
    if (err != nil) 
    { 
     NSLog(@"ERROR: Could not send action to players (%@): %@ (%d) - '%@'" ,[playersInMatch componentsJoinedByString:@","],[err localizedDescription],[err code], action); 
    } 
    else 
    { 
     NSLog(@"ERROR: Could not send action to players (%@): null error - '%@'",[playersInMatch componentsJoinedByString:@","], action); 
    } 
} 
else 
{ 
    NSLog(@"DEBUG: Message sent to players (%@) - '%@'",[playersInMatch componentsJoinedByString:@","], action); 
}} 

Jedenasta utwórz didReceiveData z GKMatchDelegate coś takiego:

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID{ 
NSString* actionString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; 
// Send the initial response after we got the initial send from the 
// invitee... 
if (!self.iAmHost &&!self.sentInitialResponse) 
{ 
    self.sentInitialResponse = true; 
    // Send a hello log entry 
    [self sendMessage: [NSString stringWithFormat:@"Message from friend, 'Hello, thanks for inviting, you have connected with %@'", self.MM_gameCenterLocalPlayer.alias] toPlayersInMatch: [NSArray arrayWithObject:playerID]]; 
} 
// Execute the action we were sent... 
NSLog(actionString);} 

dwunasty ... No teraz mieć uruchomione kanały komunikacji ... rób, co chcesz ...

+0

Dobra odpowiedź !!!!! –

+0

@ GoRose-Hulman Czy mógłbyś zaktualizować swoją odpowiedź na iOS 7? –

+0

Czy wiesz, jak to zrobić w iOS9? Właśnie zadałem podobne pytanie: http://stackoverflow.com/questions/36728503/gkmatchmaker-findmatchforrequest-invite-never-received – mark

Powiązane problemy