Как принять приглашение в Game Center
Я пытаюсь реализовать приглашения с Game Center, и есть одна вещь, которую я не понимаю. Хорошо, я отправил приглашение с одного устройства на другое. Затем у меня есть UIAlertView на приемнике, который просит меня принять или отклонить приглашение. когда я принимаю его, он обрабатывается следующим образом:
[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;
[presentingViewController presentModalViewController:mmvc animated:YES];
}
else if (playersToInvite)
{
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
request.minPlayers = 2;
request.maxPlayers = 4;
request.playersToInvite = playersToInvite;
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
mmvc.matchmakerDelegate = self;
[presentingViewController presentModalViewController:mmvc animated:YES];
}
};
Ну, это здорово, но что дальше? устройство отправителя, очевидно, ждет какого-то стандартного типа ответа, потому что оно также показывает предупреждение, сообщающее мне, что есть некоторые приглашения, на которые еще не ответили, если я нажму "играть сейчас".
Итак, как я могу принять приглашение? Какие данные (и как) я должен отправить обратно? И что именно я должен делать со стороны приемника? Должна ли игра начинаться сразу после нажатия " принять "или я должен сначала закрыть AlertView, а затем нажать"Играть сейчас"?
Рэй Вендерлих это говорит, что я должен выбрать второй способ, но когда отклонить предупреждение и нажмите "Играть сейчас", оказывается, отправитель устройство все еще ждет ответа и не знает, что я уже принял приглашение. если я нажму "играть сейчас" в этот момент, то, как я сказал выше, он показывает предупреждение, которое говорит, что приложение ждет ответа. Так что если вы когда-нибудь делали это, пожалуйста, объясните мне, что я должен делать. Спасибо!
3 ответов
- я регистрируюсь для инвайтов, как только игра загружается и вызываю делегировать при получении приглашения
- так inviteReceived называет матч мейкера для увольнения игры центральный контроллер и создание матча
- и, наконец, когда соответствие найдено, метод connectionStatusChanged заботится о том, чтобы представить все игры просмотры, игроки и прочее
вот код:
я регистрируюсь для приглашений как как только игра будет загружена и позвоните делегату, когда будет получено приглашение:
- (void)registerInvites {
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
self.pendingInvite = acceptedInvite;
self.pendingPlayersToInvite = playersToInvite;
[delegate inviteReceived];
};
}
таким образом, inviteReceived вызывает match maker для увольнения контроллера game center и создания матча:
- (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;
}
и, наконец, когда матч был найден, метод connectionStatusChanged заботится о представлении всех взглядов игры, игроков и начале матча:
- (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];
}
}
я успешно реализовал онлайн-матч game center после учебных пособий Рэя. Ответ на ваш вопрос: вам не нужно ничего отправлять на приглашающее устройство. При вызове строки:GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
, matchMakerVController обрабатывает соединение . Однако вы должны написать обработчик приглашений как можно скорее, предпочтительно в методе проверки подлинности. Смотрите мой:
-(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];
}];
};
}
и вот метод дуэли, если вам интересно. Очень грязный код, но разберитесь с ним :)
- (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) устарел. См. новый способ регистрации уведомлений о приглашениях.