ios - 游戏中心整合与程序设计

标签 ios game-center

我是 iOS 的新手,所以请原谅一个对你们大多数人来说似乎显而易见的问题。

我读过 Game Center Programming Guide 但我对 View Controller 之间的流程感到困惑。

以上面链接中的图 1-2 为例,我可以看到 Credits View 、Authentication View 等将是模态的。我无法理解的是 View 循环:Main Menu > Configure Game Play > Matchmaking > Configure Game Play > Game Play > Game End > Main Menu

在这种情况下,什么会被视为根 Controller ?它是什么类型的 Controller ?您将使用什么 segue 转到下一个 View ,以及一旦您深入多个 View ,您将如何导航回主菜单?这种情况的典型设计是什么?

最佳答案

这是多人游戏的代码。所有 Game center View 都由 Game Center 管理。 添加此代码后,您只需为多人游戏添加以下代码。当您单击“游戏”按钮时,您将调用此助手类,您可以访问此链接了解更多详细信息 [ http://www.raywenderlich.com/3276/how-to-make-a-simple-multiplayer-game-with-game-center-tutorial-part-12 ]

AppController * delegate = (AppController *) [UIApplication sharedApplication].delegate;
    [[GCHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:2 viewController:delegate.viewController];
    pimple_->ourRandom = arc4random();
    setGameState(kGameStateWaitingForMatch);



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

@interface GCHelper : NSObject<GKMatchmakerViewControllerDelegate, GKMatchDelegate>
{
    BOOL isUserAuthenticated;

    UIViewController *presentingViewController;
    GKMatch *match;
    BOOL matchStarted;

    GKInvite *pendingInvite;
    NSArray *pendingPlayersToInvite;
    NSMutableDictionary *playersDict;

    NSString *MultiplayerID;
    NSData *MultiData;
    NSString *otherPlayerID;

    char AlertMessageBoxNo;

    BOOL isDataRecieved;
}

//variables

@property (assign, readonly) BOOL gameCenterAvailable;
@property (retain) UIViewController *presentingViewController;
@property (retain) GKMatch *match;
@property (retain) GKInvite *pendingInvite;
@property (retain) NSArray *pendingPlayersToInvite;
@property (retain) NSMutableDictionary *playersDict;

@property (retain) NSString *MultiplayerID;
@property (retain) NSData *MultiData;

-(NSString*)getOtherPlayerId;
-(void)setOtherPlayerId;
//Functions
+ (GCHelper *)sharedInstance;
-(BOOL)isGameCenterAvailable;
-(void)authenticationChanged;
-(void)authenticateLocalUser;

-(void)gameOver:(NSString*)message;

-(void)setDataRecieved:(BOOL)d;
-(BOOL)getDataRecieved;


- (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers viewController:(UIViewController *)viewController;

@end


///////

#import "GCHelper.h"
#import "IPadSharebleClass.h"


@implementation GCHelper

@synthesize gameCenterAvailable;
@synthesize presentingViewController;
@synthesize match;
@synthesize pendingInvite;
@synthesize pendingPlayersToInvite;
@synthesize playersDict;
@synthesize MultiData;
@synthesize MultiplayerID;

static GCHelper *sharedHelper = nil;

+(GCHelper *) sharedInstance
{
    if (!sharedHelper)
    {
        sharedHelper = [[GCHelper alloc] init];
    }
    return sharedHelper;
}


- (BOOL)isGameCenterAvailable
{
    Class gcClass = (NSClassFromString(@"GKLocalPlayer"));
    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];
        }
        else
        {
            UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Game Center Not Available" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alert show];
            [alert release];
        }
    }
    return self;
}

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

        [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite)
        {
            NSLog(@"Received invite");
            self.pendingInvite = acceptedInvite;
            self.pendingPlayersToInvite = playersToInvite;
            IPadCallAnyWhereF.inviteReceived();
        };

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


}

- (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
{
    if (!gameCenterAvailable) return;

    matchStarted = NO;
    self.match = nil;
    self.presentingViewController = viewController;
    if (pendingInvite != nil)
    {
        [presentingViewController dismissModalViewControllerAnimated:NO];
        GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:pendingInvite] autorelease];
        mmvc.matchmakerDelegate = self;
        [presentingViewController presentModalViewController:mmvc animated:YES];

        self.pendingInvite = nil;
        self.pendingPlayersToInvite = nil;
    }
    else
    {
        [presentingViewController dismissModalViewControllerAnimated:NO];
        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;

        [presentingViewController presentModalViewController:mmvc animated:YES];

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

    }

}


#pragma mark GKMatchmakerViewControllerDelegate
- (void)matchmakerViewControllerWasCancelled:(GKMatchmakerViewController *)viewController
{
    [presentingViewController dismissModalViewControllerAnimated:YES];

    UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Game Cancel By you" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
    [alert show];
    [alert release];
    AlertMessageBoxNo='E';
}

- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFailWithError:(NSError *)error
{
    [presentingViewController dismissModalViewControllerAnimated:YES];
    NSLog(@"Error finding match: %@", error.localizedDescription);
    UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Connection Time out" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
    [alert show];
    [alert release];
    AlertMessageBoxNo='A';
}


- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)theMatch
{
    [presentingViewController dismissModalViewControllerAnimated:YES];
    self.match = theMatch;
    match.delegate = self;
    if (!matchStarted && match.expectedPlayerCount == 0)
    {
        NSLog(@"***************Ready to start match!**************");
        [self lookupPlayers];
    }
}

- (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;
             //IPadCallAnyWhereF.matchEnded();
             UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Error retrieving player info" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
             [alert show];
             [alert release];
             AlertMessageBoxNo='F';
         }
         else
         {
             self.playersDict = [NSMutableDictionary dictionaryWithCapacity:players.count];
             for (GKPlayer *player in players)
             {
                 NSLog(@"Found player: %@", player.alias);
                 [playersDict setObject:player forKey:player.playerID];
             }
             NSLog(@"Total Number of Players : %d",players.count);
             matchStarted = YES;
             IPadCallAnyWhereF.matchStarted();
         }
     }];

}

#pragma mark GKMatchDelegate
- (void)match:(GKMatch *)theMatch didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
    if (match != theMatch) return;

    MultiData=data;
    MultiplayerID=playerID;
    if(otherPlayerID==nil)
    {
        otherPlayerID=[playerID retain];
    }
    IPadCallAnyWhereF.match();
}

-(void)setDataRecieved:(BOOL)d
{
    isDataRecieved=d;
}
-(BOOL)getDataRecieved
{
    return isDataRecieved;
}


-(NSString*)getOtherPlayerId
{
    return otherPlayerID;
}

-(void)setOtherPlayerId
{
    otherPlayerID=nil;
}

- (void)match:(GKMatch *)theMatch player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state
{
    if (match != theMatch) return;
    switch (state)
    {
        case GKPlayerStateConnected:
            NSLog(@"New Player connected!");
            if (!matchStarted && theMatch.expectedPlayerCount == 0)
            {
                NSLog(@"&&&&&&&&&& Ready to start match in the match!");
                [self lookupPlayers];
            }
            break;
        case GKPlayerStateDisconnected:
            NSLog(@"--------Player disconnected!--------");
            matchStarted = NO;
            UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Player Disconnected" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
            [alert show];
            [alert release];
            AlertMessageBoxNo='B';
            //IPadCallAnyWhereF.matchDisconnect();
            break;
    }
}

- (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;
    //IPadCallAnyWhereF.matchEnded();
    UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Failed to connect to player" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
    [alert show];
    [alert release];
    AlertMessageBoxNo='C';

}

- (void)match:(GKMatch *)theMatch didFailWithError:(NSError *)error
{
    if (match != theMatch) return;

    NSLog(@"Match failed with error: %@", error.localizedDescription);
    matchStarted = NO;
    //IPadCallAnyWhereF.matchEnded();
    UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Match failed" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
    [alert show];
    [alert release];
    AlertMessageBoxNo='D';

}

-(void)gameOver:(NSString*)message
{
    UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:message delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
    [alert show];
    [alert release];
    AlertMessageBoxNo='G';
}

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSString *title = [alertView buttonTitleAtIndex:buttonIndex];

    if([title isEqualToString:@"Try Again"])
    {
        IPadCallAnyWhereF.matchDisconnect();
    }
    else if([title isEqualToString:@"Main Menu"])
    {
        IPadCallAnyWhereF.gotoMainMenu();
    }

}



@end

谢谢

关于ios - 游戏中心整合与程序设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13938363/

相关文章:

iphone - iOS开发: Does automatch always timeout around five minutes of waiting?

ios - 匹配排名或类似的对手

ios - 从 JSON 数据 Swift 4 创建 TableView 部分

ios - 单击 UITableView 中的标签时,tableview 单元格中的 IndexPath 返回错误

ios - 在 Xcode 8 上出现 "SpringBoard was unable to service the request"错误

ios - Game Center 登录对话框在第一次取消后不再显示 (iOS7)

iphone - 通过游戏中心共享保存的游戏数据?

ios - Game Center 与 Sprite Kit 的集成?

ios - 仅在 Swift 4.2 中上传包含多部分表单数据的图像

ios - Error Domain=NSURLErrorDomain Code=-1003 “找不到具有指定主机名的服务器