Search code examples
cocos2d-xmultiplayer

How can I make an online 2 player game in Cocos2d X?


I've made a platform game like Megaman and want people to be able to connect with eachother to play it together. It must work on Android and Iphone. I'm using Cocos2d X so it's hard to find good information that's not using deprecated or removed methods/objects.

What would be a simple way and get enough fps to make it look good?

edit: It sucks that people just vote down this question, cause I really don't know how to specify it better. I dont know how to get started with this. Thanks for voting down guys! :S


Solution

  • with help of apple game center you can implement multiplayer very early.
    
    for example
    
    #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;
    
    ///////////
    
    
    
    #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();
        }
    
    }