0

私は iOS を初めて使用するので、ほとんどの人にとって明白に思えるかもしれない質問を許してください。

Game Center プログラミング ガイドを読みましたが、 View Controller 間のフローについて混乱しています。

Using figure 1-2 in the above link as an example, I can see that the Credits view, Authentication view, etc will be modal. What I can't get my head around is the loop of views: Main Menu > Configure Game Play > Matchmaking > Configure Game Play > Game Play > Game End > Main Menu.

In this scenario, What would be considered the root controller? What type of controller would it be? What segue would you use to go to the next view and how would you navigate back to the Main Menu once you are several views deep? What would be a typical design for this scenario?

4

1 に答える 1

3

これはマルチプレイヤー用のコードです。Game Center のすべてのビューは Game Center によって管理されます。このコードを追加した後、マルチプレイヤー用に次のコードを追加するだけです。ゲーム ボタンをクリックすると、このヘルパー クラスが呼び出されます。詳細については、このリンクにアクセスしてください [ http://www.raywenderlich.com/3276/how-to-make-a-simple-multiplayer-game-with-ゲーム センター チュートリアル パート 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

ありがとう

于 2012-12-20T06:52:09.477 に答える