Reputation: 131
I read all documentation about leaderboards in Google Play Services and it seems that when I call the submitScore function of GameClient the service take account of the highest score submitted only. E.g.:
1st call:
gamesclient.submitScore( 100 );
Now player score is 100
2nd call:
gamesclient.submitScore( 150 );
Now player score is 150
3rd call:
gamesclient.submitScore( 100 );
player score still remains 150. Submitted value isn't greater than last so it is ignored.
Is there a simple way to retrieve last player score, sum the new score and submit the total for create an incremental score leaderboard ? Something like
int old_score = ...GET LAST PLAYER SCORE...
int new_score = old_score + current_game_score;
gamesclient.submitScore( new_score );
Upvotes: 13
Views: 4709
Reputation: 1299
In case someone is still looking for the solution, according to the latest android releases, it can be done as follows:
private LeaderboardsClient mLeaderboardsClient = Games.getLeaderboardsClient(this, googleSignInAccount);
private void updateLeaderboards(final String leaderboardId) {
mLeaderboardsClient.loadCurrentPlayerLeaderboardScore(
leaderboardId,
LeaderboardVariant.TIME_SPAN_ALL_TIME,
LeaderboardVariant.COLLECTION_PUBLIC
).addOnSuccessListener(new OnSuccessListener<AnnotatedData<LeaderboardScore>>() {
@Override
public void onSuccess(AnnotatedData<LeaderboardScore> leaderboardScoreAnnotatedData) {
if (leaderboardScoreAnnotatedData.get() == null)
mLeaderboardsClient.submitScore(leaderboardId, 1);
else {
long currentscore = leaderboardScoreAnnotatedData.get().getRawScore();
mLeaderboardsClient.submitScore(leaderboardId, currentscore + 1);
}
}
});
}
Upvotes: 0
Reputation: 6648
While you have been given examples of how to increment scores you can't use leaderboards as league tables where scores decrease.
Google presently only allows the facility to hide scores of suspected cheaters. If there was some way to lower scores or erase them entirely you would be able to do what you are asking.
I think the reasoning behind this is that if they let you modify already posted scores it would diminish user trust in both the Google Play Game Services platform aswell as in your game- for distorting what players like to take ownership of (excuse the jargon.).
This leads to score inflation over time, I think they use 64 bit integers internally:
/**
* Submit a score to the leaderboard for the currently signed-in player.
* The score is ignored if it is worse (as defined by the leaderboard
* configuration) than a previously submitted score for the same player.
*/
void SubmitScore(std::string const &leaderboard_id, uint64_t score);
You could however modify the leaderboard's fixed place decimal place point position as a course adjustment to this inflation. I wouldn't.
Sorry if this is off topic, let's hope Google take this into consideration in future updates.
Upvotes: 0
Reputation: 1370
Didn't test it so far, but i think thats the way to go:
PendingResult<Leaderboards.LoadPlayerScoreResult> result = Games.Leaderboards.loadCurrentPlayerLeaderboardScore(gameHelper.getApiClient(),"LEADERBOARD_ID",LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC);
result.setResultCallback(new ResultCallback<Leaderboards.LoadPlayerScoreResult>() {
@Override
public void onResult(Leaderboards.LoadPlayerScoreResult loadPlayerScoreResult) {
Games.Leaderboards.submitScore(gameHelper.getApiClient(), "LEADERBOARD_ID",loadPlayerScoreResult.getScore().getRawScore()+ score);
}
Upvotes: 4
Reputation: 1912
Here's what I came up with...
@Override
public void postNewScore(final int finalScore, final ArrayList<String> theseBoards) {
//posts score update to any theseBoards... most likely 2 boards
for (final String anID : theseBoards) {
aHelper.getGamesClient().loadPlayerCenteredScores(new OnLeaderboardScoresLoadedListener() {
@Override
public void onLeaderboardScoresLoaded(int statusCode, Leaderboard leaderboard, LeaderboardScoreBuffer scores) {
if(statusCode == GamesClient.STATUS_OK){
if(scores.getCount() == 0){
aHelper.getGamesClient().submitScore(anID, finalScore);
dLog("submitted a score because there were no scores period");
} else {
for (LeaderboardScore s : scores) {
if(s.getScoreHolder().getPlayerId().contains(aHelper.getGamesClient().getCurrentPlayer().getPlayerId()) ||
aHelper.getGamesClient().getCurrentPlayer().getPlayerId().contains(s.getScoreHolder().getPlayerId())){
aHelper.getGamesClient().submitScore(anID, finalScore + s.getRawScore());
dLog("just submitted " + (finalScore + s.getRawScore()));
scores.close();
return;
}
}
//if to here, then no score on the current page, which means the player does not have a score
aHelper.getGamesClient().submitScore(anID, finalScore);
dLog("because no entry, just submitted " + (finalScore));
}
}
scores.close();
}
}, anID, LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_SOCIAL, 1);
}
}
Upvotes: 1
Reputation: 6709
Does not seem like there is an in-built way of doing this unfortunately. However, you could use Cloud Save to just save the most recent score of the player and just use that.
Alternatively, (this might seem a little tacky) every time you submit a score, save that score in SharedPreferences
and then when you submit another score, use that preference to increment the score rather than set an entirely new one.
Hopefully this is of help, if this isn't really how you'd like to go about solving your issue, let me know and I'll try to find another solution...
Upvotes: 1