Search code examples
iosobjective-cgame-centerleaderboardgame-center-leaderboard

Coding a Second Leaderboard


I am making a game in which the player can achieve a positive high score or a negative low score depending on the choices they make. The code that I've been using works great if there is only one leaderboard, but I'm having trouble when I try to add the second. TEHS is the leaderboard identifier for HighScore and TELS is the leaderboard identifier for LowScore.

I authenticate the local player:

-(void)authenticateLocalPlayer{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];

localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error){
    if (viewController != nil) {
        [self presentViewController:viewController animated:YES completion:nil];
    }
    else{
        if ([GKLocalPlayer localPlayer].authenticated) {
            _gameCenterEnabled = YES;

            // Get the default leaderboard identifier.
            [[GKLocalPlayer localPlayer] loadDefaultLeaderboardIdentifierWithCompletionHandler:^(NSString *leaderboardIdentifier, NSError *error) {

                if (error != nil) {
                    NSLog(@"%@", [error localizedDescription]);
                }
                else{
                    TEHS = leaderboardidentifier;
                }
            }];
        }

        else{
            _gameCenterEnabled = NO;
        }
    }
};
}

Scores are reported:

-(void)reportHighScore{

GKScore *highscore = [[GKScore alloc] initWithLeaderboardIdentifier:TEHS];
highscore.value = HighScoreNumber;

[GKScore reportScores:@[highscore] withCompletionHandler:^(NSError *error) {
    if (error != nil) {
        NSLog(@"%@", [error localizedDescription]);
    }
}];
}

-(void)reportLowScore {

GKScore *lowscore = [[GKScore alloc] initWithLeaderboardIdentifier:TELS];
lowscore.value = LowScoreNumber;

[GKScore reportScores:@[lowscore] withCompletionHandler:^(NSError *error) {
    if (error != nil) {
        NSLog(@"%@", [error localizedDescription]);
    }
}];
}

And, the leaderboards are shown when the player activates:

-(void)showLeaderboardAndAchievements:(BOOL)shouldShowLeaderboard{
GKGameCenterViewController *gcViewController = [[GKGameCenterViewController alloc] init];

gcViewController.gameCenterDelegate = self;

if (shouldShowLeaderboard) {
    gcViewController.viewState = GKGameCenterViewControllerStateLeaderboards;
    gcViewController.leaderboardIdentifier = TEHS;
}
else{
    gcViewController.viewState = GKGameCenterViewControllerStateAchievements;
}

[self presentViewController:gcViewController animated:YES completion:nil];
}

Either reportLowScore or reportHighScore will work when I change

gcViewController.leaderboardIdentifier = TEHS;

and

TEHS = leaderboardidentifier;

to match their respective identifier. So, right now, this code works for High Score (TEHS), and if I changed the above two to TELS, Low Score would work. I'm just not quite sure what I need to do to authenticateLocalPlayer and showLeaderboardAndAchievements to get both leaderboards to work.


Solution

  • I have a game on the App Store that has two leaderboards, one for points and one for levels cleared. Instead of having one method for each leaderboard I made one method for submitting scores. Here is that method:

    -(void) submitScore:(int64_t)score Leaderboard: (NSString*)leaderboard
    {
    
        //1: Check if Game Center
        //   features are enabled
        if (!_gameCenterFeaturesEnabled) {
            return;
        }
    
        //2: Create a GKScore object
        GKScore* gkScore =
        [[GKScore alloc]
         initWithLeaderboardIdentifier:leaderboard];
    
        //3: Set the score value
        gkScore.value = score;
    
        //4: Send the score to Game Center
        [gkScore reportScoreWithCompletionHandler:
         ^(NSError* error) {
    
             [self setLastError:error];
    
             BOOL success = (error == nil);
    
             if ([_delegate
                  respondsToSelector:
                  @selector(onScoresSubmitted:)]) {
    
                 [_delegate onScoresSubmitted:success];
             }
         }];
    
    
    }
    

    When you want to submit your high scores all you have to do is add something like:

    [[GCHelper sharedGameKitHelper] submitScore:myLowScore Leaderboard:TELS];
    [[GCHelper sharedGameKitHelper] submitScore:myHighScore Leaderboard:TEHS];
    

    GCHelper is the class that contains my submitScore:Leaderboard: method.

    To view your leaderboards or achievements within your app try this:

    - (void) presentLeaderboards {
        GKGameCenterViewController* gameCenterController = [[GKGameCenterViewController alloc] init];
        gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
        gameCenterController.gameCenterDelegate = self;
        [self presentViewController:gameCenterController animated:YES completion:nil];
    }
    
    - (void) gameCenterViewControllerDidFinish:(GKGameCenterViewController*) gameCenterViewController {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    - (void) presentAchievements {
        GKGameCenterViewController* gameCenterController = [[GKGameCenterViewController alloc] init];
        gameCenterController.viewState = GKGameCenterViewControllerStateAchievements;
        gameCenterController.gameCenterDelegate = self;
    

    I hope this answers your question!