Windows 8 DevCamp and Hackathon Back in MSP

9/18/2012 2:17:59 PM

We will be having another Windows 8 Dev Camp on 10/9 at the Microsoft office in Edina.  We still have some space available, so sign up here – http://aka.ms/Win8Camp.

The next day, there will be a Windows 8 Hackathon with three grand prize winners getting a Samsung Series 7 Slate and more!  Register here – http://aka.ms/Win8Hackathon

Update:  Just informed that this particular event will not have the Slates as giveaways.  My bad for assuming we had the same format as in the past.

Tags:

Headlines | Windows 8

MDC Keynote Slides

9/18/2012 12:10:57 PM

I had a few requests for my keynote slides from the MDC.  You can download here.

Tags:

Windows 8 | Library

Ways You Can Use the Search Contract in Your Windows Game

9/18/2012 10:07:01 AM

ATTENTION:  Great resources for Windows 8 developers!!! Make sure you take advantage of 30 Days.

 

clip_image002The Search contract is a way you can integrate the Windows 8 search experience into your game. Windows 8 provides a Search feature that is enabled via the Charm bar (shown at right). The Charm bar is activated by a user swiping from the right edge of the screen with a finger, or by either a mouse or keyboard action (mouse to the upper right corner of the screen or Windows+C ). From the Charm bar, the user can select the Search charm and enter the default Search experience.

The default Search experience allows users to search through their files, applications, and settings to find things they are interested in. More interesting, however, is that this Search experience can be extended in two unique ways.

First, if you look at the default Search pane, you will see a list of applications in the bottom half of the pane. The Search pane allows the user to send the search term they have typed into the search text box to another application by tapping on its tile. Windows 8 will launch the selected app and pass the search term to the application. It is up to the application to use the search term in a way that makes sense for the app. For a game, this could be looking up the term in a help file, finding a match with online players, or looking in saved games for a possible match.

clip_image004The second way that Search can be extended is by integrating the search contract with an application while it is running. In this case, any search term entered would be immediately passed to your app. The Search panes is updated to show that the search term will be passed to your game and not to a more general search.

Getting Started

In a game scenario, it is most likely that the second option, “in game” searching, is the most applicable. There are a lot of potential uses for search. A few examples include searching help, looking up friends or “frenemies” to see who is playing online, finding units or game pieces on a board, and more. Fundamentally, all of these scenarios are handled the same. They only differ in how you will present the results to the player. Because “in game” searching is most common for games, let’s start with an example of how to hook a game into Windows 8 Search.

clip_image007In order to integrate with Search, it is important that you set up the Search Declaration in your game’s package.appxmanifest file. Double-click on the file in Solution Explorer, and then click on the Declaration tab. In the Available Declarations dropdown, select the Search Declaration and click the Add button. See the picture at the right for what your package.appxmanifest should look like when you are finished.

We are now ready to add Search to our game. In most cases, you can configure search in the page that serves as the entry point into your game. If you are starting with one of the default Visual Studio templates, this will be default.html and its corresponding script file, default.js. Hooking into search in this manner will provide search handling through the lifetime of your application. You can, however, connect to search from individual pages instead of the main page if this makes sense for your game. Just remember, you will need handle the search events in each page you want search enabled.

In the Application activated event handler, you will want to add the following code:

 

var searchPane = Windows.ApplicationModel.Search.SearchPane.getForCurrentView();
searchPane.onquerysubmitted = function (eventObject) {
 
   var query = eventObj.queryText;
 
   // handle query as necessary
}

This is the minimum required to receive a query typed into the Search pane. What you do with the query is up to you. You could navigate to a page that lists online friends that match the query, or navigate to a help page and list matching topics. You could simply highlight game pieces that match the search on the currently viewed game board.

You can also provide suggestions to the user as they enter text into the search field. Handle the suggestionsrequested event and provide suggestion responses in the function handler:

 

Windows.ApplicationModel.Search.SearchPane.getForCurrentView().onsuggestionsrequested = function (eventObject) {
 
   var queryText = eventObject.queryText, suggestionRequest = eventObject.request;
   var query = queryText.toLowerCase();
   var maxNumberOfSuggestions = 5;
 
   for (var i = 0, len = suggestionList.length; i < len; i++) {
      if (suggestionList[i].substr(0, query.length).toLowerCase() === query) {
         suggestionRequest.searchSuggestionCollection.appendQuerySuggestion(suggestionList[i]);
 
         if (suggestionRequest.searchSuggestionCollection.size === maxNumberOfSuggestions) {
             break;
         }
      }
};

You are only permitted to list a total of five suggestions. How you create suggestions and order them is up to you.

The suggestionsrequested event fires with every key stroke. If you are performing async operations as part of your suggestion lookup, you need to handle that appropriately. Below is some skeleton code that shows how to handle hitting a remote web service to lookup search suggestions. This could be hitting the cloud component of your game to compare the query to the names of online players, for example.

 

Windows.ApplicationModel.Search.SearchPane.getForCurrentView().onsuggestionsrequested = function (eventObject) {
 
   var queryText = eventObject.queryText, 
          language = eventObject.language,
          suggestionRequest = eventObject.request;
 
   var deferral = suggestionRequest.getDeferral();
 
   if (xhrRequest && xhrRequest.cancel) {
      xhrRequest.cancel();
   }
 
   xhrRequest = WinJS.xhr({ url: suggestionUri });
   xhrRequest.done(
       function (request) {
           if (request.responseText) {
               // process response
           }
           deferral.complete(); // Indicate we're done supplying suggestions.
       },
       function (error) {
           deferral.complete();
       });
   };
  }
};

There are a few things to point out. First, make sure you get a deferral from the request if you are going to be making async calls. This allows your handler to run async operations and still be able to notify the Search pane when you are finished. In addition, you should make sure you check that the async operation you started on the first key press is complete or cancelled before firing off another request on the second key press. You can see that we do that here by using a .done() on the xhrRequest, which returns undefined. If xhrRequest is not undefined, then we need to cancel that request. In our case, xhrRequest is defined outside the onsuggestionsrequested handler to ensure it “lives” between requests.

Wrapping Up

Using search is a great way to provide a consistent experience for your users. There are a lot of scenarios where search makes sense for a game, and you are only limited by your imagination on how to use it. You can find a great sample app that illustrates the techniques discussed here and more at http://code.msdn.microsoft.com/windowsapps/Search-app-contract-sample-118a92f5

Tags:

HTML | WinJS | Windows 8

Ways You can Leverage Share Contracts in your Windows Store Game

9/18/2012 9:35:48 AM

For more detailed information and examples, see Adding share (Metro style apps using JavaScript and HTML) article and the two share sample applications, Share Source and Share Target.  Make sure you take advantage of 30 Days.

 

One of the great new features available to developers creating Windows Store games is the Share Contract. The Share Contract, or sharing, provides an easy way for you to share data from your game to other applications the user has on their system.

Why is sharing useful? Games are, by their nature, social. Perhaps you are starting to play a game of Ultimate Zombie Battles and you want to let your friends know you are playing so they can come join you. You may want to let the world know that you just achieved a personal high score on Find the Chicken. Or better yet, you just downloaded a new game and you think it is so cool, you want to let your friend and family know about it so they can play it too.

As a game developer, you want to enable all these scenarios. It provides a great Windows 8 gaming experience, differentiates your game from those that don’t share, and it can create more awareness about your game. Ideally, you want to enable these scenarios because they are features your user wants and makes your game that much more enjoyable.

The Basics

sharebrokerLet’s start off by gaining a basic understanding of how sharing works and the steps required for an app to share data. Later, we will look at some specific scenarios, like those mentioned above, and how you would implement them in your game.  Fundamentally, sharing is a very simple operation. A share operation consists of three parts: the source application that is sharing some data, the data to be transferred via the share broker, and the target application that will receive and process the data. The share broker is provided by Windows 8 and mediates the data exchange between the source and target apps. The picture to the right shows how this process works.

The code below shows how an application that is a share source would provide data to be shared.

 

var share = Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();
share.ondatarequested = function (e) {
// Title of Share Options
e.request.data.properties.title = "New High Score";
 
// Description of what is being shared
e.request.data.properties.description = "You Scored 1,000pts";
 
// Share plain text
e.request.data.setText("Bob’s New High Score is 1,000pts in Zombie Battles");
};

sharepaneYou should always set the title and description properties. These properties provide context to the user when they are looking at the Share UI and give them confidence in what they are about to share. You can set a variety of different data types to share. In the example code, we are only sharing simple text data via the setText() function. You could however, share multiple data types in a single share request, and you are encouraged to do so.

In addition to sharing text, HTML, and images, there are a variety of other formats you can share, including custom data formats. The supported formatted are listed below:

  • Plain Text
  • Formatted text
  • URIs
  • HTML
  • Images
  • Files
  • Custom data formats

By providing multiple data types, you expand the total number of target applications the user can share your application’s data with, and you allow the target application to choose which data type it can use the best. For instance, if a target app can understand both text and HTML, it would likely prefer to use the HTML data format since it provides for more engaging way to display text.

Sharing Different Data Formats

When sharing a high score, we may want to provide something more engaging than a simple text string. You can craft a share request to use a variety of formats to provide a much nicer experience. In addition to text, you could provide HTML. This would allow the user to send the high score via email, share the high score image on a social network, etc. The variety of formats provides a richer experience for your users. Our share source example could be updated as shown:

 

   1:  var share = Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();
   2:   
   3:  share.ondatarequested = function (e) {
   4:   
   5:  e.request.data.properties.title = "New High Score";
   6:  e.request.data.properties.description = "You Scored 1,000pts";
   7:  e.request.data.setText("Bob set a New High Score of 1,000pts is Zombie Battles");
   8:   
   9:  var HTMLstr = "<b>Bob</b> <h3>New High Score</h3> is 1,000pts in <i>Zombie Battles</i>";
  10:   
  11:  // Format HTML 
  12:  e.request.data.setHTMLFormat(
  13:       Windows.ApplicationModel.DataTransfer.HTMLFormatHelper.createHTMLFormat(HTMLstr));
  14:  };

Notice, in the setHTMLFormat() function the need to call createHTMLFormat(). This prepares the HTML for use by the target application, and failure to call this on an HTML string will result in the target app not being able to display the transferred HTML.

Text and HTML are nice, but pictures are worth a thousand words. Sharing an image can add additional pizazz to your game’s share operation. Imagine your game is based on the player advancing from one level of difficulty to another. You may want to have an image, or a badge, that can be shared to show the player’s success. You have placed these badge images into your project just like any other asset so you can easily display them in an <img> tag on screen when congratulating your user. But how do you share an image that is part of your game’s install package with another application?

There are two ways to approach this. The first is that you just want to share the image itself. The second is you want to take some HTML that is being displayed onscreen, including the badge image, and turn that into your share payload.

In the first scenario, all we need to do is acquire a stream to the image file and hand that stream to the share target application. Here is how you do that:

 

var deferral = e.request.getDeferral();
 
var imageUri = new Windows.Foundation.Uri('ms-appx:///images/highscore.png');
Windows.Storage.StorageFile.getFileFromApplicationUriAsync(imageUri).then(function (imageFile) {
 
var streamReference = Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(imageFile);
 
request.data.properties.thumbnail = streamReference;
request.data.setStorageItems([imageFile]);
request.data.setBitmap(streamReference);
 
deferral.complete();

Going through this code, there are few things worth pointing out. First, since we will be performing an asynchronous call, it is a good idea to grab a deferral from the DataTranferManager request. This lets the DTM know that we are doing something that could take a while. In our case, we could probably skip this since we are making a relatively quick call to local assets, If you had a longer running process it is a good thing to do.

highscoreNext, notice how we craft the Uri to the local image. We prefix the file path with “ms-appx://”, letting WinRT know that we are accessing a local resource. We turn that into an Uri, and then use the getFileFromApplicationUriAsync() call to obtain the file itself, which we then turn into a stream. Since we are passing an image, it is a good idea to a) set the thumbnail property for apps that would like to use a thumbnail, and pass the stream reference via setStorageItems(). We do this because some apps will want to deal with images files as streams instead of actual bitmaps, thus giving our use a wider range of applications they can share with and more flexibility for the target app when working with our share payload.

Now, let’s handle sharing parts of our UX. You have crafted a nice “reward page” showing someone that they have achieved a new level, set a new high score, whatever. Inside that page is some HTML like the following:

<div id="HTMLFragment" class="HTMLFragment" style="margin-top: 20px;">
 
<h2>Top Score of the Day</h2>
 
<img id="fragmentImage" src="/images/highscore.png">
 
<p>Congratulations!</p>
 
</div>

This example is admittedly simple, but it has all the elements we need to demonstrate the technique. The important thing to realize is that we are including an <img> that’s src property is set to a local image file. We process the HTML for sharing like this:

var request = e.request;
var range = document.createRange();
var fragment = document.getElementById("HTMLFragment");
range.selectNode(fragment);
 
request.data = MSApp.createDataPackage(range);
request.data.properties.title = "Share Text Example";
request.data.properties.description = "Demo shows how to share text string";
 
var path = document.getElementById("fragmentImage").getAttribute("src");
var imageUri = new Windows.Foundation.Uri(path);
 
var streamReference = Windows.Storage.Streams.RandomAccessStreamReference.createFromUri(imageUri);
 
request.data.resourceMap[path] = streamReference;

Start by creating a range and selecting the HTML root element we want to send via our share operation. We convert that HTML into a fragment. There are img tags that need to have actual image files included in the payload so the fragment will render correctly. We grab the src Uri and create a stream reference that is passed as part of the resourceMap. The resource map will allow the target app to find the actual image and render it properly. In our example, there is a single image. If you have more than one image, you will need to find all the images in the fragment and repeat this process for each one.

Invoking Share

You will need to decide how you want to expose the opportunity to share information to your player. Over time, users will become accustomed to sharing data by swiping from the right edge of the screen to invoke the Charm bar, by hovering the mouse in the top-right corner, or pressing Windows Key+C . At times, however, it may not be obvious in your game that there is content that can be shared, or perhaps you want to emphasize that a particular item can be shared.

You can invoke the Share UI at any time from within your application via:

Windows.ApplicationModel.DataTransfer.DataTransferManager.showShareUI();

Being a Share Target

It is a less likely, given the highly specialized nature of a game, that you will need to be a share target. There are scenarios when being a share target makes sense. An example would be a game that also has a companion app, like a game map designer, a character designer, or something similar. In cases like that, you may want have your game to be a share target.

declarationsTo become a share target, the first thing you must do is declare that capability in your game’s package.appxmanifest file. Double-clicking on that file in Solution Explorer will open an editor. Click on the Declarations tab and you will see the screen shown at the right.

In the Available Declaration drop-down, select Share Target and click the Add button. This is step one. You must now add, using the settings to the right of the Supported Declarations pane, the Data Formats or File Types that you can accept.

In our map editor scenario, you could either use a unique file extension for saved map files or define a custom data format. The file extension approach is easy to understand. You save a map in the map editor, perhaps using the “.map” extension. You then set the Share Target setting on your game to by adding a new Supported File Type entry and set the value to “.map”. Now, from you game editor, you could simply share the saved “.map” file directly to the game, without the user having to launch the game and open the file. You game is still responsible for processing the “.map” file, but the user doesn’t have to leave the map editor to get the data to your game.

We will look at the other scenario, of working with a custom data type. It shares the same approach as the file type example, so it we are killing two birds with one stone. Let’s pretend we have a character editor that lets me build characters for the main game. In our character editor, we will share a custom data type and pass the character info as a JSON string. I won’t cover that here since the techniques are similar to what we have already looked at. If you want to see an example of doing that, check out the Share Source sample application here.

In our main game, we start by adding a new Data Format setting. In the textbox, you will enter a unique URI for you custom data format. Let’s set that to “http://mycoolgame.com/character”. At the bottom of the Declarations tab, with Share Target selected as the Supported Declaration, you will see a text box called Start Page. Here, you can enter the name of the HTML page that will be opened when your game is selected at the target of a share operation. You should design this page to reflect your game’s branding, colors, etc. Simply add a new page to the root of your project named ‘target.html, style it as necessary, and then types its name in the Start Page text box.

The more interesting aspect is handling the share operation. In the script file for target.html, you will want to do two things. Start handling the WinJS.Application activated event as shown below:

 

WinJS.Application.onactivated = function(e) {
 
    if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.shareTarget) {
 
           eventObject.setPromise(WinJS.UI.processAll());
           shareOperation = eventObject.detail.shareOperation;
 
           WinJS.Application.queueEvent({ type: "shareready" });
     }
};

There are two important things to note. First, we check to make sure that we are arriving at target.html via a shareTarget activation. Next, after we grab the data payload of the operation, we place an event on the Application queue. This is a user-defined event, not one provided by default. The reason we add a shareready event (or whatever you want to call it) to the queue is we want to return control to the system as soon as possible. By doing this, we can run our longer processes for parsing the data without slowing down the UI. Note, the variable shareoperation is defined elsewhere so that it is accessible to both the onactivated handler and the shareready handler.

In shareready, we can extract the data and update the UI on target.html as necessary.

 

function shareReady(eventArgs) {
 
   document.getElementById("title").innerText = shareOperation.data.properties.title;
   document.getElementById("description").innerText = shareOperation.data.properties.description;
 
   if (shareOperation.data.contains(customFormatName)) {
      shareOperation.data.getTextAsync(customFormatName).done(function (customFormatString) {
          var customFormatObject = JSON.parse(customFormatString);
 
          // Update rest of the UI
          });
    }
};

In our shareready handler, we update our UI immediately with the title and description provided in the share operation payload. We then look to see if it contains our custom data format. If so, we extract the custom data, which in this case has been passed to us as a JSON string. We can then continue on loading the character data into our game for future use. This might be saving it as a local data file, for example.

Wrapping Up

Sharing is a great way to extend the value of your game and to get some free publicity, as well. Players that enjoy your game will want to let others know of their accomplishments, and sharing allows you to leverage all of the great social media, email, and networking clients that the user will already have installed on their system. Sharing is easy to add, so make sure you do it, and take your Windows 8 game experience to the next level.

Tags:

HTML | WinJS | Windows 8

Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen

About the author

Jeff Brand Jeff Brand

This is the personal web site of Jeff Brand, self-proclaimed .NET Sex Symbol and All-Around Good guy. Content from my presentations, blog, and links to other useful .NET information can all be found here.

E-mail me Send mail


Calendar

<<  September 2012  >>
MoTuWeThFrSaSu
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

View posts in large calendar

My Twitter Updates

XBOX
Live

Recent comments

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2014

Sign in