Click here to Skip to main content
15,880,299 members
Articles / Mobile Apps / Windows Phone 7

How To: Use leaderboards on Windows Phone with XPG

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
31 Jan 2012CPOL3 min read 26.4K   2   7
Use leaderboards on Windows Phone with XPG

This is a continuation of the How To series. This first 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 along side 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 the XPG Management App were loaded in-game. Once these leaderboards were loaded, the first page of scores for each of them was also retrieved and loaded. All the objects provided in the XPG API for Windows Phone implement the INotifyPropertyChanged interface to provide UI binding support in XAML and to simplify your coding effort.

Here’s an example of binding to the leaderboard specified in a navigation parameter.

C#
#region OnNavigatedTo
/// <summary>Handles the page being navigated to.</summary>
/// <param name="e">The arguments.</param>
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    string lbTag = NavigationContext.QueryString["lbTag"];
    if (string.IsNullOrWhiteSpace(lbTag)) { NavigationService.GoBack(); }

    if (XPGAPI.Instance.CurrentGame != null && 
    XPGAPI.Instance.CurrentGame.Leaderboards != null)
    {
        lb = XPGAPI.Instance.CurrentGame.Leaderboards.Where
    (x => x.LeaderboardTag.Equals(lbTag, StringComparison.OrdinalIgnoreCase)).
    FirstOrDefault();
        if (lb == null) { NavigationService.GoBack(); }

        SetBinding(DataContextProperty, new Binding() { Source = lb });
    }
}
#endregion OnNavigatedTo

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.

C#
#region mButtonScoreHigh_Click
/// <summary>Handles the high score button being clicked.</summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The arguments of the event.</param>
private void mButtonScoreHigh_Click(object sender, RoutedEventArgs e)
{
    int scoreUpAmount = 10;
    XPGLeaderboardScoreInfo score = lb.Scores.FirstOrDefault();
    if (score != null)
    {
        XPGAPI.Instance.SubmitScore(lb.LeaderboardTag, 
        score.UserScore + scoreUpAmount, SubmitScoreCompleted);
    }
    else
    {
        XPGAPI.Instance.SubmitScore
    (lb.LeaderboardTag, scoreUpAmount, SubmitScoreCompleted);
    }
}
#endregion mButtonScoreHigh_Click

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.

C#
#region mButtonRefresh_Click
/// <summary>Handles the refresh button being clicked.</summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The arguments of the event.</param>
private void mButtonRefresh_Click(object sender, RoutedEventArgs e)
{
    // On Windows Phone, this will invoke binding events that update the UI
    XPGAPI.Instance.GetScores(lb.LeaderboardTag, 0, GetScoresCompleted);
}
#endregion mButtonRefresh_Click

The full code

XML
<phone:PhoneApplicationPage 
    x:Class="XPG.Demo.WinPhone.PageLeaderboard"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="PageTitle" Text="XPG WP7 Demo" 
        Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle2Style}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel>
                <TextBlock x:Name="mTextBlockTitle" Text="{Binding DisplayName}" 
            Style="{StaticResource PhoneTextLargeStyle}"/>
                <StackPanel Orientation="Horizontal">
                    <Button x:Name="mButtonRefresh" Click="mButtonRefresh_Click" 
            Content="Refresh" />
                    <Button x:Name="mButtonScoreHigh" Click="mButtonScoreHigh_Click" 
            Content="High" />
                    <Button x:Name="mButtonScoreMed" Click="mButtonScoreMed_Click" 
            Content="Med" />
                    <Button x:Name="mButtonScoreLow" Click="mButtonScoreLow_Click" 
            Content="Low" />
                </StackPanel>
                <ListBox x:Name="mListBoxScores" ItemsSource="{Binding Scores}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal" >
                                <TextBlock Text="User: " />
                                <TextBlock Text="{Binding UserNameDisplay}" />
                                <TextBlock Margin="15, 0, 0, 0" Text="Score: "/>
                                <TextBlock Text="{Binding UserScore}" />
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
        </Grid>
    </Grid>

</phone:PhoneApplicationPage>
using System;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using Microsoft.Phone.Controls;

namespace XPG.Demo.WinPhone
{
    /// <summary>The leaderboard detail page.</summary>
    public partial class PageLeaderboard : PhoneApplicationPage
    {
        #region Member Variables

        /// <summary>The selected leaderboard.</summary>
        private XPGLeaderboardInfo lb;

        #endregion Member Variables

        #region Constructors

        /// <summary>Creates a new instance of <see cref="PageLeaderboard" />.</summary>
        public PageLeaderboard()
        {
            InitializeComponent();
        }

        #endregion Constructors

        #region Event Handlers

        #region mButtonRefresh_Click
        /// <summary>Handles the refresh button being clicked.</summary>
        /// <param name="sender">The sender of the event.</param>
        /// <param name="e">The arguments of the event.</param>
        private void mButtonRefresh_Click(object sender, RoutedEventArgs e)
        {
            XPGAPI.Instance.GetScores(lb.LeaderboardTag, 0, GetScoresCompleted);
        }
        #endregion mButtonRefresh_Click

        #region mButtonScoreHigh_Click
        /// <summary>Handles the high score button being clicked.</summary>
        /// <param name="sender">The sender of the event.</param>
        /// <param name="e">The arguments of the event.</param>
        private void mButtonScoreHigh_Click(object sender, RoutedEventArgs e)
        {
            int scoreUpAmount = 10;
            XPGLeaderboardScoreInfo score = lb.Scores.FirstOrDefault();
            if (score != null)
            {
                XPGAPI.Instance.SubmitScore(lb.LeaderboardTag, 
        score.UserScore + scoreUpAmount, SubmitScoreCompleted);
            }
            else
            {
                XPGAPI.Instance.SubmitScore(lb.LeaderboardTag, 
            scoreUpAmount, SubmitScoreCompleted);
            }
        }
        #endregion mButtonScoreHigh_Click

        #region mButtonScoreLow_Click
        /// <summary>Handles the low score button being clicked.</summary>
        /// <param name="sender">The sender of the event.</param>
        /// <param name="e">The arguments of the event.</param>
        private void mButtonScoreLow_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                XPGLeaderboardScoreInfo score = lb.Scores[0];
                XPGAPI.Instance.SubmitScore(lb.LeaderboardTag, 
            score.UserScore + 1, SubmitScoreCompleted);
            }
            catch
            {
                XPGAPI.Instance.SubmitScore(lb.LeaderboardTag, 1, SubmitScoreCompleted);
            }
        }
        #endregion mButtonScoreLow_Click

        #region mButtonScoreMed_Click
        /// <summary>Handles the medium score button being clicked.</summary>
        /// <param name="sender">The sender of the event.</param>
        /// <param name="e">The arguments of the event.</param>
        private void mButtonScoreMed_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                XPGLeaderboardScoreInfo score = lb.Scores[0];
                XPGAPI.Instance.SubmitScore(lb.LeaderboardTag, 
            score.UserScore + 5, SubmitScoreCompleted);
            }
            catch
            {
                XPGAPI.Instance.SubmitScore(lb.LeaderboardTag, 5, SubmitScoreCompleted);
            }
        }
        #endregion mButtonScoreMed_Click

        #region OnNavigatedTo
        /// <summary>Handles the page being navigated to.</summary>
        /// <param name="e">The arguments.</param>
        protected override void OnNavigatedTo
        (System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            string lbTag = NavigationContext.QueryString["lbTag"];
            if (string.IsNullOrWhiteSpace(lbTag)) { NavigationService.GoBack(); }

            if (XPGAPI.Instance.CurrentGame != null && 
        XPGAPI.Instance.CurrentGame.Leaderboards != null)
            {
                lb = XPGAPI.Instance.CurrentGame.Leaderboards.Where
        (x =>

License

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.
This is a Organisation (No members)


Comments and Discussions

 
QuestionNo longer suppoted!! Pin
Hamzeh soboh11-Dec-12 0:08
professionalHamzeh soboh11-Dec-12 0:08 
QuestionSample for XNA Pin
AmitDey24-Apr-12 8:14
AmitDey24-Apr-12 8:14 
AnswerRe: Sample for XNA Pin
XPG Live24-Apr-12 8:18
XPG Live24-Apr-12 8:18 
GeneralRe: Sample for XNA Pin
AmitDey24-Apr-12 8:23
AmitDey24-Apr-12 8:23 
GeneralRe: Sample for XNA Pin
XPG Live24-Apr-12 8:46
XPG Live24-Apr-12 8:46 
GeneralRe: Sample for XNA Pin
XPG Live24-Apr-12 9:12
XPG Live24-Apr-12 9:12 
Where's a direct link to the XNA sample code: http://www.xpglive.com/en/downloads/latest/XPG-API-Demo-Source-WinPhoneXNA.zip[^]
GeneralRe: Sample for XNA Pin
AmitDey24-Apr-12 19:46
AmitDey24-Apr-12 19:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.