我正在尝试使用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然后点击“立即播放”?
Ray Wenderlich's tutorial说我应该选择第二种方式但是当解除警报并点击“立即播放”时,发现发送方设备仍在等待响应并且不知道我已经接受了邀请。如果我此时点击“立即播放”,那么,如上所述,它会显示一条警告,表示应用程序正在等待响应。所以,如果你曾经这样做过,请解释我应该怎么做。谢谢!
答案 0 :(得分:5)
以下是代码:
我在加载游戏后立即注册邀请,并在收到邀请时致电代表:
- (void)registerInvites {
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
self.pendingInvite = acceptedInvite;
self.pendingPlayersToInvite = playersToInvite;
[delegate inviteReceived];
};
}
所以inviteReceived会调用匹配器来解雇游戏中心控制器并创建匹配:
- (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];
}
}
答案 1 :(得分:3)
我已经成功实施了Ray的教程之后的在线游戏中心比赛。您的回答是:您无需向邀请设备发送任何内容。当您调用该行: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:^{
}];
}
}
答案 2 :(得分:1)
inviteHandler = ^(GKInvite * acceptedInvite,NSArray * playersToInvite)现已弃用。请参阅注册邀请通知的新方法。