2012-05-23 1 views
0

Je travaille actuellement sur Game Center Multiplayer et j'ai rencontré quelques obstacles. Actuellement, le code que j'ai ci-dessous va authentifier l'utilisateur afficher la vue matchmaker et commencer un match très bien. Cependant quand j'essaye d'inviter un ami pour un match, la vue d'alerte demandant de jouer le match montre quand j'accepte cela m'amène au contrôleur de matchmaking et dit qu'il attend l'autre joueur sur mon autre appareil il dit aussi qu'il attend pour que l'autre joueur réponde. Finalement, après un certain temps, l'invitation a été annulée. Je n'utilise pas le simulateur. J'ai 2 appareils avec des profils de centre de jeu séparés. L'un est IOS 4.2 et l'autre est IOS 4.3. Je n'ai aucune idée de ce qui pourrait être faux. Tout mon code multijoueur est ci-dessous. Aussi pour l'envoi de données à l'un ou l'autre des appareils, j'aimerais savoir un bon site pour en savoir plus à ce sujet. Im excité de voir ce que vous pouvez tous venir avec. MerciXcode - Game Center - Invitation multijoueur non acceptée

ViewController.h

#import <Foundation/Foundation.h> 
#import <GameKit/GameKit.h> 

@protocol GCHelperDelegate 
- (void)matchStarted; 
- (void)matchEnded; 
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID; 
- (void)inviteReceived; 
@end 

@interface ViewController : UIViewController <GKMatchmakerViewControllerDelegate, GKMatchDelegate, GCHelperDelegate, GameCenterManagerDelegate> { 
BOOL gameCenterAvailable; 
BOOL userAuthenticated; 

UIViewController *presentingViewController; 
GKMatch *match; 
BOOL matchStarted; 
id <GCHelperDelegate> delegate; 
NSMutableDictionary *playersDict; 
GKInvite *pendingInvite; 
NSArray *pendingPlayersToInvite; 

} 

@property (assign, readonly) BOOL gameCenterAvailable; 
@property (retain) GKMatch *match; 
@property (assign) id <GCHelperDelegate> delegate; 
@property (retain) NSMutableDictionary *playersDict; 
@property (retain) GKInvite *pendingInvite; 
@property (retain) NSArray *pendingPlayersToInvite; 

- (void)authenticateLocalUser; 
- (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers viewController:(UIViewController *)viewController delegate:(id<GCHelperDelegate>)theDelegate; 

@end 

et la vue Controller.m

//ViewController.m Multyplayer 


#pragma mark Initialization 

- (BOOL)isGameCenterAvailable { 
// check for presence of GKLocalPlayer API 
Class gcClass = (NSClassFromString(@"GKLocalPlayer")); 

// check if the device is running iOS 4.1 or later 
NSString *reqSysVer = @"4.1"; 
NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; 
BOOL osVersionSupported = ([currSysVer compare:reqSysVer 
             options:NSNumericSearch] != NSOrderedAscending); 

return (gcClass && osVersionSupported); 
} 

- (id)init { 
if ((self = [super init])) { 
    gameCenterAvailable = [self isGameCenterAvailable]; 
    if (gameCenterAvailable) { 
     NSNotificationCenter *nc = 
     [NSNotificationCenter defaultCenter]; 
     [nc addObserver:self 
       selector:@selector(authenticationChanged) 
        name:GKPlayerAuthenticationDidChangeNotificationName 
       object:nil]; 
    } 
} 
return self; 
} 

#pragma mark Internal functions 

- (void)authenticationChanged {  


if ([GKLocalPlayer localPlayer].isAuthenticated && !userAuthenticated) { 
    NSLog(@"Authentication changed: player authenticated."); 
    userAuthenticated = TRUE; 

    [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) { 

     NSLog(@"Received invite"); 
     self.pendingInvite = acceptedInvite; 
     self.pendingPlayersToInvite = playersToInvite; 
     [delegate inviteReceived]; 

    }; 

} else if (![GKLocalPlayer localPlayer].isAuthenticated && userAuthenticated) { 
    NSLog(@"Authentication changed: player not authenticated"); 
    userAuthenticated = FALSE; 
} 

    } 

- (void)lookupPlayers { 

NSLog(@"Looking up %d players...", match.playerIDs.count); 
[GKPlayer loadPlayersForIdentifiers:match.playerIDs withCompletionHandler:^(NSArray *players, NSError *error) { 

    if (error != nil) { 
     NSLog(@"Error retrieving player info: %@", error.localizedDescription); 
     matchStarted = NO; 
     [delegate matchEnded]; 
    } else { 

     // Populate players dict 
     self.playersDict = [NSMutableDictionary dictionaryWithCapacity:players.count]; 
     for (GKPlayer *player in players) { 
      NSLog(@"Found player: %@", player.alias); 
      [playersDict setObject:player forKey:player.playerID]; 
     } 

     // Notify delegate match can begin 
     matchStarted = YES; 
     [delegate matchStarted]; 

    } 
}]; 

} 

#pragma mark User functions 

- (void)authenticateLocalUser { 

if (!gameCenterAvailable) return; 

NSLog(@"Authenticating local user..."); 
if ([GKLocalPlayer localPlayer].authenticated == NO) {  
    [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:nil];   
} else { 
    NSLog(@"Already authenticated!"); 
} 
} 


- (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers viewController:(UIViewController *)viewController delegate:(id<GCHelperDelegate>)theDelegate { 

if (!gameCenterAvailable) return; 

matchStarted = NO; 
self.match = nil; 
self.presentingViewController = viewController; 
delegate = theDelegate; 

if (pendingInvite != nil) { 

    GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:pendingInvite] autorelease]; 
    mmvc.matchmakerDelegate = self; 
    [self presentModalViewController:mmvc animated:YES]; 

    self.pendingInvite = nil; 
    self.pendingPlayersToInvite = nil; 

} else { 

    GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease]; 
    request.minPlayers = minPlayers;  
    request.maxPlayers = maxPlayers; 
    request.playersToInvite = pendingPlayersToInvite; 

    GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];  
    mmvc.matchmakerDelegate = self; 

    [self presentModalViewController:mmvc animated:YES]; 

    self.pendingInvite = nil; 
    self.pendingPlayersToInvite = nil; 

} 
}   

#pragma mark GKMatchmakerViewControllerDelegate 

// The user has cancelled matchmaking 
- (void)matchmakerViewControllerWasCancelled:(GKMatchmakerViewController *)viewController { 
[self dismissModalViewControllerAnimated:YES]; 
} 

// Matchmaking has failed with an error 
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFailWithError:(NSError *)error { 
[self dismissModalViewControllerAnimated:YES]; 
NSLog(@"Error finding match: %@", error.localizedDescription);  
} 

// A peer-to-peer match has been found, the game should start 
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)theMatch { 
[self dismissModalViewControllerAnimated:YES]; 
self.match = theMatch; 
match.delegate = self; 
if (!matchStarted && match.expectedPlayerCount == 0) { 
    NSLog(@"Ready to start match!"); 
    [self lookupPlayers]; 
} 
} 

#pragma mark GKMatchDelegate 

// The match received data sent from the player. 
- (void)match:(GKMatch *)theMatch didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID { 

if (match != theMatch) return; 

[delegate match:theMatch didReceiveData:data fromPlayer:playerID]; 
} 

// The player state changed (eg. connected or disconnected) 
- (void)match:(GKMatch *)theMatch player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state { 

if (match != theMatch) return; 

switch (state) { 
    case GKPlayerStateConnected: 
     // handle a new player connection. 
     NSLog(@"Player connected!"); 

     if (!matchStarted && theMatch.expectedPlayerCount == 0) { 
      NSLog(@"Ready to start match!"); 
      [self lookupPlayers]; 
     } 

     break; 
    case GKPlayerStateDisconnected: 
     // a player just disconnected. 
     NSLog(@"Player disconnected!"); 
     matchStarted = NO; 
     [delegate matchEnded]; 
     break; 
}     

} 

// The match was unable to connect with the player due to an error. 
- (void)match:(GKMatch *)theMatch connectionWithPlayerFailed:(NSString *)playerID withError:(NSError *)error { 

if (match != theMatch) return; 

NSLog(@"Failed to connect to player with error: %@", error.localizedDescription); 
matchStarted = NO; 
[delegate matchEnded]; 
} 

// The match was unable to be established with any players due to an error. 
- (void)match:(GKMatch *)theMatch didFailWithError:(NSError *)error { 

if (match != theMatch) return; 

NSLog(@"Match failed with error: %@", error.localizedDescription); 
matchStarted = NO; 
[delegate matchEnded]; 
} 
-(IBAction)findMatch{ 
    // if (![GameCenterManager isGameCenterAvailable]) return; 

matchStarted = NO; 
self.match = nil; 

GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease]; 
request.minPlayers = 2;  
request.maxPlayers = 2; 

GKMatchmakerViewController *mmvc = 
[[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];  
mmvc.matchmakerDelegate = self; 

[self presentModalViewController:mmvc animated:YES]; 
} 

#pragma mark - View lifecycle 


- (void)viewDidLoad{ 

self.currentLeaderBoard = kLeaderboardID; 

if ([GameCenterManager isGameCenterAvailable]) { 

    self.gameCenterManager = [[[GameCenterManager alloc] init] autorelease]; 
    [self.gameCenterManager setDelegate:self]; 
    [self.gameCenterManager authenticateLocalUser]; 

    [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) { 
     // Insert application-specific code here to clean up any games in progress. 
     if (acceptedInvite) 
     { 
      GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease]; 
      mmvc.matchmakerDelegate = self; 
      [self presentModalViewController:mmvc animated:YES]; 

     } 
     else if (playersToInvite) 
     { 
      GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease]; 
      request.minPlayers = 2; 
      request.maxPlayers = 2; 
      request.playersToInvite = playersToInvite; 

      GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease]; 
      mmvc.matchmakerDelegate = self; 
      [self presentModalViewController:mmvc animated:YES]; 
     } 
    }; 

}else { 

    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Game Center Disabled"message:@"For Game Center make sure you have an account and you have a proper device connection."delegate:self cancelButtonTitle:@"Ok"otherButtonTitles:nil]; 
    [alert show]; 

} 
} 

Répondre

0

Est-ce que le NSLog: reçu est imprimé invitent dans la console lorsque vous acceptez une invitation? La méthode [delegate inviteAccepted] devrait gérer ce qui se passe lorsqu'un joueur accepte une invitation. Cela peut devenir assez fastidieux car vous ne savez pas quelle vue est actuellement affichée. Vous devriez trouver en quelque sorte à ce sujet, pousser la vue. Ensuite, à partir de cette vue, l'application doit présenter le viewMontroller matchMaker. Mon bloc d'invitation ressemble à ceci:

[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite){ 

     NSLog(@"Invite"); 

     if([AppDelegate mainMenuController].presentedViewController!=nil) { 
      [[AppDelegate mainMenuController] dismissViewControllerAnimated:NO completion:^{ 

      }]; 
     } 

     self.pendingInvite = acceptedInvite; 
     self.pendingPlayersToInvite = playersToInvite; 

     [[AppDelegate mainMenuController] presentViewController:[AppDelegate mainMenuController].multiGameMenu animated:NO completion:^{ 

      [[AppDelegate mainMenuController].multiGameMenu duel:nil]; 
     }]; 

    }; 

Où multiGameMenu est juste un menu et la méthode de duel ne fait que créer une instance de jeu et appelle findMatchWithMaxPlayers: int minplayers: méthode int. Faites-moi savoir comment ça se passe !!

+0

Invite Received est imprimé sur le NSLog. –

+0

Cela signifie que le gestionnaire est effectivement appelé, vous ne le manipulez pas correctement –

+0

J'ai eu beaucoup de problèmes à pousser une vue différente pour le Matchmaker ViewController je reçois constamment une erreur sigbart est là où vous pourriez suggérer que je pourrais peut-être en savoir plus sur le fait de pousser une vue à un contrôleur de vue supplémentaire? Comment faites-vous? Je suis désolé, je suis nouveau au centre de jeu. –

0

Essayez d'utiliser:

- (void)matchmakerViewController:(GKMatchmakerViewController *) viewController 
    didReceiveAcceptFromHostedPlayer:(NSString *)playerID 
{ 
    [viewController setHostedPlayer:playerID connected:YES]; 
} 

J'espère que ça aide!