Tuesday, April 16, 2013

Adding Mobile Service to Whack-a-bug - PART 1

In a weak (beer influenced) moment on the Microsoft Windows Azure Gaming Summit on April 9th I promised someone that I'd make a point out of how simple it would be to add an online hiscore list to my development tool/game called "whack-a-bug". Since I'm a man of my word I sat down and did so. In less than an hour.

Whack-a-bug is a game, designed and constructed within 8 hours just to prove a point that developing for Windows Store is easy and deployment is fast.



"The game is very simple, whack those bugs and avoid destroying unit-tests."

The features I added was the ability to post your score to an online hiscore-list if your sprint is successful. Authentication will not be included in this first post but my plans are to incorprate that in a subsequent post.

So the outline of my work is

  • Create a Mobile Service
  • Wire up Whack-a-bug to that Mobile Service
  • Post data to a hiscore-table
  • Retrieve the hiscore list
  • Play the game!


And YES I know, since we are not adding authentication, anyone can post using any name at the moment. :)

Create a Mobile Service


The process is pretty straight forward. I browsed to http://www.azure.com and sign in (create account if necessary).

I selected "MOBILE SERVICES" on the left and clicked "CREATE NEW MOBILE SERVICE". The dialog below appeard and I simply typed in whackabug as the URL. A also chose to create a new database, you can also select an existing database. Lastly, I set the region to East US.

The service is then created for you. It takes less than half a minute to have it up and running. When it's done it looks this.


Wire up Whack-a-bug to Mobile Services


It's very simple to wire up you application. Just select the platform you are interested in and read the instructions. In my case it's a Windows Store app and I've already installed Mobile Services SDK. The SDK is also available on nuget.

What I did was to copy the codesnippet to my project as described.


Post data to a hiscore-table


Mobile Services is configured default to accept dynamic schema. That means that we just have to create a simple POCO with our required fields. But you do need to create the table in the portal. I created a table called "HiscoreEntry". The name is important to remember since you need to create a POCO class with the same name.


In the Create New Table dialog you enter the name of the table and then set permissions. For the first part of this blog series will just allow any application with the correct application key to perform any CRUD operation. The application key is a long string that I masked out in the code snippet we copied in the step before.

The POCO I created looks like this.

 public class HiscoreEntry  
 {  
   public int Id { get; set; }  
   public int BugsKilled { get; set; }  
   public string Username { get; set; }  
 }  

Simple enough! One thing worth pointing out when using dynamic schema is that you must provide a value for nullable types, like string. Otherwise the serializer will serialize this as JSON object with the value set to null. Mobile Services cannot create a column based on null since it wouldn't know the type. Check out this blog post for some more info around this specific tip: http://timrayburn.net/blog/working-with-dynamic-schema-in-azure-mobile-services

Well, back to Whack-a-bug. The UI needed to be modified. I added a textbox for the username and a button to submit the score to the game over control. These are only displayed if the sprint was successful. We also check that we have entered something in the box before posting it.

The post method looks like this:

 private async void SubmitScore(string username, string bugsKilled)  
 {  
   var item = new HiscoreEntry()  
   {  
     Username = username,  
     BugsKilled = bugsKilled  
   };  
   var table = App.MobileService.GetTable<HiscoreEntry>();  
   await table.InsertAsync(item);  
 }  

Error handling code is omitted for the sake of simplicity. But you should wrap the insert in an exception-handler.

Retrieve the hiscore list


I needed a placed the hiscore list in a UserControl with the pinned note background. The data is displayed in a grid. After that I wrote some code to retrieve the hiscore list. For this we need to query mobile services for the top eight players. Why eight? I didn't feel like redrawing the background! :)

I also make use of the wonder that is await/async when I populate the data into the grid.

 public async void ReloadData()  
 {  
   var table = App.MobileService.GetTable<HiscoreEntry>();  
   var list = await table.OrderByDescending(e => e.BugsKilled).Take(6).ToListAsync();  
   HiscoreListView.ItemsSource = list;  
 }  

The HiscoreListView is a simple ListView with an ItemTemplate defined like below.

     <ListView x:Name="HiscoreListView" Width="200" Canvas.Left="59" Canvas.Top="66">  
       <ListView.ItemTemplate>  
         <DataTemplate>  
           <Grid Width="170" Height="30">  
             <Grid.ColumnDefinitions>  
               <ColumnDefinition Width="1*"></ColumnDefinition>  
               <ColumnDefinition Width="1*"></ColumnDefinition>  
             </Grid.ColumnDefinitions>  
             <TextBlock Grid.Column="0" Text="{Binding Username}" FontSize="18" Foreground="Black" />  
             <TextBlock Grid.Column="1" Text="{Binding BugsKilled}" FontSize="18" Foreground="Black" TextAlignment="Right" />  
           </Grid>  
         </DataTemplate>  
       </ListView.ItemTemplate>  
       <ListView.ItemContainerStyle>  
         <Style TargetType="ListViewItem">  
           <Setter Property="Height" Value="30" />  
         </Style>  
       </ListView.ItemContainerStyle>  
     </ListView>  

That's it!



You can download it by clicking on this link!

Of course, the obvious problems with this example is that we don't have any error handling and no user authentication. The error handling will be added before I submit the final version to the store. When I do so, I'll edit this post and add what I did below.

No comments:

Post a Comment