Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Blackberry

How To: Use Leaderboards on BlackBerry with XPG

0.00/5 (No votes)
6 Feb 2012CPOL3 min read 11.6K  
This post will cover leaderboard types and setup, accessing leaderboards in game, posting a score to a leaderboard, retrieving scores from a leaderboard.

This is a continuation of the How To series. This previous post is here.

This article will cover:

  • Leaderboard types and setup
  • Accessing leaderboards in game
  • Posting a score to a leaderboard
  • Retrieving scores from a leaderboard

Prerequisites

Leaderboard types and setup

In order to setup a leaderboard, you’ll need to have a free developer account with XPG and have registered a game in the management app. Assuming you’ve done these things, you can click on the leaderboards tab in the management app and begin defining your leaderboards.

image

In the above image, you can see the leaderboard dialog. As with most display values in the XPG system, the leaderboard name is globalized to help you provide a local experience for the end user. A display image can be defined by clicking the icon in the top right corner. The XPG system allows you to define a game-unique identifier for your leaderboard which is particularly helpful when migrating from another system to XPG, or implementing XPG alongside another system. The available score types are Float, Integer, Money, and Time and each can be used with a score order of Ascending or Descending. The score order indicates if the high scores take high ranks (Descending) or if the lower scores take high ranks (Ascending). You can also limit this leaderboard’s availability by game version. Game versions are defined on the Access Keys tab in the Games area of the management app. Each version gets a new access key (or secret key) which positively identifies your game and game version.

image

Accessing leaderboards in game

As with many things in XPG, accessing leaderboards within your game is very simple. When your game was initialized (discussed in this post) the leaderboards defined in there were loaded in-game. Once these leaderboards were loaded, the first page of scores for each of them was also retrieved and loaded.

Java
public ScreenLeaderboard(XPGLeaderboardInfo leaderboard) {
    super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR);

    if (leaderboard == null) {
        close();
    }

    lb = leaderboard;

    grid = new GridFieldManager(20, 1, FIELD_LEFT);
    managerRow1 = new HorizontalFieldManager(FIELD_LEFT);

    labelInfo = new LabelField(lb.getDisplayName());
    managerRow1.add(buttonRefresh);
    managerRow1.add(buttonScoreHigh);
    managerRow1.add(buttonScoreMed);
    managerRow1.add(buttonScoreLow);

    grid.add(labelInfo, FIELD_LEFT);
    grid.add(managerRow1, FIELD_LEFT);
}

Posting a score to a leaderboard

There are overloads provided to work with each of the score types mentioned above. The API will perform local updates of the leaderboard data after posting a score to the server when it detects that no user data from other players has affected the ranking other than the local user. Alternatively, the API will also initiate a full update of the leaderboard local data if it detects that one or more users have affected the leaderboard ranking other than the local user. This is all handled auto-magically in order to conserve bandwidth, processor time, and device battery.

Here is an example of score posting simplicity.

Java
buttonScoreHigh.setCommand(new Command(new CommandHandler() {
    public void execute(ReadOnlyCommandMetadata metadata, Object context) {
        if (userScore != null) {
            XPGAPI.Instance.submitScore(
                    lb.getLeaderboardTag(),
                    new Double(
                            userScore.getUserScore().doubleValue() + 10),
                    null);
        } else {
            try {
                XPGLeaderboardScoreInfo score = ((XPGLeaderboardScoreInfo) scores
                        .elementAt(0));
                XPGAPI.Instance.submitScore(
                        lb.getLeaderboardTag(),
                        new Double(
                                score.getUserScore().doubleValue() + 10),
                        null);
            } catch (Exception e) {
                XPGAPI.Instance.submitScore(lb.getLeaderboardTag(),
                        new Double(10), null);
            }
        }
    }
}));

Retrieving scores from a leaderboard

Retrieving scores from XPG is equally simple. The scores are stored locally on the leaderboard instance of the initialized game instance, so there are no collections for you to keep up with and manage on your own. Also, leaderboards support paging, so you are not required to have all the ranked user scores in memory at once.

Java
//Hook event to trigger getting scores
buttonRefresh.setCommand(new Command(new CommandHandler() {
    public void execute(ReadOnlyCommandMetadata metadata, Object context) {
        XPGAPI.Instance.getScores(lb.getLeaderboardTag(), new Long(0),
                null);
    }
}));

//Set GetScores callback
XPGAPI.Instance.setCallbackGetScores(new XPGAPICallbackGetScores() {
    public void gotResponse(XPGAPIResponse response,
            XPGScoresResultInfo body) {
        if (!response.getFailed().booleanValue() && body != null) {
            clearScores();
            scores = body.getScores();
            displayScores();
        }
    }
});

// Clear previously displayed scores
private void clearScores() {
    grid.deleteRange(2, grid.getRowCount() - 2);
}

// Displayed new scores from server
private void displayScores() {
    if (scores != null && scores.size() > 0) {
        for (int i = 0; i < scores.size(); i++) {
            final XPGLeaderboardScoreInfo score = (XPGLeaderboardScoreInfo) scores
                    .elementAt(i);
            HorizontalFieldManager hfm = new HorizontalFieldManager(
                    FIELD_LEFT);
            LabelField labelUser = new LabelField("User: "
                    + score.getUserNameDisplay());
            labelUser.setMargin(0, 15, 0, 0);
            LabelField labelScore = new LabelField("Score: "
                    + String.valueOf(score.getUserScore()));

            hfm.add(labelUser);
            hfm.add(labelScore);
            grid.add(hfm, Field.FIELD_LEFT);
            if (score.getUserName().equalsIgnoreCase(
                    XPGAPI.Instance.getCurrentUser().getUserName())) {
                userScore = score;
            }
        }
    }
}

Full Code

Java
package XPG.Demo.BlackBerry;

import java.util.Vector;

import net.rim.device.api.command.Command;
import net.rim.device.api.command.CommandHandler;
import net.rim.device.api.command.ReadOnlyCommandMetadata;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.GridFieldManager;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;

import com.xpglive.api.XPGAPI;
import com.xpglive.api.XPGAPICallbackGetScores;
import com.xpglive.api.XPGAPICallbackSubmitScore;
import com.xpglive.api.XPGAPIResponse;
import com.xpglive.api.XPGLeaderboardInfo;
import com.xpglive.api.XPGLeaderboardScoreInfo;
import com.xpglive.api.XPGScoreResultInfo;
import com.xpglive.api.XPGScoresResultInfo;

public class ScreenLeaderboard extends MainScreen {
    private GridFieldManager grid;
    HorizontalFieldManager managerRow1;
    private LabelField labelInfo;
    private ButtonField buttonRefresh = new ButtonField("Refresh");
    private ButtonField buttonScoreHigh = new ButtonField("High");
    private ButtonField buttonScoreMed = new ButtonField("Med");
    private ButtonField buttonScoreLow = new ButtonField("Low");
    private XPGLeaderboardInfo lb;
    private XPGLeaderboardScoreInfo userScore;

    private Vector scores;

    public ScreenLeaderboard(XPGLeaderboardInfo leaderboard) {
        super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR);

        if (leaderboard == null) {
            close();
        }

        lb = leaderboard;

        grid = new GridFieldManager(20, 1, FIELD_LEFT);
        managerRow1 = new HorizontalFieldManager(FIELD_LEFT);

        labelInfo = new LabelField(lb.getDisplayName());
        managerRow1.add(buttonRefresh);
        managerRow1.add(buttonScoreHigh);
        managerRow1.add(buttonScoreMed);
        managerRow1.add(buttonScoreLow);

        grid.add(labelInfo, FIELD_LEFT);
        grid.add(managerRow1, FIELD_LEFT);

        buttonRefresh.setCommand(new Command(new CommandHandler() {
            public void execute(ReadOnlyCommandMetadata metadata, Object context) {
                XPGAPI.Instance.getScores(lb.getLeaderboardTag(), new Long(0),
                        null);
            }
        }));

        buttonScoreHigh.setCommand(new Command(new CommandHandler() {
            public void execute(ReadOnlyCommandMetadata metadata, Object context) {
                if (userScore != null) {
                    XPGAPI.Instance.submitScore(
                            lb.getLeaderboardTag(),
                            new Double(
                                    userScore.getUserScore().doubleValue() + 10),
                            null);
                } else {
                    try {
                        XPGLeaderboardScoreInfo score = ((XPGLeaderboardScoreInfo) scores
                                .elementAt(0));
                        XPGAPI.Instance.submitScore(
                                lb.getLeaderboardTag(),
                                new Double(
                                        score.getUserScore().doubleValue() + 10),
                                null);
                    } catch (Exception e) {
                        XPGAPI.Instance.submitScore(lb.getLeaderboardTag(),
                                new Double(10), null);
                    }
                }
            }
        }));

        buttonScoreMed.setCommand(new Command(new CommandHandler() {
            public void execute(ReadOnlyCommandMetadata metadata, Object context) {
                if (userScore != null) {
                    XPGAPI.Instance.submitScore(
                            lb.getLeaderboardTag(),
                            new Double(
                                    userScore.getUserScore().doubleValue() + 5),
                            null);
                } else {
                    try {
                        XPGLeaderboardScoreInfo score = ((XPGLeaderboardScoreInfo) scores
                                .elementAt(0));
                        XPGAPI.Instance.submitScore(
                                lb.getLeaderboardTag(),
                                new Double(
                                        score.getUserScore().doubleValue() + 5),
                                null);
                    } catch (Exception e) {
                        XPGAPI.Instance.submitScore(lb.getLeaderboardTag(),
                                new Double(5), null);
                    }
                }
            }
        }));

        buttonScoreLow.setCommand(new Command(new CommandHandler() {
            public void execute(ReadOnlyCommandMetadata metadata, Object context) {
                if (userScore != null) {
                    XPGAPI.Instance.submitScore(
                            lb.getLeaderboardTag(),
                            new Double(
                                    userScore.getUserScore().doubleValue() + 1),
                            null);
                } else {
                    try {
                        XPGLeaderboardScoreInfo score = ((XPGLeaderboardScoreInfo) scores
                                .elementAt(0));
                        XPGAPI.Instance.submitScore(
                                lb.getLeaderboardTag(),
                                new Double(
                                        score.getUserScore().doubleValue() + 1),
                                null);
                    } catch (Exception e) {
                        XPGAPI.Instance.submitScore(lb.getLeaderboardTag(),
                                new Double(1), null);
                    }
                }
            }
        }));

        XPGAPI.Instance.setCallbackGetScores(new XPGAPICallbackGetScores() {
            public void gotResponse(XPGAPIResponse response,
                    XPGScoresResultInfo body) {
                if (!response.getFailed().booleanValue() && body != null) {
                    clearScores();
                    scores = body.getScores();
                    displayScores();
                }
            }
        });

        XPGAPI.Instance.setCallbackSubmitScore(new XPGAPICallbackSubmitScore() {
            public void gotResponse(XPGAPIResponse response,
                    XPGScoreResultInfo body) {
                if (!response.getFailed().booleanValue() && body != null) {
                    XPGAPI.Instance.getScores(lb.getLeaderboardTag(), new Long(
                            0), null);
                }
            }
        });

        add(grid);

        if (lb.getScores() != null && lb.getScores().size() > 0) {
            clearScores();
            scores = lb.getScores();
            displayScores();
        }
    }

    private void clearScores() {
        grid.deleteRange(2, grid.getRowCount() - 2);
    }

    private void displayScores() {
        if (scores != null && scores.size() > 0) {
            for (int i = 0; i < scores.size(); i++) {
                final XPGLeaderboardScoreInfo score = (XPGLeaderboardScoreInfo) scores
                        .elementAt(i);
                HorizontalFieldManager hfm = new HorizontalFieldManager(
                        FIELD_LEFT);
                LabelField labelUser = new LabelField("User: "
                        + score.getUserNameDisplay());
                labelUser.setMargin(0, 15, 0, 0);
                LabelField labelScore = new LabelField("Score: "
                        + String.valueOf(score.getUserScore()));

                hfm.add(labelUser);
                hfm.add(labelScore);
                grid.add(hfm, Field.FIELD_LEFT);
                if (score.getUserName().equalsIgnoreCase(
                        XPGAPI.Instance.getCurrentUser().getUserName())) {
                    userScore = score;
                }
            }
        }
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)