Enabling TypeScript Compilation in Windows Store apps

TypeScript compiles to JavaScript, thus it can be used in Windows Store apps. Other than with Web applications, where you can configure the way typescript compiles on the project’s property page, with Windows Store apps you’ll have to edit the project file by hand. Which is not that hard.

Edit the project file

To do this, unload your Windows Store JavaScript application project by right clicking and selecting unload.

Right click the project again and select edit.

What we need to do is tell MSBuild what it has to do when it encounters a TypeScript file. The whole XML file in front of you basically is nothing more than a configuration for MSBuild. It uses various “targets” that tell what to do in all kinds of situations and how properties are specified. If you want to dive deep into MSBuild, project files and everything around that you definitely should start reading here, at MSDN.

When TypeScript was installed on your computer, assuming you have, it added everything it needs to the MSBuild folder on your system. You can find this folder at C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\TypeScript.

First we’re going to define a property inside the project file to this path. The whole file is divided in PropertyGroups. You’ll have to search for a PropertyGroup that has a label named “Global”. It probably only contains a GUID at the moment and is probably around line 37. At the following to that group:

<TypeScriptPath>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(MSBuildToolsVersion)\TypeScript</TypeScriptPath>

This line defines a property “TypeScriptPath” we’re going to need later on. The path uses 2 properties defined elsewhere, but they make up the path to the TypeScript folder I talked about earlier.

Next we’re going to add the default properties for the TypeScript compiler. A few lines below the “Global” PropertyGroup you’ll find 2 imports. Place the following line right below these:

<Import Project="$(TypeScriptPath)\Microsoft.TypeScript.Default.props" />

The last part we’re going to add to the project file are the configurations for the Debug and Release builds and the targets for TypeScript. These files contain the tasks that need to be executed to compile typescript. Add the following code at almost the end of the file, right before the last import.

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
    <TypeScriptTarget>ES5</TypeScriptTarget>
    <TypeScriptRemoveComments>false</TypeScriptRemoveComments>
    <TypeScriptSourceMap>true</TypeScriptSourceMap>
    <TypeScriptModuleKind>AMD</TypeScriptModuleKind>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Release'">
    <TypeScriptTarget>ES5</TypeScriptTarget>
    <TypeScriptRemoveComments>true</TypeScriptRemoveComments>
    <TypeScriptSourceMap>false</TypeScriptSourceMap>
    <TypeScriptModuleKind>AMD</TypeScriptModuleKind>
</PropertyGroup>

<Import Project="$(TypeScriptPath)\Microsoft.TypeScript.targets" />
<Import Project="$(TypeScriptPath)\Microsoft.TypeScript.jsproj.targets" />

The code is pretty straight forward. It tells TypeScript to compile to EcmeScript 5. When building using the Debug configuration it should leave comments intact, where it should remove these when building in Release. TypeScript uses Source maps for being able to set breakpoints in your TypeScript while debugging. You won’t need these files when running in Release. The last property that is defined tells the TypeScript compiler it should use AMD modules when needed, you could change this to CommonJS if you prefer.

And that’s it. Close the file and reload the project.

You should be able to add TypeScript files to the project now. The TypeScript files get a TypeScriptCompile Package Action.

One last note. Other than with web project you’ll have to include the .js and .js.map files in your project. Otherwise they won’t get deployed and your app won’t work.

To make things a little easier for everyone, I contributed the project template to the SideWaffle project.

Using Grunt to compile .less in Windows Store apps

I was playing with Grunt. Grunt is a JavaScript task runner. It automates a lot of repetitive tasks like minification, unittesting, linting and more. I’ve used it to compile templates and compile .less files to .css. In this tutorial I’ll show you how to do the latter.

Before we dive into Grunt you need Node.js. Just go to http://nodejs.org and install it. NodeJS can serve websites, but can also run tools. Like Grunt. Node.js uses a package manager (a bit like NuGet), npm. You’ll be using npm a lot when using Node.js.

Getting started

First let’s create a new project in Visual Studio, a Windows Store app with JavaScript of course. (Although everything in this tutorial can be used in Windows Phone apps and universal apps too, as long as you use JavaScript). I named mine GruntLessApp.

After creating the project start the Node.js command prompt. This should be somewhere in your start menu. And navigate to the project folder of the project you just created.

Now before we can use Grunt we need to install it. In order to get started first install the command line interface, grunt-cli.

Type the following in the command prompt: npm install grunt-cli -g

This tells the node.js package manager, npm, to install grunt-cli globally so it can be accessed from every location.

Grunt uses 2 configuration files. Packages.json contains all packages your project is dependent on. The other one is gruntfile.js. Creating packages.json can be done by typing: npm init

And follow the instructions.

So, now it’s finally time to install Grunt itself…

Grunt

Just type: npm install grunt –save-dev

This will install Grunt and save the dependency to the packages.json file. If you save this file in your source control others can use this to install the same dependencies (by typing npm install). I personally just include these files in my project in Visual Studio and set the Package Action to none. This way I can easily edit the files in Visual Studio and store in under source control.

To get Grunt to compile your .less files you’ll have to install a task for it.

Type: npm install grunt-contrib-less –save-dev

Your packages.json file will look something like this now:

{
  "name": "GruntLessApp",
  "version": "0.0.0",
  "description": "demo application for grunt and less",
  "main": "js\\default.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "BSD-2-Clause",
  "devDependencies": {
    "grunt": "~0.4.4",
    "grunt-contrib-less": "~0.11.0"
  }
}

 

Last thing we’ll need to do is setting up the gruntfile.js file. If you like some samples of this file, have a look at the Grunt site. This file is not created automatically in this case, but you’ll can just add a .js file in visual studio in the root of your project. Be sure to set the package action to none so the file doesn’t get included in the package when you publish the app.

The gruntfile.js file is build using a few parts. The first line is the definition of a functions. This part is the same for every gruntfile.js.

module.exports = function(grunt) {
  // Do grunt-related things in here
};

 

Inside this function you’ll have to tell Grunt the configuration for the tasks to execute. This is done by passing an object to grunt.initConfig(); like so:

grunt.initConfig({
        less: {
            development: {
                options: {
                    paths: ["css"]
                },
                files: {
                    "css/default.css": ["css/*.less"]
                }
            }
        }
    });

 

Let’s go over this. The less object in line to tells Grunt we’re talking about the configuration for the less tasks. Next, on line 3, we’ve named this configuration. You can have multiple configurations for various situations. On line 4 the actual the options of the less task are specified. In this case we’ll tell the task it should use the “css” folder as a base for the @import less function. The files section on line 7 tells the task to combine the *.less files into ‘default.css’.

grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less:development']);

 

The last two lines tell Grunt to load the less contrib package and register the ‘less’ task as the default. If your gruntfile.js grows over time with more and more tasks you’ll have more of these. Probably in various forms, for development and publishing for example.

To try this out, rename your default.css to default.less and change the contents to something like:

@bgColor: #333333;
@fgColor: red;

body {
    background-color: @bgColor;
}

#content{
    border: 1px solid darken(@fgColor, 20%);

    .item{
        color:@fgColor;
    }
}

 

Now go back to your command prompt and type: grunt

To get you project to use the “new” css file, include it in your project. Set the package action of the .less file to none to exclude it from being packaged.

Automate

There are a few ways to get this process a bit more automated. Grunt is all about removing repetitive tasks and typing a command in a prompt after every change is pretty repetitive.

One way is to use the grunt-contrib-watch package. Using this package will enable you to have the command running continuously and monitor folders and files for changes. When a change happens a series of tasks can be run. Added the task is pretty straight forward. It’s basically the same as described above with the less-task.

In the case of .less files I prefer another method. Because the installation of Node.js has added the path of the npm packages to the “PATH” environment variable, the packages installed with the –g flag can be used everywhere. So let’s add it as a prebuild task to our project.

For this we have to edit the project file. By unloading the project you can edit this inside Visual Studio. Right click the project file in the solution folder and select Unload Project.

Right click the project again, and select Edit GrunLessApp.jsproj.

At the very bottom of the xml, but right before the closing </project> tag, add the following:

<Target Name="BeforeBuild">
    <Exec Command="grunt" />
</Target>

This will do exactly as it says, before the build, execute the command grunt.

To try it out we’ll have to reload the project. To do this, close the file, right click the project in the solution explorer and hit Reload Project.

From now on, on every build, grunt will be executed and help you compile your .less files to .css.

Wrap-up

And that’s it.

A few links to read more about what was discussed in the tutorial:

Windows Phone Sketchflow 2013

In the past I used SketchFlow to prototype my Windows Phone apps. Unfortunately the development of the windows phone SketchFlow templates stopped back in 2011. These templates don’t work in Blend for Visual Studio 2013. Today I had enough of not being able to use that template and just upgraded it to Blend for VS2013.

To use the template you’ll need Silverlight and SketchFlow (which comes with Blend on VS premium and ultimate).

You can download the Windows Phone SketchFlow templates here: http://1drv.ms/1gfqR1d

Once downloaded, extract the zip file into: %userprofile%\documents\Visual Studio 2013\Blend

This folder was probably empty and now it should have to folders in it, ProjectTemplates and ItemTemplates.

To see if it works, just start Blend and select new project on the welcome dialog. On the new project dialog go to Windows Phone. The SketchFlow template should be in the list.

The basics on how to use the template are still available on the codeplex project of the first version and are still pretty much valid. I might do an updated version of the documentation in Visual Studio 2013 in the future.

 

SNAGHTMLbe8b329

Combining WinJS, TypeScript, jQuery and KnockOut

In this tutorial we’re going to build a very simple Windows Store application that uses jQuery and Knockout to get some data from the internet and show this in a GridView. I’ll show you how you create a new project, get all the the TypeScript definitions you need, get data from a web service and bind that to the GridView control. I’m assuming you have at least a little TypeScript knowledge. If you don’t you should have a look at the tutorials on http://TypeScriptLang.org first.

File – New

Start by creating a new project using the template Store apps with TypeScript project template I wrote about recently. After this is installed you can go to the Windows Store section in the TypeScript category in the New Project dialog. Select the Blank App template and give the app a name. I named mine ColourLovers. Hit OK to create the project.

image

This will give us an application similar to a blank application created using the JavaScript template, only with TypeScript in place.

Because this application is going to need jQuery and Knockout we’ll have to get that into the solution. I always use NuGet to get libraries like this into my projects. The easiest way to do this is to open the Package Manager Console from Tools –> Library Package Manager in the menu. In this console window type:

Install-Package jQuery

to get jQuery. And

Install-Package knockoutjs

to install Knockout.

While we’re here, let’s install the TypeScript definition for Knockout too. The definition for jQuery is already included in the project template. Just type

Install-Package knockout.TypeScript.DefinitelyTyped

In the package manager console window to get the definition. Note that you can use the Tab key to get completion of the words.

DefinitelyTyped is a huge open source library of TypeScript definitions of JavaScript frameworks. If you would like to use a JavaScript framework in your TypeScript website or application you should check DefinitelyTyped to see if it contains the TypeScript definition. It would make your life developing you app a lot easier.

Getting Data

To get some data into the app we’re going to make an ajax call to the API of Colourlovers. This API gives us some simple data to work with. To get the data I would like to use what I always use to make ajax calls, jQuery.

To get some code completion and syntax checking on jQuery you’ll have to add a reference to the jQuery.d.ts file that’s in your project. Adding this is easy, just drag the .d.ts file from your solution window to the top of the default.ts file. This will result in a comment like this:

/// <reference path="../Scripts/typings/jquery.d.ts" />

To get the data using jQuery we are goingto use its getJSON function. This function call to the specified url and when it’s done it calls the success function you provided. The result of the ajax call is passed to the success function.

Inside the then function after the processAll we are going to place the getJSON function to get the data from ColourLovers.

args.setPromise(WinJS.UI.processAll().then(() => {
    $.getJSON("http://www.colourlovers.com/api/patterns/top?format=json",
        (result) => {

        });
}));

This piece of code looks pretty much the same as it would when writing it in plain old JavaScript. Except for the lambdas, where function used to be.

Let’s add a little code to the view, our HTML file.

<div id=”content”></div>

At this point we should be able to loop through the result and add some HTML with values from the result to the content div.

Since we are using TypeScript, it would be nice to have some actual type checking and even code completion. To do this we’ll make an interface describing the result from the ajax call. An interface in TypeScript contains the description of an object. In this case the returned object is not complex. The entire interface looks like this:

declare module ColourLovers {
    export interface Top {
        id: number;
        title: string;
        userName: string;
        numViews: number;
        numVotes: number;
        numComments: number;
        numHearts: number;
        rank: number;
        dateCreated: string;
        colors: string[];
        description: string;
        url: string;
        imageUrl: string;
        badgeUrl: string;
        apiUrl: string;
    }
}

I personally hate write code like this. Why? Because it’s very easy to have code like this generated by a computer. So I decided to build a website that does exactly that. Converting a JSON object to a TypeScript interface. At http://json2ts.com you can paste a piece of JSON into the textbox and have it converted to TypeScript. You even can enter the URL to service that returns JSON and have that converted.

To have the result use the interface we just created, add it to the callback function. Now, when we just loop though the items returned from ColourLovers, we can build some UI.

(result: ColourLovers.Top[]) => {
    var content = $("#content");
    for (var r in result) {
        div.append("<h3>" + result[r].title + "<h3>");
        div.append("<img src="" + result[r].imageUrl + "" width="150">");
        content.append(div);
    }
}

Note that when you type inside the callback, you get intellisense on the result.

image

When you run this app it should look something like below. Although this app is getting data and showing it on screen it isn’t exactly what you would expect from a Windows Store app. It would be nice to have some interaction too. You could use jQuery to get some interaction with your app, but there are other ways. Like KnockoutJS for example.

SNAGHTML24c35ad2

Binding to the UI

KnockoutJS uses a viewmodel that is bound to elements in the DOM. If you haven’t used it please have a look at http://knockoutjs.com/. The site has some very nice tutorials on getting started with using KnockOut in your web applications. It uses data-bind attributes on HTML elements to bind properties on the viewmodel to attributes or events in the DOM. It does all change and dependency tracking for you. KnockOut can also be used to render templates.

If you haven’t heard from Knockout before but have build Windows Store apps this should sound familiar.

Let’s start by creating the viewmodel. The viewmodel is basically just another TypeScript class. For sake of simplicity I added it to Default module that’s already in the project. I named the class ViewModel. I added a constructor too, because that’s where we’re going to move the ajax call we created earlier to.

class ViewModel {

    constructor() {

    }
}

The viewmodel is going to need one property to use in the DOM. Well, an array to be more specific. This array needs to be an observableArray. KnockOut uses this function (and a couple more, like a regular observable) to track changes. Whenever you push something into an observableArray the UI is updated. The TypeScript version of the observableArray is generic and takes the type you want to store in the observableArray. In the case of this tutorial we’re going to use the interface we created earlier, Colourlover.Top.

Just add this line to the ViewModel class:

top = ko.observableArray<ColourLovers.Top>();

Filling this array is as simple as passing a value to a function. And that’s something you should always keep in mind when working with knockout. You don’t just assign a value to a variable, you pass it to the variable by calling it as a function and passing the new value.

To fill the observableArray I moved the ajax call from earlier to the constructor of the ViewModel and changed the success part as follows:

$.getJSON("http://www.colourlovers.com/api/patterns/top?format=json",
    (result: ColourLovers.Top[]) => {
        this.top(result);
    });

Last small modification we’ll have to make to the TypeScript code before we can move to the HTML part of this chapter. We have to create a new instance of the ViewModel class and the knockout to do its magic with it by passing it to the applyBindings function.

At the place where we just removed the ajax call we’re going to change to code to this:

args.setPromise(WinJS.UI.processAll().then(() => {
    ko.applyBindings(new ViewModel());
}));

Now that the ViewModels set up it is time to have a look at the view, the HTML. In the last chapter we added some simple HTML to the DOM, but why not use a WinJS control this time, like a ListView. This way we get the Windows 8 grid we are used to see. The HTML for a ListView with GridLayout looks like this:

<div data-win-control="WinJS.UI.ListView"
     style="height:100%"
     id="listview"
     data-win-options="{layout:{type:WinJS.UI.GridLayout}}">
</div>

At this point the grid doesn’t display any data. Normally you would add an option to the data-win-options to set the data source. But since we are using KnockOut I would like to use the KnockOut data-bind method to set the data source. Unfortunately this doesn’t work out of the box. There is no data source handler in KnockOut to set the data source of a Windows 8 control. So I’ve created them myself. You can find them over at GitHub. The project contains only two handlers at the moment, but will grow over time. Just add the two handlers to your project and you ready to go.

Now we can specify the data source with the data-bind attribute and set it to the top property of the ViewModel.

Which results in:

<div data-win-control="WinJS.UI.ListView"
     data-bind="datasource:top"
     style="height:100%"
     id="listview"
     data-win-options="{layout:{type:WinJS.UI.GridLayout}}">
</div>

Normally, when you use the ListView you would like to specify a template which describes the way your data should be rendered. KnockOut provides its own template engine. You could specify the default template using the data-win-options attribute, but you’ll loose the reference to KnockOut that way. On my GitHub project you’ll find the handler to use a KnockOut template. The template itself is specified as follows:

<script id="itemTemplate" type="text/html">
    <div >
        <div style="width:260px;height:190px"
             data-bind="style:{backgroundImage: 'url('+$data.imageUrl+')'}">
            <div data-bind="text:title"></div>
        </div>
    </div>
</script>

You have to add a script like this to the Head section of the HTML document. This will create a tile of 260px by 190px with its background image set to one from the data returned by the ColourLovers API. On top of that the title of the pattern is displayed. Nothing Store app or TypeScript specific about that, just regular KnockOut.

To tell the grid to use this template, change the HTML of the ListView control to:

<div data-win-control="WinJS.UI.ListView"
     data-bind="datasource:top, template:itemTemplate"
     style="height:100%"
     id="listview"
     data-win-options="{layout:{type:WinJS.UI.GridLayout}}">
</div>

The last thing I want to address is that you can use some KnockOut functionality out of the box. Like handling events, even ListView specific events.

Lets say you would like to handle the clicking/tapping on an item of the grid. You would use the iteminvoked to do that. Just use the default KnockOut syntax to handle the event.

<div data-win-control="WinJS.UI.ListView"
     data-bind="datasource:top, template:itemTemplate, event:{iteminvoked:selectionChanged}"
     style="height:100%"
     id="listview"
     data-win-options="{layout:{type:WinJS.UI.GridLayout}}">
</div>

Of course you have to add the handler for the event too. Which is nothing more that a function on the ViewModel.

selectionChanged = (eventArgs) => {
    // do something useful.
};

SNAGHTML2a51292f

That’s it!

You probably thought that creating a Windows Store application that uses TypeScript, jQuery and Knockout would be far more complicated that this :) By using NuGet and the definitions found at DefinitelyTyped you get intellisense and type checking without much effort.

A few last tips to wrap things up:

Texture packer

imageWhen building my game Orbizoid I wanted to combine the images into sprite sheets. A sprite sheet is an image which contains a collection of images (sprites) that are used in a game or website. Because my game was build using HTML, JavaScript and CSS the use of sprites was very simple to do. The hard part was combining a whole lot of image into a sprite sheet. Until I came across Texture Packer. A little tool that can do a lot with sprites. Here’s how it works.

Loading images

When you open Texture Packer you start with a blank sheet. You can add images by clicking on the Add Images button on the toolbar. If you want to add an entire folder with images you can click the Add Folder button. I personally like to just drag and drop the image I need for a sheet from the Windows File Explorer to the empty area on the right in Texture Packer.

And there it is: a sprite sheet.

 image

Texture packer provides a lot of ways you can fine tune your sprite sheet. As you can see in the image above, the layout isn’t optimal and could be a little better.

Layout

Two section of the panel on the left of Texture Packer are important when changing the layout: the Geometry section, which contains properties for the sprite sheet as a whole; and the Layout section, which contains properties for laying out the individual sprites.

imageimage

The two images above show before and after tweaking the settings. One of the things that made a major difference was specifying a maximum width of 350px and setting the size constrains to allow any size.

To further optimize the sprite sheet I set the the algorithm property under the layout section to MaxRects.

To make the exact positioning more visible I check the Shape Outlines property under the layout section. You can use this property for debugging purposes.

SNAGHTML6e9d81Publishing

When you are satisfied with sprite sheet, all there’s left to do is to publish the sprite sheet to an image file. You probably want the sprite sheet in a specific format. You can find these properties in the Output section. For example, when you are creating a game using Cocos2D, you would prefer something that works with that instead of an image only. Texture Packer provides you with a large list of types and frameworks you can export to. One of them is CSS, which can be used for websites. I used the JSON Array format. This will create an image and a file containing JSON with metadata about the sprite sheet. As my image format I used PNG.

After naming both files I hit the publish button on the toolbar and both files were created. By using the .json file that was created I was able to use the sprite sheet in my game Orbizoid with any problems.

Warp-up

Texture Packer has a lot more features than I talked about here. I would suggest to just play with the different settings a little and see what everything does for yourself. It comes in a Lite version which is free and doesn’t have a and a Pro version which has a all the things you need.

If you do anything with websites or games that use images you should definitely have a look at Texture Packer to create your sprite sheets.

Pixel Guy Juggling

Convert json to TypeScript

While working on a Windows Store app I noticed I was writing TypeScript interfaces to get some syntax checking and code completion on JSON data received from an external service. In C# projects I’m used to use http://json2csharp.com to get the C# classes for my JSON and than just deserialize it to those types. I quickly searched the web and realized there wasn’t a similar solution for TypeScript.

Solution

http://json2ts.com was born. You just paste a block of JSON code into the text area and hit the generate TypeScript button to convert the piece of JSON to a TypeScript definition with interfaces.

json2ts

Using the site

To use the result in you application you’ll have to add a “.d.ts”  file (declaration files) and just copy/paste the generated TypeScript from json2ts in there. You may have seen these files before, like for jQuery or KnockoutJS. These files only contain a description of types and are very useful when used next to a Javascript Library (for a lot of these have a look at DefinitelyTyped), but there are useful on the JSON result of a external service too.

Let’s assume there’s some 3rd party service you want to use in you application that return the following JSON:

{
    "date" : "01-03-2014",
    "entry" : [{
            "id" : 1,
            "name" : "Alpha"
        }, {
            "id" : 2,
            "name" : "Beta",
            "xtra" : {
                "value" : "D",
                "someRandomLongerName" : 162    
            }
        }
    ]
}

This result is stored in the “result” variable. Now you can type “result.date” in your code to use the date value. But, TypeScript can give use code completion and syntax checking in Visual Studio. When http://json2ts.com generates the interfaces for this piece of JSON it looks something like this:

declare module namespace {

    export interface Xtra {
        value: string;
        someRandomLongerName: number;
    }

    export interface Entry {
        id: number;
        name: string;
        xtra: Xtra;
    }

    export interface RootObject {
        date: string;
        entry: Entry[];
    }

}

You can see the relations between the various types. When you place this in a “.d.ts” file and reference this file in the TypeScript file you want to use the definition you get all the benefit of TypeScript.

Wrap up

The site isn’t tested very much and I’m pretty sure there are some bug in it. If you have a piece of JSON that isn’t converting properly, please send me an email (ts2json@timmykokke.com). If you have any questions or feature suggestion drop me a line too. I probably going to add some “advanced” features to set the module name and root object names.

Store app Typescript Project Template

Recently I’ve been writing Windows Store apps using TypeScript. Because TypeScript compiles to JavaScript this can be done without any problems. The hardest part at the moment is getting the project up and running. One of the things is that there’s no official Project Template to start a new project. So I made one myself. Feel free to use it and if you run into any issues please let me know.

You can download the template here or get it from GitHub.

To use it, first extract the file in the ProjectTemplates folder of Visual Studio 2013. You can find this folder here:
  %userprofile%\documents\Visual Studio 2013\Templates\ProjectTemplates\TypeScript\Windows Store

And that’s it. Just start or restart Visual Studio and you can use the template. You can find the template under the TypeScript / Windows Store section, which may be hidden in the Other Languages category.

image

If you have any questions about the template let me know. You may want to subscribe to the RSS feed or my Twitter to stay up to date on other tutorials or articles.

About Orbizoid

Intro

A few weeks ago my first Windows Store app was certified and it’s available for download now. The game is a rebuild of the game I build for the Js13k contest a while back. Because I wasn’t limited to 13k anymore I added sounds, music and images. I also added a tutorial, settings, the ability to share your hi-score using Share Charm and added your latest scores to the live tile. Let’s have a look how it works.

10-29-2013 22-22-35 PMBecause the original game was build using HTML and JavaScript I chose to use the same for the Store app. I broke the one file from the 13k version into various files and classes to make it a lot more readable and maintainable. Code that was targeting a specific platform or browser was removed.

Main page

The original game didn’t use any real navigation, only showing and hiding a few divs. The Windows Store version uses the default navigation pattern as used in the Navigation project template.

The main page (default.html) contains a ViewBox which in turn contains the navigation control. The ViewBox is used scale the application based on various resolution (more on this later).

The main page also contains the AppBar. Buttons on the AppBar are turned on and off based on the page that is shown. When the player navigates from one page to another a function is called that updates the buttons.

The main page loads a global JavaScript (default.js) file the coordinates everything that’s happening. The code in this file is responsible for handling all “global” stuff like the Share Charm and calls from the AppBar.

Game loop

The heart of the game is the game loop. The loop is responsible for recalculating the positions of all assets and draw them on the screen, all with a specific delay. The window.requestAnimationFrame asks the browser to be informed when it’s ready to draw the next frame of the animation. In this case I narrowed it down to repaint at max every 40ms.

function animloop() {
    setTimeout(function () {
      requestId = window.requestAnimationFrame(animloop);
    }, 40);
    Orbizoid.game.recalculate();
    Orbizoid.game.draw();
}

Different Resolutions

One of the big pain points I ran into was handling different resolutions. I took the the road of implementing a ViewBox. The contents of a ViewBox are scaled to always fill it. Here’s the entire ViewBox including its content. I used a grid to center the ViewBox on the screen. The contents of the ViewBox is set fixed to 960 by 720 pixels. From this point on, all positioning can be done absolute and will be scaled to whatever the size of the ViewBox is.

<div data-win-control="WinJS.UI.ViewBox" id="viewbox"
     style="-ms-grid-column: 2; -ms-grid-row: 2;">
    <div style="height: 720px; width: 960px;">
        <div id="contentHost" class="center"
             data-win-control="Orbizoid.PageControlNavigator"
             data-win-options="{ home: '/pages/menu.html' }"></div>
    </div>
</div>

To handle the resizing of the screen I used a media query. Media queries are a CSS construction to be able to declare CSS for a specific screen size. There’s also a JavaScript function to monitor a media query, matchMedia. When the screen resolution changed to a width less then 960px I wanted the game to pause.

mql = matchMedia("screen and (max-width: 959px)");
mql.addListener(resizeListener);
...
function resizeListener(q) {
    if (q.matches) {
        Orbizoid.game.pause();
    }
}

The resizing of larger resolutions is done using normal CSS media queries.

The only thing I had a pretty hard time fixing handling the position of the “mouse” on the screen, because this was relative the the scale of the ViewBox. Here’s a small piece of the code:

onmousemove: function (event, args) {
    var that = Orbizoid.game;
    if (!that.game.player.die) {
        var y = that.viewbox.clientHeight / 720;
        var x = that.viewbox.clientWidth / 960;
        that.game.player.x = ((args.clientX - that.viewbox.offsetLeft) / x) | 0;
        that.game.player.y = ((args.clientY - that.viewbox.offsetTop) / y) | 0;
    }
}

Audio

The music is played using the standard audio element of HTML. It’s started and stopped from JavaScript.

The game audio is played using a custom audio manager. This manager creates an array of Audio objects in memory and keeps a pointer to the next element to use. The sound effects themself are store in another array. When something happens in the game the store effect is copied to a channel, played and the pointer is updated. This way I can play multiple audio files at once and do not have to wait until the last has finished playing.

When the volume is turned to 0, no audio is played.

Wrap-up

If you have any questions about how the game works, just ask. And if you haven’t played it yet, please do and let me know what you think!.

You can find the game in the Windows Store.

Behaviors SDK

When the release candidate of Visual Studio 2013 came available, so did the Behaviors SDK. The Behaviors SDK is somewhat similar to the Expression Blend SDK you might have used before when using Behaviors and Actions. Along with the SDK come a couple of actions and behaviors you can use in your Windows Store applications right away.

What are they?

Both behaviors and actions are small pieces of code that can be reused throughout your projects. In the case of the new Behaviors SDK the only thing you need to do is implement an interface. A behavior adds some behavior to an element in your application. A behavior has a method that is invoked when the behavior is attached to a Dependency Object. It also has a method that is invoked when it is detached. An action contains only one method that is invoked when a certain condition is met. This condition can be a event that is raised, or a state of data or well pretty much everything.

Those of you who are used to working with behaviors and actions on other platforms might miss the triggers. Triggers where used to work together with actions, and presented the reason for an action to be executed. In the new Behaviors SDK triggers are no longer there. They are replaced by behaviors.

What’s in the SDK?

The Behaviors SDK consists of two parts. One (Microsoft.Xaml.Interactivity) contains the tools you need to create your own behaviors and actions(more about this is a sec). The other (Microsoft.Xaml.Interactions) contains a few of the most commonly used behaviors and actions(which are build with the interfaces from the first part b.t.w.). Not everything you might be used to working with from other platforms is included in de SDK, but I’m pretty sure these will be available through open source channels.

Let’s just go over the actions and behaviors included in de SDK.

Actions:

  • CallMethodAction : An action that calls a method on a specified object when invoked.
  • ChangePropertyAction : An action that will change a specified property to a specified value when invoked.
  • GoToStateAction : An action that will transition a FrameworkElement to a specified VisualState when executed.
  • InvokeCommandAction : Executes a specified ICommand when invoked.
  • NavigateToPageAction : An action that switches the current visual to the specified Page.
  • ControlStoryboardAction : An action that will change the state of the specified Storyboard when executed.
  • PlaySoundAction : An action that will play a sound to completion.

Behaviors:

  • DataTriggerBehavior : A behavior that performs actions when the bound data meets a specified condition.
  • EventTriggerBehavior : A behavior that listens for a specified event on its source and executes its actions when that event is fired.
  • IncrementalUpdateBehavior : A behavior that allows incremental updating of ListView and GridView contents to support faster updating. By attaching this behavior to elements in the ItemTemplate used by these views, some of the updates can be deferred until there is render time available, resulting in a smoother experience.

The other part contains two interfaces you need when building your own: IAction and IBehavior. There are some attributes and helper classes you can use too.

How do you build your own actions and behaviors? The short version: create a class that inherits from DependencyObject and implement the IAction interface or the IBehavior interface. Now, lets have a look a the long version…

Build your own Behavior

As I said earlier, you need to do is inherit from DependencyObject and implement the IBehavior interface. The code below shows the basic empty implementation of the interface. It might look familiar if you have build behaviors before. The Attach method is call when then the underlying object is initialized. At this point you need to add the new behavior to the associated object. It also is a good moment to set the AssociatedObject property to keep track of the associated object.

The Detach method is called when the behavior is removed from the underlying object. This would be the perfect opportunity to remove some event handlers and things like that.

public class SelectAllOnFocusBehavior : DependencyObject, IBehavior
{
    public void Attach(DependencyObject associatedObject)
    {
        throw new NotImplementedException();
    }

    public void Detach()
    {
        throw new NotImplementedException();
    }
    
    public DependencyObject AssociatedObject { get; private set; }
}

Lets walk through a simple implementation of a behavior. This behavior can be placed on a TextBox and will select it’s contents when the textbox gets focus. First have a look at the Attach method defined on line 6. In this method the associated object is stored in the AssociatedObject property. Next, the associated object is converted to a TextBox and, if it’s not null, the GotFocus event is being handled.

The handling of the GotFocus event is pretty simple in this case. Again, the associated object is converted to a TextBox and the text of that TextBox is selected.

Always be a good citizen and clean up after yourself. And that’s just what the Detach method at line 21 is for. It converts the associated object to a TextBox and removes the GotFocus event handler.

The last thing I would like to mention is the attribute on line 1. The TypeConstraint attribute limits the behavior to only be placed on a specified type, a TextBox in this case.

[TypeConstraint(typeof (TextBox))]
public class SelectAllOnFocusBehavior : DependencyObject, IBehavior
{
        
    public void Attach(DependencyObject associatedObject)
    {
        this.AssociatedObject = associatedObject;
        TextBox tb = this.AssociatedObject as TextBox;
        if (tb != null)
        {
            tb.GotFocus += tb_GotFocus;
        }
    }

    private void tb_GotFocus(object sender, RoutedEventArgs e)
    {
        TextBox tb = this.AssociatedObject as TextBox;
        tb.SelectAll();
    }

    public void Detach()
    {
        TextBox tb = this.AssociatedObject as TextBox;

        if (tb != null)
        {
            tb.GotFocus -= tb_GotFocus;
        }
    }

    public DependencyObject AssociatedObject { get; private set; }
}

Build your own action

An action needs to inherit from DependecyObject also, and it has to implement the IAction interface to make in an action. The IAction interface has only one method that needs to be implemented, Execute.

public class ShowFlyoutAction : DependencyObject,IAction
{
    public object Execute(object sender, object parameter)
    {
        throw new NotImplementedException();
    }
}

Lets have a look at a real action. When using an AttachedFlyout you’ll have to use some code in your code behind file to show the flyout… Or you could us an action to do this in a way it can be reused. The code that you would use in your code behind is pretty much that same as the code that goes into the Execute method of the Action.

In this case the sender is converted to a FrameworkElement. And if it’s not null the ShowAttachedFlyout method is called, with the FrameworkElement passed as a parameter.

You might want to select the default event that triggers the Action. By default an Action is used in combination with the EventTriggerBehavior. The default event is “Clicked”. To change this you can use the DefaultEvent attribute on your action. In this case the default event is set to Tapped.

[DefaultEvent(typeof(FrameworkElement),"Tapped")]
public class ShowFlyoutAction : DependencyObject,IAction
{
    public object Execute(object sender, object parameter)
    {
        var element = sender as FrameworkElement;
        if (element != null)
        {
            Flyout.ShowAttachedFlyout(element);
        }

        return sender;
    }
}

Anything else?

Well… I wouldn’t include a section like this if there wasn’t something else to talk about. There are two more helpful classes inside the Behaviors SDK.

The first is the VisualStateUtilities class. This static class can help you when working with visual states. It contains a couple of methods. GoToState and GetVisualStateGroups perform almost the same task as the similar methods on the VisualStateManager class. They use the VisualStateManager under the hood, but perform some extra checks too.

The FindNearestStatefulControl method walks up the visual tree and looks for any controls with visual state groups defined. It takes a FrameworkElement as a parameter as a starting point of the search. It returns the control with visual state groups, null if there isn’t any.

The second and last thing I would like to talk about is the CustomPropertyValueEditor attribute. With this attribute you define what property value editor must be used for a property of your action or behavior. The attribute takes only one parameter, a CustomPropertyValueEditor enum value. This enum contains four values: ElementBinding, PropertyBinding, StateName and Storyboard.

image

  • ElementBinding : Shows the Element picker and lets you pick an element from the designer.
  • PropertyBinding : Shows the Property picker and lets you pick an element and choose a property of that to bind to.
  • StateName : Shows a dropdown list containing the Visual States of a file and lets you pick one.
  • Storyboard : Shows a dropdown list containing the available storyboards and lets you pick one of those.

Wrap up

I am very happy behaviors and actions are available in Windows Store apps. I was missing these very much.

If you have written some behaviors or actions, for Windows Store apps or any other platform and you would like to share them with the world, you can use my new site for just that: http://blendbehaviors.net. This site lets you search behaviors and actions and submit your own.

Settings Flyout from Blend

Adding a settings flyout to your application has become much simpler with the release of the Windows 8.1 preview and the preview of Blend for Visual Studio 2013. The settings flyout is now supported out of the box and can be added to your project by using an item template.

SNAGHTML86d740b

Adding a Settings Flyout

A settings flyout can be added to your project just by adding a new item. You can do this by right-clicking on a project in the project panel and select Add New Item. From the list on the New Item dialog select the Settings Flyout. You have to give the flyout a name. I named it “DemoSettingsFlyout”. Hit OK to add the flyout to your project.

The settings flyout basically is a ContentControl with a title, an icon, a couple of brushes and methods to show and hide the flyout.

The easiest way to show a flyout is to call its Show method. Do demonstrate this, I added a button to my main page. From the properties panel, by going to events list via the lightning bolt icon, I added an event handler for the Tapped event. In the code behind I added the following lines to the event handler:

DemoSettingsFlyout flyout = new DemoSettingsFlyout();
flyout.Show();

I don’t think this code needs any explanation. I also don’t think you are going to use a settings flyout by hitting a button, or at least not only that way. A settings flyout needs to be accessible through the settings charm.

SNAGHTML3cdef185Using the charm

To get the setting flyout accessible through the settings charm you’ll have to attach it to the settings panel of your app. To get this done you first have to get a hold of the SettingsPane for the current view. And than handle the CommandsRequested event. This event is raised at the moment the settings panel is opened. I attached a handler to this event in the OnNavigatedTo method of the page and detach it in the OnNavigatedFrom method.

In the handler of the CommandsRequested event we’re going to create a SettingsCommand that, when called, shows the settings flyoulllt. The SettingsCommand needs a key (“DemoAppSettings”), a label (“Demo Settings”) and a handler that is called when the command is invoked.

The code on my page looks like this:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    var settingsPane = SettingsPane.GetForCurrentView();
    settingsPane.CommandsRequested += MainPage_CommandsRequested;
    base.OnNavigatedTo(e);
}

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    var settingsPane = SettingsPane.GetForCurrentView();
    settingsPane.CommandsRequested -= MainPage_CommandsRequested;
    base.OnNavigatedFrom(e);
}

void MainPage_CommandsRequested(SettingsPane sender, 
                                SettingsPaneCommandsRequestedEventArgs args)
{
    SettingsCommand demoSettings =
        new SettingsCommand("DemoAppSettings", "Demo Settings", 
        (handler) => {
            DemoSettingsFlyout demoSettingsFlyout = new DemoSettingsFlyout();   
            demoSettingsFlyout.Show();
        });
    args.Request.ApplicationCommands.Add(demoSettings);
}

Where to go from here?

In this tutorial I only talked about adding a settings flyout to you application and showing that. To add actual settings to my application I would use some sort of model that I set to the DataContext of the flyout. On the flyout I bind all settings of the model to controls to set that. The storing and retrieving of the actual settings would be a whole tutorial on its own.