I'm working on a game where scores are submitted to leaderboards in an activity and the new high scores are displayed with ranks in a fragment. I have something (somewhat) functional, but the success rate is ~10%.
The flow is as follows:
Method handleLeaders
This method gets the current scores for each leaderboard, and if the new score is better, it is submitted and a new newHigh object is created with the score and added to an ArrayList. After all 3 of the leaderboards are handled, the method setHighs is called. (Errors are checked for in each of the leaderboard calls)
public void handleLeaders(boolean win, int size, double t, final int toupees) {
if(win) {
final long time = (long) t;
// Toupees
Games.Leaderboards.loadCurrentPlayerLeaderboardScore(mGoogleApiClient,
getString(R.string.leaderboard_trumps_toupeed),
LeaderboardVariant.TIME_SPAN_ALL_TIME,
LeaderboardVariant.COLLECTION_PUBLIC).setResultCallback(
new ResultCallback<Leaderboards.LoadPlayerScoreResult>() {
@Override
public void onResult(Leaderboards.LoadPlayerScoreResult arg0) {
LeaderboardScore c = arg0.getScore();
int old;
if (c != null)
old = (int) c.getRawScore();
else
old = 0;
Games.Leaderboards.submitScore(mGoogleApiClient, getResources().getString(R.string.leaderboard_trumps_toupeed), old + toupees);
GameEndOverlay.newHighs.add(new newHigh("Trumps Toupee'd", old + toupees));
Status status = arg0.getStatus();
int statusCode = status.getStatusCode();
if (statusCode == GamesStatusCodes.STATUS_NETWORK_ERROR_NO_DATA)
GameEndOverlay.highsError = true;
if(++GameEndOverlay.leaderboardsCompleted == 3)
((GameEndOverlay) gameEndOverlayFrag).setHighs();
}
});
if (size == getResources().getInteger(R.integer.size_apprentice)) {
// Wins
Games.Leaderboards.loadCurrentPlayerLeaderboardScore(mGoogleApiClient,
getString(R.string.leaderboard_apprentice_wins),
LeaderboardVariant.TIME_SPAN_ALL_TIME,
LeaderboardVariant.COLLECTION_PUBLIC).setResultCallback(
new ResultCallback<Leaderboards.LoadPlayerScoreResult>() {
@Override
public void onResult(Leaderboards.LoadPlayerScoreResult arg0) {
LeaderboardScore c = arg0.getScore();
int wins;
if (c != null)
wins = (int) c.getRawScore();
else
wins = 0;
Games.Leaderboards.submitScore(mGoogleApiClient, getResources().getString(R.string.leaderboard_apprentice_wins), wins + 1);
GameEndOverlay.newHighs.add(new newHigh("Apprentice Wins", wins + 1));
Status status = arg0.getStatus();
int statusCode = status.getStatusCode();
if (statusCode == GamesStatusCodes.STATUS_NETWORK_ERROR_NO_DATA)
GameEndOverlay.highsError = true;
if(++GameEndOverlay.leaderboardsCompleted == 3)
((GameEndOverlay) gameEndOverlayFrag).setHighs();
}
});
// Speed
Games.Leaderboards.loadCurrentPlayerLeaderboardScore(mGoogleApiClient,
getString(R.string.leaderboard_fastest_apprentice),
LeaderboardVariant.TIME_SPAN_ALL_TIME,
LeaderboardVariant.COLLECTION_PUBLIC).setResultCallback(
new ResultCallback<Leaderboards.LoadPlayerScoreResult>() {
@Override
public void onResult(Leaderboards.LoadPlayerScoreResult arg0) {
LeaderboardScore c = arg0.getScore();
long old_time;
if(c != null) {
old_time = c.getRawScore();
Log.d("time", old_time + "");
if(time < old_time) {
Games.Leaderboards.submitScore(mGoogleApiClient, getResources().getString(R.string.leaderboard_fastest_apprentice), time);
GameEndOverlay.newHighs.add(new newHigh("Fastest Apprentice", time));
}
}
else {
Games.Leaderboards.submitScore(mGoogleApiClient, getResources().getString(R.string.leaderboard_fastest_apprentice), time);
GameEndOverlay.newHighs.add(new newHigh("Fastest Apprentice", time));
}
Status status = arg0.getStatus();
int statusCode = status.getStatusCode();
if (statusCode == GamesStatusCodes.STATUS_NETWORK_ERROR_NO_DATA)
GameEndOverlay.highsError = true;
if(++GameEndOverlay.leaderboardsCompleted == 3)
((GameEndOverlay) gameEndOverlayFrag).setHighs();
}
});
}
}
Method setHighs
This method gets the ranks of each corresponding newHigh and stores the new rank inside the object. After all ranks are gathered, the method setSecondHighs is called. (Errors are checked for in each of the leaderboard calls)
public void setHighs() {
if(getActivity() == null)
return;
ranksComputed = 0;
for(newHigh highRaw : newHighs) {
final newHigh high = highRaw;
switch(high.getName()) {
case "Trumps Toupee'd":
Games.Leaderboards.loadCurrentPlayerLeaderboardScore(mGoogleApiClient,
getString(R.string.leaderboard_trumps_toupeed),
LeaderboardVariant.TIME_SPAN_ALL_TIME,
LeaderboardVariant.COLLECTION_PUBLIC).setResultCallback(
new ResultCallback<Leaderboards.LoadPlayerScoreResult>() {
@Override
public void onResult(Leaderboards.LoadPlayerScoreResult arg0) {
if(arg0.getScore() == null) {
highsError = true;
ranksComputed++;
if(ranksComputed >= newHighs.size())
setSecondHighs();
return;
}
high.setRank(arg0.getScore().getRank());
Status status = arg0.getStatus();
int statusCode = status.getStatusCode();
if (statusCode == GamesStatusCodes.STATUS_NETWORK_ERROR_NO_DATA)
GameEndOverlay.highsError = true;
ranksComputed++;
if(ranksComputed >= newHighs.size())
setSecondHighs();
}
});
break;
case "Apprentice Wins":
Games.Leaderboards.loadCurrentPlayerLeaderboardScore(mGoogleApiClient,
getString(R.string.leaderboard_apprentice_wins),
LeaderboardVariant.TIME_SPAN_ALL_TIME,
LeaderboardVariant.COLLECTION_PUBLIC).setResultCallback(
new ResultCallback<Leaderboards.LoadPlayerScoreResult>() {
@Override
public void onResult(Leaderboards.LoadPlayerScoreResult arg0) {
if(arg0.getScore() == null) {
highsError = true;
ranksComputed++;
if(ranksComputed >= newHighs.size())
setSecondHighs();
return;
}
high.setRank(arg0.getScore().getRank());
Status status = arg0.getStatus();
int statusCode = status.getStatusCode();
if (statusCode == GamesStatusCodes.STATUS_NETWORK_ERROR_NO_DATA)
GameEndOverlay.highsError = true;
ranksComputed++;
if(ranksComputed >= newHighs.size())
setSecondHighs();
}
});
break;
case "Fastest Apprentice":
Games.Leaderboards.loadCurrentPlayerLeaderboardScore(mGoogleApiClient,
getString(R.string.leaderboard_fastest_apprentice),
LeaderboardVariant.TIME_SPAN_ALL_TIME,
LeaderboardVariant.COLLECTION_PUBLIC).setResultCallback(
new ResultCallback<Leaderboards.LoadPlayerScoreResult>() {
@Override
public void onResult(Leaderboards.LoadPlayerScoreResult arg0) {
if(arg0.getScore() == null) {
highsError = true;
ranksComputed++;
if(ranksComputed >= newHighs.size())
setSecondHighs();
return;
}
high.setRank(arg0.getScore().getRank());
Status status = arg0.getStatus();
int statusCode = status.getStatusCode();
if (statusCode == GamesStatusCodes.STATUS_NETWORK_ERROR_NO_DATA)
GameEndOverlay.highsError = true;
ranksComputed++;
if(ranksComputed >= newHighs.size())
setSecondHighs();
}
});
break;
}
}
}
Method setSecondHighs
This method either displays an error or new ranks+score to the user
public void setSecondHighs() {
if(highsError)
// display an error to the user
else
// display ranks+score to user
}
The issue is that there are a LOT of API calls here, and the submissions are hanging at different points in the calls. I know there has to be a better way to do this. Any help would be greatly appreciated.
Cheers!