2013-03-25 3 views
7

맞춤 UI (GKMatchMakerViewController 없음)를 사용하여 실시간 멀티 플레이어 게임을 구현하려고합니다. startBrowsingForNearbyPlayersWithReachableHandler :^(NSString * playerID, BOOL 도달 가능)를 사용하여 로컬 플레이어를 찾은 다음 GKMatchmaker 싱글 톤 (이미 시작한)으로 일치 요청을 시작합니다.iOS Game Center GameKit 프로그램 방식의 초청 중매

여기 내가 문제가있는 곳입니다. 요청을 보내면 완료 처리기가 오류없이 거의 즉시 시작되고 반환되는 일치 항목의 예상 플레이어 수는 0입니다. 한편, 다른 플레이어는 확실히 요청에 응답하지 않은

관련 코드 :

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

에 : 나는 이것을 포함 할 필요가 이전 질문 (iOS Gamecenter Programmatic Matchmaking)에서 알 수

- (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]; 
     } 
    }]; 
} 

위의 코드는 포함되어 있어야하는 곳을 모르겠다. 나는 GKMatchRequest inviteeResponseHandler와 중매인 finMatchForRequest : withCompletionHandler 둘 다 시도해 보았다. 문제는 일치하는 사람이 즉시 (초대받은 사람이 초대되기 전에도) 일치를 반환하고 초대 된 사람이 일치하는 초대를 탭한 후에도 matchRequest inviteeResponseHandler가 호출되지 않는다는 것입니다.

누군가가 이에 대한 조언을 제공 할 수 있습니까? 고맙습니다.

... 짐

+0

어떻게 startBrowsingForNearbyPla를 얻었습니까? yersWithReachableHandler가 작동합니까? 나는 그것으로부터 어떤 콜백도 결코 얻지 않는다? – bobmoff

답변

15

난 그냥이 내 게임에 작업을 오늘 밤 얻었다. 통신 채널 설정을 얻으려면 더 많은 협상이 필요합니다. 초대 자에게 반환 된 초기 경기는 피초청자가 응답하기를 기다리고 있습니다 ... 여기에는 두 명의 플레이어 만있는 내 과정이 있습니다. 여기 내 커뮤니케이션 스핀 업이 수행하는 모든 단계가 있습니다. 물론, 실제 오류 처리는 여기에 포함되지 :

첫째, 권리 inviteHandler 설정 인증 후, 플레이어

두 번째를 인증합니다. 다음과 같이 입력하십시오 :

[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..."); 
      } 
     }]; 
    } 
}; 

세 번째로 친구 별명 (별칭)을 가져 오십시오.

// 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]; 
    } 
}; 

다섯째, findMatchForRequest 전화 요청을 사용 : withCompletionHandler이 같은 ...

[[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... 
    } 
}]; 

넷째, 설정이처럼 GKMatchRequest 뭔가 ... 나는 단 하나의 친구를 초대하고

여섯째,이 요청을 다른 플레이어에게 보내고 두 번째 단계의 "inviteHandler"가 수락되면 받아들입니다.

일곱 번째로, 두 번째 단계의 "inviteHandler"가 GKInvite!

8 번째 단계 인 "inviteeResponseHandler"가 호출되면서 일치가 완료됩니다.

아홉째, GKMatchDelegate에서 didChangeState를 작성하여 일치 항목의 처리를 처리하십시오.이런 식으로 뭔가 :

- (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); 
}} 

11,이 같은 didReceiveData GKMatchDelegate에서 무언가 만들 :

- (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]]; 
    } 
}} 

열 번째, 여기에 내 sendMessage 첨부입니다 글쎄 지금은 ...

- (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);} 

열두 번째를 당신 통신 채널을 가동시키고 ... 원하는대로하십시오 ...

+0

좋은 답변 !!!!! –

+0

@ GoRose-Hulman은 iOS 7에 대한 답변을 업데이트 할 수 있습니까? –

+0

iOS9에서 올바른 방법을 알고 있습니까? 방금 비슷한 질문을했습니다. http://stackoverflow.com/questions/36728503/gkmatchmaker-findmatchforrequest-invite-never-received – mark