I\'m trying to implement invitations with Game Center and there\'s one thing that i don\'t understand. Ok, i\'ve sent an invitation from one device to another. Then i have a
Here is the code:
I register for invites as soon as the game is loaded and call the delegate when an invite is received:
- (void)registerInvites {
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
self.pendingInvite = acceptedInvite;
self.pendingPlayersToInvite = playersToInvite;
[delegate inviteReceived];
};
}
So inviteReceived calls the match maker for dismissing the game center controller and creating the match:
- (void)inviteReceived {
[[GCMultiplayerHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:2 viewController:(UIViewController*)[self.superview nextResponder] delegate:self];
}
- (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers viewController:(UIViewController *)viewController delegate:(id<GCMultiplayerHelperDelegate>)theDelegate {
if (!gameCenterAvailable) return;
matchStarted = NO;
self.match = nil;
self.presentingViewController = viewController;
delegate = theDelegate;
[presentingViewController dismissModalViewControllerAnimated:YES];
GKMatchmakerViewController *mmvc;
if (pendingInvite != nil) {
mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:pendingInvite] autorelease];
} else {
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
request.minPlayers = minPlayers;
request.maxPlayers = maxPlayers;
request.playersToInvite = pendingPlayersToInvite;
mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
}
mmvc.matchmakerDelegate = self;
[presentingViewController presentModalViewController:mmvc animated:YES];
self.pendingInvite = nil;
self.pendingPlayersToInvite = nil;
}
And finally, when the match is been found, the method connectionStatusChanged takes care of presenting all the game's views, players and starting the match:
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)theMatch
{
self.match = theMatch;
match.delegate = self;
if (!matchStarted && match.expectedPlayerCount == 0) {
NSLog(@"Ready to start match! - didFindMatch");
[presentingViewController dismissModalViewControllerAnimated:YES];
[self.delegate connectionStatusChanged:CONNECTIONSUCCESS];
}
}
I've successfully implemented an online game center match following Ray's tutorials. The answer to you question is: You don't have to send anything to the inviting device. When you call the line:GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
, the matchMakerVController handles the connection . However, you should write an invitation handler ASAP, preferably in the authentication changed method. See mine:
-(void) authenticationChanged {
if ([GKLocalPlayer localPlayer].isAuthenticated && !userAuthenticated) {
NSLog(@"Authentication changed: player authenticated.");
userAuthenticated = TRUE;
[self sendUnsentScores];
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite){
NSLog(@"Invite");
if([AppDelegate mainMenuController].presentedViewController!=nil) {
[[AppDelegate mainMenuController] dismissViewControllerAnimated:NO completion:^{
}];
} // if we're not on the main menu, or another game is going on.
// this would be easier to do if you were using a navigation controller
// where you'd just push the multiplayer menu etc.
self.pendingInvite = acceptedInvite;
self.pendingPlayersToInvite = playersToInvite;
[[AppDelegate mainMenuController] presentViewController:[AppDelegate mainMenuController].multiGameMenu animated:NO completion:^{ // push the multiplayer menu
[[AppDelegate mainMenuController].multiGameMenu duel:nil];
}];
};
}
and here is the duel method if you're interested. Very messy code but deal with it :)
- (IBAction)duel:(id)sender {
NSLog(@"duel");
if (presentingMenu.multiGameController==nil || presentingMenu.multiGame.gameInProgress==NO) {
presentingMenu.multiGame=nil;
presentingMenu.multiGameController=nil;
MultiViewController *mvc = [[MultiViewController alloc] init]; //create game VC
presentingMenu.multiGameController = mvc; //presenting menu is just the main menu VC
// it holds this menu, and the game
// objects.
}
if (presentingMenu.multiGame == nil) {
presentingMenu.multiGame = [[MultiGame alloc] // similarly create the game object
initWithViewController:presentingMenu.multiGameController];
//they both have pointers to each other (A loose, bad MVC).
presentingMenu.multiGameController.game = presentingMenu.multiGame;
[presentingMenu.multiGame startGame];
}
if (presentingMenu.multiGameController.gameState==0) { //new game
presentingMenu.multiGameController.game = presentingMenu.multiGame;
[[GCHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:2 viewController:self delegate:presentingMenu.multiGame]; // the GC magic happens here - it know about the invite.
} else {
[self presentViewController:presentingMenu.multiGameController animated:YES completion:^{
}];
}
}
inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) is deprecated now. See the new way to register for invite notifications.
GKMatchMaker invite handler deprecated