I'm using the following method to retrieve the top 100 scores from one of my gamecenter leaderboards. Everything is working, correctly, except that as I retrieve a score, I'd like to add them up, so that once it is done, I have 1 total score.
How could I fix it?
- (void) retrieveTop100Scores {
GKLeaderboard *leaderboard1 = [[GKLeaderboard alloc] init];
leaderboard1.identifier = [Team currentTeam];
leaderboard1.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboard1.playerScope = GKLeaderboardPlayerScopeGlobal;
leaderboard1.range = NSMakeRange(1, 100);
[leaderboard1 loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
if (scores != nil) {
for (GKScore *score in scores) {
NSLog(#"%lld", score.value);
//Add them all up here?
}
}
}];
}
You can make a variable outside of the loop, and in each iteration, var+=score.value. Therefore after the iteration, the variable you build will contain the total score.
Related
A part of code (I didn't write) is shown as deprecated in my Xcode project, here's the code block:
#pragma mark - Report Achievement Progress
static int reportAchievement(struct lua_State *state) {
[gameCenterAddOnInstance reportAchievementAction:[NSString stringWithCString:lua_tostring(state, 1) encoding:NSUTF8StringEncoding] percentComplete:(int)lua_tointeger(state, 2)];
return 1;
}
- (void) reportAchievementAction: (NSString*) identifier percentComplete: (float) percent
{
GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier: identifier];
if (achievement)
{
achievement.percentComplete = percent;
[achievement reportAchievementWithCompletionHandler:^(NSError *error)
{
if (error != nil)
{
NSLog(#"Error in reporting achievements: %#", error);
}
}];
}
}
According to Xcode, the depreciated part is:
reportAchievementWithCompletionHandler
Xcode suggests to use:
reportAchievements:WithCompletionHandler:
Instead. But, not being familiar with objective C, I wouldn't know where to start.
How to implement to new function?
Try this
[GKAchievement reportAchievements:#[achievement] withCompletionHandler:^(NSError *error)
{
if (error != nil)
{
NSLog(#"Error in reporting achievements: %#", error);
}
}];
Apple replaced the instance method - reportAchievementWithCompletionHandler: with the class method + reportAchievements:withCompletionHandler:. This allows you to report multiple achievements at once without having to call the instance method on every achievement object.
#[achievement] is shorthand for [NSArray arrayWithObjects:achievement, nil].
I am adding achievements into an xCode project. The code below that I am using works fine in awarding the achievement but the only problem is that it is constantly being awarded in the background in the debug console. This is happening every time I load the game.
I also find that when the achievement is awarded for the very first time the completion banner is on repeat.
My question today is how do I edit the code to only award the achievement once, display the banner and then never appear again?
-(void)Scoring
{
ScoreNumber = ScoreNumber + AddedScore;
AddedScore = AddedScore - 1;
if (AddedScore < 0) {
AddedScore = 0;
}
Score.text = [NSString stringWithFormat:#"%i", ScoreNumber];
if (ScoreNumber > 110 && ScoreNumber < 1000) {
LevelNUmber = 2;
//self.view.backgroundColor = [UIColor greenColor];
GKAchievement *achievement= [[GKAchievement alloc] initWithIdentifier:#"_level1easy"];
achievement.percentComplete = 100.0;
achievement.showsCompletionBanner = YES;
if(achievement!= NULL)
{
NSArray *achievements = [NSArray arrayWithObjects:achievement, nil];
[GKAchievement reportAchievements:achievements withCompletionHandler:^(NSError *error) {
if (error != nil) {
NSLog(#"Error in reporting achievements: %#", error);
} else {
NSLog(#"Achievement 1 Success");
}
}];
}
}
If I understand your question correctly, then you just need to save the state of your achievement somewhere, then check it when you go into your Scoring method. Maybe try saving in NSUserdefaults, for example;
NSUserDefaults *savedScoring = [NSUserDefaults standardUserDefaults];
[savedScoring setObject:self.showsCompletionBanner forKey:#"showsCompletionBanner"];
Then check this whenever you game loads.
Why score doesn't get incremented?
GKLeaderboard *lb = [[GKLeaderboard alloc] initWithPlayerIDs:#["G:1518137155"]];
lb.category = #"top_matcher";
[lb loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
if(error == nil){
GKScore *score = [scores lastObject];
if(score) {
score.value += 40;
[score reportScoreWithCompletionHandler:^(NSError *error) {
NSLog(#"ERR: %# SC:%lld %# %# %d", error, score.value, score.playerID, score.category, scores.count);
}];
}
}
}];
I see no error in output
ERR: (null) SC:61 G:1689523782 top_matcher 1
It's clearly documented here.
Almost all classes in Game Kit that send data to or retrieve information from Game Center expect the device to have an authenticated local player. The work those classes do is always on behalf of the local player. For example, if your game reports scores to a leaderboard, it can only report a score earned by the local player.
Trying to test out a leaderboard. I do this:
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
if (leaderboardRequest != nil)
{
leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardRequest.category = self.gameData.leaderboardId;
leaderboardRequest.range = NSMakeRange(1,10);
[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
if (error != nil)
{
// Handle the error.
}
if (scores != nil)
{
for (GKScore *score in scores) {
NSLog(#"score retrieved: %lld", score.value);
}
}
}];
}
I play the game on one device with user A, and get a score of 137. When I query the leaderboard I get the one 137 score back. I play on another device with user B, score 243, and get only the 243 score back when I query the leaderboard.
So why am I only getting back scores from the user that is logged in? Obviously I need everyone's scores to create a custom leaderboard. It is my understanding that GKLeaderboardPlayerScopeGlobal should retrieve all scores, not just those for the local user.
I'm trying to enable Game Center Leaderboard to my iPad game and I have learned that you need to post more than one score to a leaderboard for the scores to show in the default leaderboard UI.
I have two separete accounts that I used to post two different scores to the same leaderboard, but when I call loadScoresWithCompletionHandler I only get one score back (the score for the user I currently are logged in with).
Any ideas why?
GKLeaderboard *myLB = [[GKLeaderboard alloc] init];
myLB.category = #"MyLeaderboardId";
myLB.timeScope = GKLeaderboardTimeScopeAllTime;
myLB.playerScope = GKLeaderboardPlayerScopeGlobal;
myLB.range = NSMakeRange(1, 100);
[myLB loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
if (error != nil)
{
NSLog(#"%#", [error localizedDescription]);
}
if (scores != nil)
{
for (GKScore *score in scores)
{
NSLog(#"%lld", score.value);
}
}
}];
It works fine for me. Just add scores under another account.
I've got:
scores (
"<GKScore: 0x960e3e0><0x960e3e0> player=G:1208389607 rank=1 date=2012-01-19 12:56:47 +0000 value=27 formattedValue=27 context=(null)",
"<GKScore: 0x96a1bc0><0x96a1bc0> player=G:1176161436 rank=2 date=2012-01-19 08:35:06 +0000 value=16 formattedValue=16 context=(null)"
)
And center by standard controller show same results.
thanks,