Home Tutorials Download Beta Store Forum Documentation KnowledgeBase Wiki Blog

ShiVa3D

Return to Code Snippets

Game Center integrated!

Paste down any little snippets or request a new one.

Game Center integrated!

Postby vklymenko » 18 Feb 2011, 14:48

Hi all! I was looking for GameCenter integration samples on forum, but hadn't success on it, so as far I got it working, I'll share for others. Special thanks for DaveYoung, Chris, Dell and all who is spending time on irc chatt ; )


Game Center is Apple's scores/achivs handling system, which is integrated into almost all games on iphone/ipad. Sure there are other features that GC has, but in most cases we need login, submitting scores, achievements, viewing leaderboards pages etc, so lets do it.

First of all I will describe the way I've integrated it. There are few ways like plugins, compiling lua to c++ etc, but I did in way lua+ObjC+engine-wrapper. So you can call GameCenter's stuff directly from lua and with some changes of xCode project's files you will have it working on your iOS device.

Im doing everything in Main AI of my game, but sure you can do it anywhere in your lua scripts. So we have onInit() function of our game, where everything starting.

I've added there
Code: Select all
user.postEvent ( application.getCurrentUser ( ),0,"MainAI","onInitGameCenter" )

and created empty handler onInitGameCenter (NOT FUNCTION, only handlers can works)

Now we need to catch this call in ObjC/Cpp code, so once we created xCode proj, we are going to S3DEngine_Wrapper.cpp and searching there extern "C" bool S3DEngine_iPhone_LoadPack
adding:
Code: Select all
   S3DClient_InstallCurrentUserEventHook   ( "MainAI", "onInitGameCenter",  GameCenterSetInitCallback, NULL ) ;

and before this function we're declaring the func:
Code: Select all
void GameCenterSetInitCallback ( unsigned char _iArgumentCount, const void *_pArguments, void *_pUserData )
{
   bGameCenterWantInit = true;
}


we need to make a link between wrapper and ObjC code thats why we will use the boolen variable, later we will handle this boolen to show/close GameCenter stuff etc.
sure we need declare this variable, so we are going to start of the file and adding
Code: Select all
static bool bGameCenterWantInit = false;

to the list of variables you see there

Also we need 2 functions to read and handle this boolen from ObjC code, so at the end of this file (before AdMob integrations) we are adding:

Code: Select all
extern "C" bool S3DEngine_GameCenter_WantInit ( )
{
    return bGameCenterWantInit ;
}

extern "C" void S3DEngine_GameCenter_SetWantInitFalse ( )
{
    bGameCenterWantInit = false;
}


and in S3DEngine_Wrapper.h
we're adding
Code: Select all
extern bool         S3DEngine_GameCenter_WantInit               ( );
extern void         S3DEngine_GameCenter_SetWantInitFalse         ( );


now we need to call something from it from ObjC code because only ObjC part can handle delegates, so we will be able to have controls on UIViews etc.

we're going to S3DEngine_EAGLView.h
and adding
Code: Select all
#import <GameKit/GameKit.h>
at top

now open S3DEngine_EAGLView.m
and searching function - (void)drawView
this function is calling every time on new frame. As far we have boolens we can do something just "once", like call GameCenter login. In lua scripts I believe you can handle have you called GameCenter login already to prevent multiply initializations. We will also implement callbacks to scripts, so from lua we will handle everything and will know have we logged into GameCenter or is GameCenter already initialized etc.
so in this function just after ad-mob checks we're adding

Code: Select all
         if ( S3DEngine_GameCenter_WantInit ( ) )
         {
            S3DEngine_GameCenter_SetWantInitFalse();
            [self authenticateLocalPlayer];           
         }

as you see we will call GameCenter and will change boolen to false to prevent few calls. Now probably you're curious what is "authenticateLocalPlayer" ? : ) that is the start of our ObjC code, so lets code it also:

in the same S3DEngine_EAGLView.m file we're searching

-(void)showVirtualKeyboard

and adding stuff just before this

Code: Select all
//-----------------
// GAME CENTER


BOOL isGameCenterAvailable()
{
    // Check for presence of GKLocalPlayer API.   
    Class gcClass = (NSClassFromString(@"GKLocalPlayer"));   
   
    // The device must be running running iOS 4.1 or later.   
    NSString *reqSysVer = @"4.1";   
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];   
    BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);   
   
    return (gcClass && osVersionSupported);
}

- (void)authenticateLocalPlayer {
   
   if(!isGameCenterAvailable()){
      return;
   }
    [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error) {      
      if (error == nil){
         [self registerForAuthenticationNotification];
         S3DClient_SendEventToCurrentUser("MainAI","onGameCenterLogged",NULL);
      }else{
         S3DClient_SendEventToCurrentUser("MainAI","onGameCenterOut",NULL);
      }
   }];
}

- (void)registerForAuthenticationNotification
{
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc addObserver: self selector:@selector(authenticationChanged) name:GKPlayerAuthenticationDidChangeNotificationName object:nil];
}

- (void)authenticationChanged
{
   if(!isGameCenterAvailable()){
      return;
   }
   
    if ([GKLocalPlayer localPlayer].isAuthenticated){      
      S3DClient_SendEventToCurrentUser("MainAI","onGameCenterLogged",NULL);
   }else{
      S3DClient_SendEventToCurrentUser("MainAI","onGameCenterOut",NULL);
   }
}


as you see we have new callbacks "onGameCenterLogged", "onGameCenterOut". You must add these to your lua scripts - create new 2 handlers and inside you can write code to change global enviroment variables of your script - to know is GameCenter logged or quit. New iOS has feature of multitasking, so sometimes it can happens that your app can go into pause and at that moment player can log out from GameCenter and login with another account, so keep that in mind that GameCenter in/out can happens not only at start of your game. In this part of code we are also checking is GameCenter available.

in S3DEngine_EAGLView.h
you should also add this:

Code: Select all
- (void)authenticateLocalPlayer;
- (void)registerForAuthenticationNotification;
- (void)authenticationChanged;


before "@end"

ok, now you may try to compile the sources and see what happens. At this point we have only GameCenter login feature, but it will be more easy to add other features:

add these:
Code: Select all
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController;
- (void)showLeaderboard;

- (void)showAchievements;
- (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController;

- (void)reportScore;
- (void)reportAchiv;

to the same part of S3DEngine_EAGLView.h

then:

Code: Select all
         if ( S3DEngine_GameCenter_WantVisible ( ) )
         {
            S3DEngine_GameCenter_SetWantVisibleFalse();
            [self showLeaderboard];           
         }
         
         if (S3DEngine_GameCenter_WantAchivs())
         {
            S3DEngine_GameCenter_SetWantAchivsFalse();
            [self showAchievements];
         }
         
         if (S3DEngine_GameCenter_WantSubmitScores())
         {
            S3DEngine_GameCenter_SetWantSubmitScoresFalse();
            [self reportScore];
         }
         
         if (S3DEngine_GameCenter_WantSubmitAchiv())
         {
            S3DEngine_GameCenter_SetWantSubmitAchivFalse();
            [self reportAchiv];
         }         
         


to S3DEngine_EAGLView.m into "- (void)drawView "

and:

Code: Select all
- (void)showLeaderboard
{

   UIWindow* window = [UIApplication sharedApplication].keyWindow;
   
    GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];   
    if (leaderboardController != nil) {
      leaderboardController.leaderboardDelegate = self;
      
      UIViewController *glView2 = [[UIViewController alloc] init];
      [window addSubview: glView2.view];
        [glView2 presentModalViewController: leaderboardController animated: YES];
    }
   
}

- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
    [viewController dismissModalViewControllerAnimated:YES];
   [viewController.view.superview removeFromSuperview];
   [viewController release];
}

- (void)showAchievements
{   

   UIWindow* window = [UIApplication sharedApplication].keyWindow;

    GKAchievementViewController *achievements = [[GKAchievementViewController alloc] init];   
    if (achievements != nil){
        achievements.achievementDelegate = self;
      UIViewController *glView2 = [[UIViewController alloc] init];
      [window addSubview: glView2.view];
        [glView2 presentModalViewController: achievements animated: YES];      
    }   
}

- (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
{
    [viewController dismissModalViewControllerAnimated:YES];
   [viewController.view.superview removeFromSuperview];
   [viewController release];
}

- (void)reportScore
{
   
    GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:@"LeaderboardName1"] autorelease];
   if(scoreReporter){
      scoreReporter.value = S3DEngine_GameCenter_GetScoresToSubmit();   
      
      [scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {   
         if (error != nil){
            // handle the reporting error
            
         }
      }];   
   }
}

- (void) reportAchiv
{
   
   int m = S3DEngine_GameCenter_GetAchivToSubmit();
   
   NSString *achievementID = [[NSString alloc] autorelease];
   switch (m){
      case 1:
         achievementID = @"AchivName1";
         break;
      case 2:
         achievementID = @"AchivName2";
         break;

      }
   
      GKAchievement *achievement = [[[GKAchievement alloc] initWithIdentifier: achievementID] autorelease];   
      if (achievement){      
         achievement.percentComplete = 100.0f;      
         [achievement reportAchievementWithCompletionHandler:^(NSError *error){
         if (error != nil){
            
         }      
      }];
    }   
   
   
}

before "-(void)showVirtualKeyboard" in the same file
(plz replace achievement names with yours (like AchivName1) and leaderboard name LeaderboardName1.

this into S3DEngine_Wrapper.h:

Code: Select all
extern bool         S3DEngine_GameCenter_WantVisible            ( );
extern void         S3DEngine_GameCenter_SetWantVisibleFalse      ( );

extern bool         S3DEngine_GameCenter_WantAchivs               ( );
extern void         S3DEngine_GameCenter_SetWantAchivsFalse         ( );
   
extern bool         S3DEngine_GameCenter_WantSubmitScores         ( );
extern void         S3DEngine_GameCenter_SetWantSubmitScoresFalse   ( );
extern int         S3DEngine_GameCenter_GetScoresToSubmit         ( );

extern bool         S3DEngine_GameCenter_WantSubmitAchiv         ( );
extern void         S3DEngine_GameCenter_SetWantSubmitAchivFalse   ( );
extern int         S3DEngine_GameCenter_GetAchivToSubmit         ( );



and last thing into S3DEngine_Wrapper.cpp:

at top
Code: Select all
static bool bGameCenterWantVisible = false;
static bool bGameCenterWantAchivs = false;

static bool   bGameCenterWantSubmitScores=false;
static int nScoresToSubmit = 0;

static bool   bGameCenterWantSubmitAchiv=false;
static int nAchivToSubmit = 0;


these before "extern "C" bool S3DEngine_iPhone_LoadPack":

Code: Select all
void GameCenterSetVisibleCallback ( unsigned char _iArgumentCount, const void *_pArguments, void *_pUserData )
{   
   bGameCenterWantVisible = true;
}

void GameCenterSetAchivsCallback ( unsigned char _iArgumentCount, const void *_pArguments, void *_pUserData )
{
   bGameCenterWantAchivs = true;
}

void GameCenterSubmitScoresCallback ( unsigned char _iArgumentCount, const void *_pArguments, void *_pUserData )
{
   bGameCenterWantSubmitScores = true;
   const S3DX::AIVariable *pVariables = (const S3DX::AIVariable *)_pArguments ;
   nScoresToSubmit   = pVariables[0].GetNumberValue ( );
}

void GameCenterSubmitAchivCallback ( unsigned char _iArgumentCount, const void *_pArguments, void *_pUserData )
{
   bGameCenterWantSubmitAchiv = true;
   const S3DX::AIVariable *pVariables = (const S3DX::AIVariable *)_pArguments ;
   nAchivToSubmit   = pVariables[0].GetNumberValue ( );
}


and this into "extern "C" bool S3DEngine_iPhone_LoadPack":
Code: Select all
   S3DClient_InstallCurrentUserEventHook   ( "MainAI", "onShowLeaderboard", GameCenterSetVisibleCallback, NULL ) ;
   S3DClient_InstallCurrentUserEventHook   ( "MainAI", "onShowAchievements", GameCenterSetAchivsCallback, NULL ) ;

   S3DClient_InstallCurrentUserEventHook   ( "MainAI", "onSubmitScores",  GameCenterSubmitScoresCallback, NULL ) ;
   S3DClient_InstallCurrentUserEventHook   ( "MainAI", "onSubmitAchiv",  GameCenterSubmitAchivCallback, NULL ) ;

   


and at the end of file:

Code: Select all
extern "C" bool S3DEngine_GameCenter_WantVisible ( )
{
    return bGameCenterWantVisible ;
}

extern "C" void S3DEngine_GameCenter_SetWantVisibleFalse ( )
{
    bGameCenterWantVisible = false;
}

extern "C" bool S3DEngine_GameCenter_WantAchivs ( )
{
    return bGameCenterWantAchivs ;
}

extern "C" void S3DEngine_GameCenter_SetWantAchivsFalse ( )
{
    bGameCenterWantAchivs = false;
}
extern "C" bool S3DEngine_GameCenter_WantSubmitScores ( )
{
    return bGameCenterWantSubmitScores ;
}
extern "C" void S3DEngine_GameCenter_SetWantSubmitScoresFalse ( )
{
    bGameCenterWantSubmitScores = false;
}
extern "C" int S3DEngine_GameCenter_GetScoresToSubmit()
{
   return nScoresToSubmit;
}
extern "C" bool S3DEngine_GameCenter_WantSubmitAchiv ( )
{
    return bGameCenterWantSubmitAchiv ;
}
extern "C" void S3DEngine_GameCenter_SetWantSubmitAchivFalse ( )
{
    bGameCenterWantSubmitAchiv = false;
}
extern "C" int S3DEngine_GameCenter_GetAchivToSubmit()
{
   return nAchivToSubmit;
}


as you can see you must also add handlers onShowLeaderboard, onShowAchievements, onSubmitScores, onSubmitAchiv. Use simple integer values as parameters in lua to send. For achievements use 1,2...n to submit number of achievement you want, then as you can find in functions Im using "switch case" to send achievement name.

-----------------------------------------------
ADDITIONAL [SCORES RETRIEVING FROM LEADERBOARD]:
-----------------------------------------------

Here I'll describe how I've coded logic for getting N highscores from GameCenter's leaderboard and delivering to lua-scripts for handling ; )

First of all some theory about how it works:
we will create few handlers in lua-scripts, which will send "request" to c++/objC and will get callbacks.

so:
create 2 variables in your main ai model:
let's call them "tableNames" and "tableScores", they should have "Table" as type
and empty for now. We will use these tables for saving received highscores with players real names.

your code of filling this variables should be that:
Code: Select all
   
    table.empty ( this.tableScores ( ) )
    table.empty ( this.tableNames ( ) )
    user.postEvent ( application.getCurrentUser ( ),0,"MainAI","onFillMarkersTable" )


as you see we have "onFillMarkersTable" handler - you should create an empty handler with this name in your ai model.

now we're going to xCode proj and opening S3DEngine_Wrapper.cpp
we will use the same method with boolean variable as we did before, so we're adding
Code: Select all
static bool bGameCenterWantMarkers = false;

to top part of the file with other variables

at the end of this file (before ad-mob integrations in most cases) we're adding functions:

Code: Select all
extern "C" bool S3DEngine_GameCenter_WantMarkers ( )
{
    return bGameCenterWantMarkers ;
}
extern "C" void S3DEngine_GameCenter_SetWantMarkersFalse ( )
{
    bGameCenterWantMarkers = false;
}


to handle this boolean
also don't forget to declare them in S3DEngine_Wrapper.h:

Code: Select all
extern bool         S3DEngine_GameCenter_WantMarkers               ( );
extern void         S3DEngine_GameCenter_SetWantMarkersFalse         ( );


now in the same .cpp file we're searching:
"extern "C" bool S3DEngine_iPhone_LoadPack" function and adding a hook:

Code: Select all
   S3DClient_InstallCurrentUserEventHook   ( "MainAI", "onFillMarkersTable",  GameCenterMarkersCallback, NULL ) ;

before the function we're adding also:

Code: Select all
void GameCenterMarkersCallback ( unsigned char _iArgumentCount, const void *_pArguments, void *_pUserData )
{
   bGameCenterWantMarkers = true;
}


now we're going to S3DEngine_EAGLView.m file and searching function
"- (void)drawView "
as we did before we're adding check and call:

Code: Select all
         if (S3DEngine_GameCenter_WantMarkers())
         {
            S3DEngine_GameCenter_SetWantMarkersFalse();
            [self fillMarkersTable];
         }


As you understand we need now to create "fillMarkersTable" function, which will do all work, so we're going to S3DEngine_EAGLView.h and adding

Code: Select all
- (void)fillMarkersTable;


now back to .m file and after our previous integration lets write most important function:

Code: Select all
- (void) fillMarkersTable
{

   
   GKLeaderboard* leaderBoard = [[[GKLeaderboard alloc] init] autorelease];
   leaderBoard.category = @"LeaderboardName1";
   leaderBoard.timeScope = GKLeaderboardTimeScopeAllTime;
   leaderBoard.range = NSMakeRange(1,50);
   
   [leaderBoard loadScoresWithCompletionHandler: ^(NSArray *scoress, NSError *error)
    {
       int n =0;
       for ( n = 0; n < [scoress count]; n++ )
       {
          GKScore* a = [scoress objectAtIndex:n];
         
          [GKPlayer loadPlayersForIdentifiers: [NSArray arrayWithObject: [a playerID]] withCompletionHandler:^(NSArray *playerArray, NSError *error)
           {
              GKPlayer* player= NULL;
              for (GKPlayer* tempPlayer in playerArray)
              {
                 if([tempPlayer.playerID isEqualToString: [a playerID]])
                 {
                    player= tempPlayer;
                    NSString* rez = player.alias;
                    const char*cString = [[a formattedValue] UTF8String];
                    const char*cString2 = [rez UTF8String];
                   
                    const void *params = [OurConvert getOurConvert:cString2 andY:cString];
                    S3DClient_SendEventToCurrentUser("MainAI","onGetNewMarkerData",2,params);                   
                   
                    break;
                 }
              }
           }];         
       }
    }];   
   
   
}


now lets see what we have there:

"LeaderboardName1" - you should change that with yours leaderboard name as you setuped in apple account
"leaderBoard.range = NSMakeRange(1,50);" - you can change it to e.g. 1,100 so you'll getting first 100 entries of highscores leaderboard.
"const void *params = [OurConvert getOurConvert:cString2 andY:cString];"

as you see we have to convert values to AIVariables, so we called non-existing getOurConvert function in OurConvert interface. To get it working, lets create "OurConvert.h" and "OurConvert.mm" files and add to xCode's tree and import them while we haven't closed our file:

Code: Select all
#import "OurConvert.h"
into top of S3DEngine_EAGLView.m

OurConvert.h:
Code: Select all
#import <Foundation/Foundation.h>
@interface OurConvert: NSObject{ }
+(const void*)getOurConvert:(const char*)s1 andY:(const char*)s2;
@end


OurConvert.mm:
Code: Select all
#import "OurConvert.h"
#import "S3DXPlugin.h"
@implementation OurConvert
+(const void*)getOurConvert:(const char*)s1 andY:(const char*)s2{
   static S3DX::AIVariable args[2];
   args[0].SetStringValue(s1);
   args[1].SetStringValue(s2);
   return args;
}
@end

at this point I want to say thanks for a person, who posted his example of such convertations on the forum, unfortunally I can't find the original post, but it was converting of posX/posY values, anyway Im glad to add the author to special thanks ; )

so the last thing is to handle stuff by scripts. As you see we need to create "onGetNewMarkerData" handler and write there:

Code: Select all
--------------------------------------------------------------------------------
function MainAI.onGetNewMarkerData (  sName, sScore  )
--------------------------------------------------------------------------------

    local s = ""
    local n = string.getLength ( sScore )
    local sTheScore = ""
   
    for i=0,n-1
    do
        s = string.getSubString ( sScore, i, 1 )
        if ((s == "0") or (s == "1") or (s == "2") or (s == "3") or (s=="4") or (s=="5") or (s=="6") or (s=="7") or (s=="8") or (s=="9"))
        then
            sTheScore = sTheScore .. s
        end
    end

    table.add ( this.tableNames ( ), sName )
    table.add ( this.tableScores( ), sTheScore )

--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------


so in this way we will fill our table-type variables
and later you can do like:
local tName = table.getFirst ( this.tableNames() )
local tScore = table.getFirst ( this.tableScores () )
to get data from this values and create score markers like in Doodle Jump game or something ; ) I've also did simple checks for digits-only filtering, because in most cases scores from GameCenter looks like "120m" or "1500 points", so we need to filter chars and have real numbers ; ) enjoy ; )

its about it : ) Thanks for reading if you see that and reached the end of the thread : ) Feel free to write comments if any issues.

(offtop: I wrote also a tutorial about In-App Purchases integrating, so if you need it you can find at http://www.stonetrip.com/developer/forum/viewtopic.php?f=40&t=24139&p=38008#p38008 or Facebook "share"-function integration: http://www.stonetrip.com/developer/forum/viewtopic.php?f=40&t=25586&p=47275&hilit=facebook+iOS#p47275)



---------------------------------------------------------------------------
---------------------------------------------------------------------------
MODIFICATION #1 "SUBMIT SCORES FOR MULTIPLY LEADERBOARDS"
---------------------------------------------------------------------------

So after discussion with other developers I decided to expand the tutorial. This modification can be done after you'll make basic integration (described upper). You need this modification only if you have more then 1 leaderboard setuped in your game. (But even if you have 1 - this code will allow you to send leaderboard name from lua scripts, instead searching and changing it in objC part).
Implementing is pretty easy: besides sending "nScores" to submit from scripts - we're sending also leaderboard name as well.
So in your shiva scripts please change this:
Code: Select all
  MainAI.onSubmitScores ( scores )

to this:
Code: Select all
  MainAI.onSubmitScores ( sLeaderboard, scores )

thats all we need from scripts, now lets open xCode project and make some changes:

S3DEngine_Wrapper.h:
at the end of functions declarations add this:
Code: Select all
extern const char *S3DEngine_GameCenter_GetLeaderboardNameForScores ();


S3DEngine_Wrapper.cpp:
at start of the file, put this into variables declarations list:
Code: Select all
   static char sLeaderboardForScores[64] = "";


now find "void GameCenterSubmitScoresCallback ( unsigned char _iArgumentCount, const void *_pArguments, void *_pUserData )"
and make this function looks like this:
Code: Select all
   bGameCenterWantSubmitScores = true;
   
    if ( _pArguments && ( _iArgumentCount == 2 ) )
    {
        const S3DX::AIVariable *pVariables = (const S3DX::AIVariable *)_pArguments ;

        if ( pVariables[0].GetType ( ) == S3DX::AIVariable::eTypeString )
            strncpy ( sLeaderboardForScores, pVariables[0].GetStringValue ( ), 63 ) ;
        if ( pVariables[1].GetType ( ) == S3DX::AIVariable::eTypeNumber )
            nScoresToSubmit   = pVariables[1].GetNumberValue ( );
       
    }


and at the end of this file you need to add this function:
Code: Select all
extern "C" const char *S3DEngine_GameCenter_GetLeaderboardNameForScores()
{
    return sLeaderboardForScores;
}


inside file S3DEngine_EAGLView.m:
find "- (void)reportScore" and make it looks like this:
Code: Select all
- (void)reportScore
{
   
   
    NSString* sLeaderboard = [[NSString alloc] initWithUTF8String:S3DEngine_GameCenter_GetLeaderboardNameForScores()];

   
    GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:sLeaderboard] autorelease];
   if(scoreReporter){
        int nScores = S3DEngine_GameCenter_GetScoresToSubmit();   
      scoreReporter.value = [[NSNumber numberWithInt:nScores] longLongValue];
      
      [scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {   
         if (error != nil){
            // handle the reporting error
                //NSLog(@"error while posting scores");
            
         }
      }];   
   }
}


so as you can see instead using hardcoded string as we were doing before - now we are reading "S3DEngine_GameCenter_GetLeaderboardNameForScores()". Now your code is much more professional 8)





------------------------------------------------------------------------------
------------ FIX FOR iPAD INPUT LOCKED AFTER LEADERBOARD CLOSED ---------
------------------------------------------------------------------------------

djey wrote:Ok so I've just added a temporary UIViewController to the S3DEngine_EAGLView.h (after the AbMob stuff
Code: Select all
 
    AdMobView                      *pAdMobView                  ;
    AdMobViewDelegate              *pAdMobViewDelegate          ;
   
    UIViewController               *tempVC;


Then I use the following piece of code in the .m:

Code: Select all
- (void)showLeaderboard
{
   
    tempVC = [[UIViewController alloc] init];
    UIWindow* window = [UIApplication sharedApplication].keyWindow;
   
    GKLeaderboardViewController* leaderboardController = [[[GKLeaderboardViewController alloc] init] autorelease];
    if (leaderboardController != nil)
    {
        leaderboardController.leaderboardDelegate = self;
        [window addSubview:tempVC.view]; //Doesn't show up without this
        [tempVC presentModalViewController:leaderboardController animated:YES];
    }
   
}

- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
        [tempVC dismissViewControllerAnimated:YES completion:^(void)
         {
             [tempVC.view removeFromSuperview];
             [tempVC release];
         }];
}


Last edited by vklymenko on 04 Aug 2012, 09:09, edited 16 times in total.
User avatar
vklymenko
Platinum Boarder
Platinum Boarder
 
Posts: 759
Location: Europe

Re: Game Center integrated!

Postby Baptiste » 18 Feb 2011, 14:51

Amazing job, thanks!
Baptiste
Junior Boarder
Junior Boarder
 
Posts: 26

Re: Game Center integrated!

Postby Diffa » 18 Feb 2011, 15:04

:D Thanx!!!
Diffa
Gold Boarder
Gold Boarder
 
Posts: 216

Re: Game Center integrated!

Postby FlashMP » 18 Feb 2011, 15:52

Its really COOL!!! Thanks a lot, dude! :wink:
User avatar
FlashMP
Junior Boarder
Junior Boarder
 
Posts: 23

Re: Game Center integrated!

Postby dpharaoh » 18 Feb 2011, 15:56

Thanks for posting up the juicy bits!
dpharaoh
Platinum Boarder
Platinum Boarder
 
Posts: 1521
Location: New Bedford, MA

Re: Game Center integrated!

Postby NiCoX » 18 Feb 2011, 20:47

Nice to share!
User avatar
NiCoX
Platinum Boarder
Platinum Boarder
 
Posts: 5652
Location: France

Re: Game Center integrated!

Postby dustin1138 » 19 Feb 2011, 07:03

This is absolutely fantastic!!! Man, I hope I can integrate this into "Poker With Bob"!
dustin1138
Senior Boarder
Senior Boarder
 
Posts: 77

Re: Game Center integrated!

Postby vklymenko » 19 Feb 2011, 09:42

Hi Dustin! Sure you can : ) Try to do step by step and let me know if any issues ; )
User avatar
vklymenko
Platinum Boarder
Platinum Boarder
 
Posts: 759
Location: Europe

Re: Game Center integrated!

Postby vklymenko » 19 Feb 2011, 22:57

update: I've added tutorial about [SCORES RETRIEVING FROM LEADERBOARD] feature!
If someone already completed the integration - please let us know - if everything fine and have missed something ; )
User avatar
vklymenko
Platinum Boarder
Platinum Boarder
 
Posts: 759
Location: Europe

Re: Game Center integrated!

Postby broozar » 20 Feb 2011, 00:22

Image

thanks for this huge contribution! i put it on the wiki: http://www.stonetrip.com/developer/wiki/index.php?title=IOS_GameCenter
User avatar
broozar
Platinum Boarder
Platinum Boarder
 
Posts: 3570
Location: Berlin - Germany

Re: Game Center integrated!

Postby michax » 20 Feb 2011, 02:55

Thanks a lot for detailed tutorial !
User avatar
michax
Platinum Boarder
Platinum Boarder
 
Posts: 469
Location: Poland

Re: Game Center integrated!

Postby vklymenko » 20 Feb 2011, 09:41

broozar, cool thanks!
I did copy/past from my project, so still waiting - who will try the integration to hear are there any issues!!! Pretty much code here so I could miss some lines - so plz leave your daily tasks and do the most important step of your app dev - GameCenter integration!!! : )
User avatar
vklymenko
Platinum Boarder
Platinum Boarder
 
Posts: 759
Location: Europe

Re: Game Center integrated!

Postby Markuzzzz » 03 Mar 2011, 08:54

I will try this in the coming weeks! Thanks a lot guys for this implementation :)

I will let you know how it goes!

kind regards,

Markus
http://www.nifty-inspirations.com, because simple things are hard to find!
Markuzzzz
Platinum Boarder
Platinum Boarder
 
Posts: 578
Location: Netherlands

Re: Game Center integrated!

Postby Markuzzzz » 07 Mar 2011, 18:33

Ok, so far no build errors :)

I have a small question. When I build a project version with the UAT, it opens xCode with the project. Now I change my STK in Shiva, rebuild and again I try to build a project with the UAT, now it asks me to overwrite the file that I have changed (S3DEngine files in your sample), what is the best way to work around this override. Obviously I dont want to overwrite. Only want to add the new stk to the project?
http://www.nifty-inspirations.com, because simple things are hard to find!
Markuzzzz
Platinum Boarder
Platinum Boarder
 
Posts: 578
Location: Netherlands

Re: Game Center integrated!

Postby vklymenko » 07 Mar 2011, 18:40

hi, maybe these hints will help:
- once xCode proj created, no needs to create it anymore with Auth. tool
- if you want to replace the stk, you should close xCode, go to "Resources" folder inside xcode-proj folder, find "S3DMain.stk" and place your new stk instead this, then run xCode. It works for me. Plz specify your question with more details, maybe I'll help ; )
User avatar
vklymenko
Platinum Boarder
Platinum Boarder
 
Posts: 759
Location: Europe

Next

Return to Code Snippets

cron