My requirement is to get top 5 scores from leaderboard and display it in my app.
There is a method loadTopScores but it shows the scores in its own UI i guess.
mGamesClint.loadTopScores(new OnLeaderboardScoresLoadedListener() {
public void onLeaderboardScoresLoaded(int arg0, LeaderboardBuffer arg1,
LeaderboardScoreBuffer arg2) {
// TODO Auto-generated method stub
}
}, LEADERBOARD_ID,LeaderboardVariant.TIME_SPAN_ALL_TIME , LeaderboardVariant.COLLECTION_PUBLIC, 5, true);
So is there any way I can get individual data like Name and score..?
Name 1 : Name of the top scorer 1
score 1 : score of the top scorer 1
Name 2 : Name of the top scorer 2
score 2 : score of the top scorer 2
......and so on
I just want name string and score integer so that I can use it in my game.
Please suggest me some ideas
You are on the right track in your example, you just need to extract the information once it is loaded. It is fairly confusing to get it working but I will point you to this answer of mine, which shows how to do it for achievements - doing it for leaderboards works the same way, except that you will use the leaderboard interfaces instead of those used for achievements.
Basically, you will access arg2 to get the data, and it should look something like this:
mGamesClint.loadTopScores(new OnLeaderboardScoresLoadedListener() {
public void onLeaderboardScoresLoaded(int arg0, LeaderboardBuffer arg1, LeaderboardScoreBuffer arg2) {
// iterate through the list of returned scores for the leaderboard
int size = arg2.getCount();
for ( int i = 0; i < size; i++ ) {
LeaderboardScore lbs = arg2.get( i );
// access the leaderboard data
int rank = i + 1; // Rank/Position (#1..#2...#n)
String name = lbs.getScoreHolderDisplayName();
String scoreStr = lbs.getDisplayScore();
long score = lbs.getRawScore();
// now display or cache these values, or do whatever with them :)
}
arg2.close();
arg1.close();
}
}, LEADERBOARD_ID,LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC, 5, true);
I did not actually test this implementation, but it should work (or at least show you enough so you can fix any mistakes I might have made).
Just remember that this will be done asynchronously, so the contents of the method will not execute immediately, but rather once the scores have been loaded.
Here is how I have achieved it.
PendingResult<Leaderboards.LoadScoresResult> topScores =
Games.Leaderboards.loadTopScores(getApiClient(),LEADERBOARD_ID,LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC, 1, true);
topScores.setResultCallback(new ResultCallback<Leaderboards.LoadScoresResult>() {
#Override
public void onResult(LoadScoresResult scoreResults) {
if(scoreResults != null) {
if (scoreResults.getStatus().getStatusCode() == GamesStatusCodes.STATUS_OK) {
scoreStringBuilder = new StringBuilder();
LeaderboardScoreBuffer scoreBuffer = scoreResults.getScores();
Iterator<LeaderboardScore> it = scoreBuffer.iterator();
while(it.hasNext()){
LeaderboardScore temp = it.next();
Log.d("PlayGames", "player"+temp.getScoreHolderDisplayName()+" id:"+temp.getRawScore() + " Rank: "+temp.getRank());
scoreStringBuilder.append("|"+temp.getScoreHolderDisplayName()+"*"+temp.getRawScore());
}
UnityPlayer.UnitySendMessage(handlerName, "onGetScoreSucceededEventListener", "");
Log.d("PlayGames", "Call Sent for getHighScorewithPlayerNameSuccess ::: "+handlerName);
}
}
}});
You can use it as you want I created a String and returned it to Unity and then parsed it.
But this code is working with Latest Google Play Services.
Thanks
My Solution which worked is as follows which is for the latest game play services.
Games.Leaderboards.loadTopScores(mGamesClint,LEADERBOARD_ID, LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC, 5).setResultCallback(new ResultCallback<Leaderboards.LoadScoresResult>() {
public void onResult(LoadScoresResult arg0) {
// TODO Auto-generated method stub
int size = arg0.getScores().getCount();
for ( int i = 0; i < 3; i++ ) {
LeaderboardScore lbs = arg0.getScores().get(i);
String name = lbs.getScoreHolderDisplayName();
String score = lbs.getDisplayScore();
Uri urlimage = lbs.getScoreHolderHiResImageUri();
}
}
you can get all the data from leaderboard users here including high resolution image ie. profile picture.
Hope you get the idea here.
This code gets you the top 5 scores on your leaderboard.
private LeaderboardsClient mLeaderboardsClient;
mLeaderboardsClient.loadTopScores("HgkF9bOSF_UPAAILKE", LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC,5,true).addOnSuccessListener(new OnSuccessListener<AnnotatedData<LeaderboardsClient.LeaderboardScores>>() {
#Override
public void onSuccess(AnnotatedData<LeaderboardsClient.LeaderboardScores> leaderboardScoresAnnotatedData) {
LeaderboardScoreBuffer scoreBuffer = leaderboardScoresAnnotatedData.get().getScores();
Iterator<LeaderboardScore> it = scoreBuffer.iterator();
while(it.hasNext()){
LeaderboardScore temp = it.next();
Log.d("PlayGames", "player"+temp.getScoreHolderDisplayName()+" id:"+temp.getRawScore() + " Rank: "+temp.getRank());
}
}
});
Related
I'm getting errors when trying to get a player's scores across all leaderboards, in order to store locally.
My Android game is designed to be played offline, so I store high score and lifetime scores locally for each game mode.
Now I am working on adding leaderboards to my game. During the game play, I periodically post these scores to the leaderboards. So far so good.
Naturally, I need to cover the scenario where a user either uninstalls my game or moves to a new device, etc. In that scenario, when they sign in again to Google, I need to update the scores that are on leaderboards back into my local version.
Here's where I seem to get 26504 - NETWORK_ERROR_NO_DATA when I make the 4th call.
I have tried to wait until the 3rd call is complete and then fire the 4th one but I still get the same error. So I haven't even been able to add code for the 5-6 additional scores I will still need to retrieve.
getScoresFromLeaderboards(GAME_MODE_FIXED_QUESTIONS, SCORE_HIGH);
getScoresFromLeaderboards(GAME_MODE_FIXED_QUESTIONS, SCORE_LIFETIME);
getScoresFromLeaderboards(GAME_MODE_RAPID_FIRE, SCORE_HIGH);
getScoresFromLeaderboards(GAME_MODE_RAPID_FIRE, SCORE_LIFETIME);
Then...
public long getScoresFromLeaderboards(final String gameMode, final String scoreType) {
final int scoreHigh = 0, scoreLifetime = 0;
String leaderboardID = getLeaderboardForGameMode(gameMode, scoreType);
mLeaderboardsClient.loadCurrentPlayerLeaderboardScore(leaderboardID, LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC )
.addOnCompleteListener(new OnCompleteListener<AnnotatedData<LeaderboardScore>>() {
#Override
public void onComplete(#NonNull Task<AnnotatedData<LeaderboardScore>> task) {
if (task.isSuccessful()) {
AnnotatedData<LeaderboardScore> lbs = task.getResult();
long i = lbs.get().getRawScore();
// Do something to store the score locally
}
else{
Log.Error("Error", "Retrieval failed");
}
}
I would suggest another approach to using "loadCurrentPlayerLeaderboardScore" which has the 3 query limit
Use loadPlayerCenteredScores instead . Limit the scores to 1. The resultant buffer will return only the player score. You are now in the user quota of 500 requests instead of 3.
long limitResultsTo = 1;
String PlayerID = "-1"; // set this from playersClient.getCurrentPlayer() ->task-> getPlayerId()
String leaderboardID = getString(R.string.leaderboard_name); // or string of ID
Games.getLeaderboardsClient(this, GoogleSignIn.getLastSignedInAccount(this))
.loadPlayerCenteredScores(leaderboardName, LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC, limitResultsTo)
.addOnSuccessListener(new OnSuccessListener<AnnotatedData<LeaderboardsClient.LeaderboardScores>>() {
#Override
public void onSuccess(AnnotatedData<LeaderboardsClient.LeaderboardScores> leaderboardScoreAnnotatedData) { // big ups Danoli3.com for the fix for loadCurrentPlayerLeaderboardScore
LeaderboardsClient.LeaderboardScores scoresResult = leaderboardScoreAnnotatedData.get();
LeaderboardScore scoreResult = (scoresResult != null ? scoresResult.getScores().get(0) : null);
long score = 0;
if(scoreResult != null && scoreResult.getScoreHolder() != null &&
PlayerID.equals(scoreResult.getScoreHolder().getPlayerId())) // else if the player has 0 score it will retrieve top player
score = scoreResult.getRawScore();
// use the score in your own code here
// Log.i(TAG, "loadPlayerCenteredScores:" + leaderboardID + " score:" + score);
leaderboardScoreAnnotatedData = null;
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "Failure:loadPlayerCenteredScores GPG:Leader:" + leaderboardID + " Ex:" + e.getMessage());
}
everything works fine when creating a room and automatch too, but the problem is when i call p.getDisplayName(), in this code it dosn't return the opponent name it returns some junk letters ..
void updatePeerScoresDisplay() {
((TextView) findViewById(R.id.score0)).setText(formatScore(mScore) + " - Me");
int[] arr = {
R.id.score1, R.id.score2, R.id.score3
};
int i = 0;
if (mRoomId != null) {
for (Participant p : mParticipants) {
String pid = p.getParticipantId();
if (pid.equals(mMyId))
continue;
if (p.getStatus() != Participant.STATUS_JOINED)
continue;
int score = mParticipantScore.containsKey(pid) ? mParticipantScore.get(pid) : 0;
((TextView) findViewById(arr[i])).setText(formatScore(score) + " - "+
p.getDisplayName());
++i;
}
}
It returns something like Player234, it won't return the player's name, even if he/she is in your circles (as I have experienced). That's the point of a random opponent match.
google play game realtime multiplayer how to get quickmatch player's name?
My problem is I have around 1000+ records in an Android App
string field1;
string field2;
string field3;
string field4;
//...
I want to search in this set of records and get the best results on two fields (field1 and field2).
Currently I read each record and compare() (string compare) with the text i want to search so that takes a long time.
What is the best method to perform search?
Store each records in SQLite DB and do "select query where like"
Hash-Mapped
? any other suggestions?
Or may be create an Index of the records and do search.
If you want to search for not exact matches, I would try to make an ArrayList of MyAppRecord where
public class MyAppRecord {
private String record;
private int deviance;
}
and get for each record the deviance of the String you want to find with:
public static int getLevenshteinDistance (String s, String t) {
if (s == null || t == null) {
throw new IllegalArgumentException("Strings must not be null");
}
int n = s.length(); // length of s
int m = t.length(); // length of t
if (n == 0) {
return m;
} else if (m == 0) {
return n;
}
int p[] = new int[n+1]; //'previous' cost array, horizontally
int d[] = new int[n+1]; // cost array, horizontally
int _d[]; //placeholder to assist in swapping p and d
// indexes into strings s and t
int i; // iterates through s
int j; // iterates through t
char t_j; // jth character of t
int cost; // cost
for (i = 0; i<=n; i++) {
p[i] = i;
}
for (j = 1; j<=m; j++) {
t_j = t.charAt(j-1);
d[0] = j;
for (i=1; i<=n; i++) {
cost = s.charAt(i-1)==t_j ? 0 : 1;
// minimum of cell to the left+1, to the top+1, diagonally left and up +cost
d[i] = Math.min(Math.min(d[i-1]+1, p[i]+1), p[i-1]+cost);
}
// copy current distance counts to 'previous row' distance counts
_d = p;
p = d;
d = _d;
}
// our last action in the above loop was to switch d and p, so p now
// actually has the most recent cost counts
return p[n];
}
}
save it to your MyAppRecord-object and finally sort your ArrayList by the deviance of its MyAppRecord-objects.
Note that this could take some time, depending on your set of records. And NOTE that there is no way of telling wether dogA or dogB is on a certain position in your list by searching for dog.
Read up on the Levensthein distance to get a feeling on how it works. You may get the idea of sorting out strings that are possibly to long/short to get a distance that is okay for a threshold you may have.
It is also possible to copy "good enough" results to a different ArrayList.
I am getting an unusual result when attempting to place a value in an array.
I have an array table[] of a simple class result{ int score, long time, string ID}
Intention is to have a sort of leader board.
My code happily finds the correct place to insert a new score if it is in the top 10.
int ix = 0;
int jx = 10; //
while ( ix < jx )
{
if (points > sTable[ix].points)
{
// score is higher move records down
for (jx = mNumRecords - 1; jx >ix ; jx--)
{
sTable[jx] = sTable[jx -1];
}
//now add new score
sTable[ix].score = score; // all good until here
sTable[ix].time = time;
}
ix++;
}
Problem is that when I try to insert the score using sTable[ix].score = score;
The value gets written to sTable[ix].score and also sTable[ix +1].score.
It is repeatable, it occurs at any value of ix, I have single stepped through the code and as far as I can tell the command only executes once.
Has anyone seen this before?
That because you copied the object reference to the next element in the array. You should copy the values, or create a new object:
Option A:
// score is higher move records down
for (jx = mNumRecords - 1; jx >ix ; jx--)
{
sTable[jx].time = sTable[jx -1].time;
sTable[jx].score = sTable[jx -1].score;
}
//now add new score
sTable[ix].score = score; // all good until here
sTable[ix].time = time;
Option B:
for (jx = mNumRecords - 1; jx >ix ; jx--)
{
sTable[jx] = sTable[jx -1];
}
sTable[ix] = new Result(score, time, ""); // Or however you construct the object
Using the text to speech API I want to change the string array to increment from index 0 string and when it reaches the end it will go back to the beginning.
At the moment it uses a random generator and the method works as follows:
public static void sayHello() {
// Select a random hello.
int helloLength = HELLOS.length;
String hello = HELLOS[RANDOM.nextInt(helloLength)];
mTts.speak(hello,
TextToSpeech.QUEUE_FLUSH, // Drop all pending entries in the playback queue.
null);
}
HELLOS is the array and it holds the strings:
String [] HELLOS = {"One" "Two" "Three" "Four"};
Appreciate any help
Thanks.
When you want to increment an index but loop around to zero again modulo is your friend.
int currentHelloIndex = 0;
public static void sayHello() {
// Select a random hello.
int helloLength = HELLOS.length;
String hello = HELLOS[currentHelloIndex];
currentHelloIndex = (currentHelloIndex + 1) % helloLength;
mTts.speak(hello,
TextToSpeech.QUEUE_FLUSH, // Drop all pending entries in the playback queue.
null);
}