Search code examples
iosobjective-ccocos2d-iphonegame-centermultiplayer

iPhone Multiplayer Code works, but iPad doesn't. Delegate issue?


I've pretty much wrapped up my multiplayer code for my iPhone app and started working to update the graphics for the iPad version. Much to my surprise after updating all my sprites, my iPad version behaves completely differently than the iPhone. I'm using a combination of some custom code written by a freelance developer and Ray Wenderlich's GCHelper. Up until now, everything has been working great. For the iphone app, my gamelayer sends and receives all the player moves. In the iPad app, the MainMenu scene is receiving the data for some reason.

MainMenu.h

@protocol GCHelperDelegate
- (void)matchStarted;
- (void)matchEnded;
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID;
- (void)inviteReceived;
@end


@interface MainMenu: CCLayer <GCHelperDelegate>
{//some code
}

MainMenu.m

- (void) StartMultiplayerGame  //button calls up gamecenter matchmaking
{
    NSLog(@"***In StartMultiplayerGame***");


    delegate1 = (AppDelegate *) [UIApplication sharedApplication].delegate;
    [[GCHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:4 viewController:delegate1.viewController delegate:self]; 

    boo_multiplayer=true;
    boo_startgame=true;

    colorLayer = [CCLayerColor layerWithColor:ccc4(0, 0, 0, 255)];
    [colorLayer setOpacity:175];
    [self addChild:colorLayer z:2]; 

    return;    
}

GCHelper.h

#import <Foundation/Foundation.h>
#import <GameKit/GameKit.h>
#import "cocos2d.h"
#import "AppDelegate.h"


@protocol GCHelperDelegate
- (void)matchStarted;
- (void)matchEnded;
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID;
- (void)inviteReceived;
@end

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

    bool boo_invite;

    UIViewController *presentingViewController;
    GKMatch *match;
    BOOL matchStarted;
    __strong id <GCHelperDelegate> delegate;
    NSMutableDictionary *playersDict;
    GKInvite *pendingInvite;
    NSArray *pendingPlayersToInvite;

    NSMutableArray *playernames;
    NSMutableArray *playeridentification;

    NSError *lastError;

    GKMatchRequest *request;

   // // AppDelegate *delegate1;


}

@property (assign, readonly) BOOL gameCenterAvailable;
@property (strong) UIViewController *presentingViewController;
@property (strong) GKMatch *match;
@property (strong) id <GCHelperDelegate> delegate;
@property (strong) NSMutableDictionary *playersDict;
@property (strong) GKInvite *pendingInvite;
@property (strong) NSArray *pendingPlayersToInvite;



+ (GCHelper *)sharedInstance;
- (void)authenticateLocalUser;
- (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers viewController:(UIViewController *)viewController delegate:(id<GCHelperDelegate>)theDelegate;

@end

GCHelper.m

- (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers viewController:(UIViewController *)viewController delegate:(id<GCHelperDelegate>)theDelegate
{    
    if (!gameCenterAvailable) return;

    matchStarted = NO;
    self.match = nil;
    self.presentingViewController = viewController;
    delegate = theDelegate;

    if (pendingInvite != nil) {

        [presentingViewController dismissModalViewControllerAnimated:NO];
        GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithInvite:pendingInvite];
        mmvc.matchmakerDelegate = self;
        [presentingViewController presentModalViewController:mmvc animated:YES];

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

    }
    else {

        [presentingViewController dismissModalViewControllerAnimated:NO];
        request=[[GKMatchRequest alloc] init];
        request.minPlayers = minPlayers;
        request.maxPlayers = maxPlayers;
        request.playersToInvite = pendingPlayersToInvite;

        GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithMatchRequest:request];    
        mmvc.matchmakerDelegate = self;

        [presentingViewController presentModalViewController:mmvc animated:YES];

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

    }

}

// A peer-to-peer match has been found, the game should start
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)theMatch {
    [presentingViewController dismissModalViewControllerAnimated:YES];
    self.match = theMatch;
    self.match.delegate = self;
    currentMatch=match;

    if (!matchStarted && match.expectedPlayerCount == 0)
    {
        NSLog(@"Ready to start match!");

        TXGameCenterManager * gameCenterManager = [TXGameCenterManager sharedTXGameCenterManager];
        gameCenterManager.multiplayerMatch = match;
        // The delegate of the match is HelloWorldLayer

        gameCenterManager.multiplayerMatch.delegate = self;
        AppDelegate * delegate1 = (AppDelegate *) [UIApplication sharedApplication].delegate;
        [delegate1.viewController dismissModalViewControllerAnimated:NO];

       [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;
            //[delegate matchEnded];
        }
        else
        {
// some code.  
    [[CCDirector sharedDirector] replaceScene:[HelloWorldLayer node]];
        }

What I REALLY don't understand is that the iPad simulator works just fine. What's going on with my app here and how do I force the didReceiveData method to run in the gamelayer instead of my menu scene?


Solution

  • Such an idiot. The iPad iOS needed to be upgraded to 6.0.