Archive

Posts Tagged ‘WinJS’

Introducing DoodlePad!

February 26, 2013 1 comment

Another simple but fun application that I wrote for my boys. DoodlePad is yet another paint-like clone that is touch enabled. I wanted to provide a simple means for my boys to play around and make me some cool drawings.

Here are a couple screens shots:

screenshot_02262013_073728
This is the splash screen.

screenshot_02262013_073831
Here is a screen showing my Appbar and NavBar.

screenshot_02262013_073838
Here is an example of the color picker I use.

screenshot_02262013_073848
Here is a simple example of my size picker I use as well.

Like my games, this application relies heavily on HTML5 canvas to get its job done. I also want to provide a link to a pure JavaScript color picker I used in the app in case any of you are looking for one.

I tried to find a control or some pure JavaScript that would allow me to do the size picker and I didn’t find one. I ended up building it myself as the process is really simple and can be used anywhere you need something to reflect size. First, I used an Input type of “range”. Next I positioned a DIV to the right of it.

Here is the HTML snippet of the flyout that I am using in my application:

<div class="flyout" id="sizeFlyout" data-win-control="WinJS.UI.Flyout"><label>Size: <input id="penSize" type="range" max="100" min="1" step="1" value="5" /></label>
<div id="actualSize"></div>
</div>

Next, I will show you the CSS I used:

#sizeFlyout {
    height:100px;
    width: 425px;
}
#actualSize {
    float:right;
    height:5px;
    width:5px;
    background-color: black;
}

Finally, here is the JavaScript I used to adjust the size of the DIV and color:

var brushColor = "#df4b26";
var actualSize = document.getElementById("actualSize");
var penSize = document.getElementById("penSize");
penSize.addEventListener("change", function (element, e) {
    actualSize.style.height = penSize.value + "px";
    actualSize.style.width = penSize.value + "px";
}, false);

As you can see, it is pretty simple and is a great technique to represent the size of an object based on a range or scale.

Another interesting feature that I struggled with a bit was allowing my boys to pick a background color or even open an existing image and use it as a background. My first approach was to simple paint this on to the canvas and it worked fine if the boys would pick a background color and start drawing but the moment they tried to pick a different background color it would overlay and cover up their drawing. I also noticed that the more I put into the canvas the more I had to worry about performance.

It turns out that my solution was simple, an HTML5 canvas is transparent by default and this turns out to be great. All I had to do was simply set the background color of the DIV that was wrapping my canvas.

This worked perfect until I tried to save my canvas out to a file. When I performed a save, I would get a transparent background because the “real” background was not part of the canvas. Here is the save function that I used. I am showing the full cycle from when the user clicks on the save button:

function saveAs() {
    // Verify that we are currently not snapped, or that we can unsnap to open the picker
    var currentState = Windows.UI.ViewManagement.ApplicationView.value;
    if (currentState === Windows.UI.ViewManagement.ApplicationViewState.snapped &&
        !Windows.UI.ViewManagement.ApplicationView.tryUnsnap()) {
        // Fail silently if we can't unsnap
        return;
    }

    var encoderId;
    var filename;
    var stream;

    var imgData;

    // Create the picker object and set options
    var picker = getFilePicker("save");

    picker.pickSaveFileAsync().then(function (file) {
        if (file == null) return;
        filename = file.name;

        if (file) {
            switch (file.fileType) {
                case ".jpg":
                    encoderId = Windows.Graphics.Imaging.BitmapEncoder.jpegEncoderId;
                    break;
                case ".bmp":
                    encoderId = Windows.Graphics.Imaging.BitmapEncoder.bmpEncoderId;
                    break;
                case ".png":
                default:
                    encoderId = Windows.Graphics.Imaging.BitmapEncoder.pngEncoderId;
                    break;
            }
            return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
        } else {
            return WinJS.Promise.wrapError("No file selected");
        }
    }).then(function (_stream) {
        stream = _stream;

        // BitmapEncoder expects an empty output stream; the user may have selected a
        // pre-existing file.
        stream.size = 0;

        return Windows.Graphics.Imaging.BitmapEncoder.createAsync(encoderId, stream);
        //return Windows.Graphics.Imaging.BitmapEncoder.createAsync(Windows.Graphics.Imaging.BitmapEncoder.pngEncoderId, stream);
    }).then(function (encoder) {
        var canvas = id("doodleCanvas");
        var width = canvas.width;
        var height = canvas.height;
        var ctx = canvas.getContext("2d");

        var canvas2 = id("canvas2");
        canvas2.width = width;
        canvas2.height = height;
        WinJS.Utilities.removeClass(canvas2, "hidden");
        var ctx2 = canvas2.getContext("2d");
        var root = document.getElementById("root");
        if (root.style.backgroundImage !== "") {
            ctx2.drawImage(currentImage, 0, 0, width, height);
        }
        else if (root.style.backgroundColor !== "") {
            ctx2.fillStyle = root.style.backgroundColor;
            ctx2.fillRect(0, 0, width, height);
        }
        ctx2.drawImage(canvas, 0, 0);

        imgData = ctx2.getImageData(0, 0, width, height);
        WinJS.Utilities.addClass(canvas2, "hidden");

        encoder.setPixelData(
            Windows.Graphics.Imaging.BitmapPixelFormat.rgba8,
            Windows.Graphics.Imaging.BitmapAlphaMode.straight,
            width,
            height,
            96, // Horizontal DPI
            96, // Vertical DPI
            imgData.data
        );

        //Go do the encoding
        return encoder.flushAsync();
    }).then(function () {
        WinJS.log && WinJS.log("Saved new file: " + filename, "sample", "status");
        //id("buttonSave").disabled = false;
        //id("buttonRender").disabled = false;
    }).then(null, function (error) {
        WinJS.log && WinJS.log("Failed to save file: " + error.message, "sample", "error");
    }).done(function () {
        stream && stream.close();
    });
};

If you haven’t played with Promises, I would suggest you do as they make asynchronous programming a lot easier in JavaScript. My function saveAs gets called whenever the save button is pressed. I then proceed to display a Save File Picker. Once the user has picked a file name or existing file, I grab the stream object and pass it to my encoding. It is here that I perform a simple swap operation where I use two canvas objects. This allows me to “paint” the background on the original canvas while still saving its content on a dummy canvas. I then just dump the contents from the dummy back onto the original canvas.

All in all, I have plans to continue to improve the application. The boys have requested the ability to have stamps or stencils. They would like to have simple shapes to draw as well as the ability to have stock images for them to color. They also wanted to have a crayon effect and some others that they have used in the past.

Hope this helps….

Introducing Tank Commander!

February 26, 2013 1 comment

In this post, I wanted to describe Tank Commander and talk about some of the logic that went into building it.

Here is the description of the game:

Tank Commander is a game that teaches you programming logic. You get one chance to write your program and destroy the base. You can play any level but your real skill comes when you can write all the programs without a single error!

The following are some of the screens in the game:

Tank Commander - Splash

Main Screen

screenshot_02252013_234142

screenshot_02252013_235058

screenshot_02252013_234251

screenshot_02252013_234354

screenshot_02252013_234438

The main premise behind the game was to use it as a tool for teaching my boys how to think logically and perform some simple programming. My oldest can win each level with a couple of tries. My youngest is still working but he has the first couple levels down perfect!

I have really enjoyed building games using HTML5 and the Canvas. It is so easy with CreateJS and the suite of tools it provides. I have looked at other libraries but it keeps pulling me back to use it for my games so far. I decided to build on the simple level editor that I built for my first game, Milo the Mosquito as it was a very straight forward approach. I did, however, make it a little more complicated as I wanted to have a little more metadata about the levels.

Probably, one of the most challenging parts about creating the game, was trying to make sure that I had a good collision detection.  I didn’t really need to worry about this in my other game but now with moving objects, I needed to be a little more careful.  Thankfully, due to the grid that I was using, I simply rolled out a poor man’s collision detection system using the X and Y coordinates.  That is one of the reasons why you see them in the game. There were originally meant for debugging purposes only but I liked them so much that I decided to keep them.

I also had to create a simple parser for the input the user typed into the programming console. I know that this experience can be improved upon by providing some compiler errors or hints to help the user play the game.

In my first release I provided a toggle for all sounds in the game but I changed that a little in the next release to have a toggle for both sounds and music in the game. I also decided to save the settings of what the user chose automatically so that when they came back to the game it would be ready.

Another area that I found was not the most intuitive was the original main menu. When a user went to the selected a level from the dropdown, the level automatically started. This was very irritating if you clicked on the home button in a level and then wanted to go back.

I now have a “Go” button that takes the user to the selected level.

In my original design of Milo the Mosquito, I had a separate level text file. I changed this up a little and now use JSON for Tank Commander. This provided me with the ability to define more complex levels and behaviors.

The following is the first level for Tank Commander as JSON:

[{
	"id": 1,
	"name": "Fire!",
	"level": "intro",
	"background": [
		"1NNNNNN2",
		"W......E",
		"W......E",
		"W......E",
		"W......E",
		"W......E",
		"W......E",
		"3SSSSSS4"
	],
	"game": [
		"......P.",
		"P...T...",
		"........",
		".....P..",
		"..P.....",
		".P.....P",
		"....X...",
		"......P."
	],
	"tankDirection": "north"
},
]

I left out the rest of the levels for brevity. I have two layers to my game so that I could create a background and then position the other assets on the screen. I finally have a direction so that I can tween the tank into the correct orientation. This is also beneficial as it allow me to have a single sprite sheet with animation going in a single direction and be able to tween all the other direction by just rotating the items.

Here is a quick legend of what I am doing with the “background” and “game” arrays.  I wanted to have a background where I could define a nice border instead of the same tile.  This is the reason for the following values: 1, N, 2, W, E, 3, S, 4.  It doesn’t take a lot of imagination to see what I am representing here.  I also used the “.” character to represent the tiles within the border.

The “game” array is basically the same, I am representing different tiles by using different characters: P, T, X.

Here is a screen shot of the layer rendered:

screenshot_02252013_234108

This is a simple approach and can be used for a lot of time layouts.  It is used in a lot of 2D platform games.

Although, I have ran into some challenges while developing this game, I really enjoyed building it using HTML5 Canvas and JavaScript.  The other thing that I absolutely love is the ability now to natively target Windows 8.

Hope this helps and inspires you to write one as well…

Developing Windows 8 – Using AppBarCommand Icons outside the AppBar

November 23, 2012 1 comment

One of the things I really like about developing Windows 8 applications is the ability to use the built in icons provided by the Segoe UI Symbol font.  It is through this font that I can do thing like this in my AppBar:

<button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'find', label:'Find', icon:'find', section:'selection', tooltip:'Find (Ctrl+F)'}"></button>

I am able to use the name of the icon directly, “find”, because of some helpers provided by WinJS but I can still access the icons directly due to the font family being exposed.

Another nice feature is that if you create a brand new JavaScript Windows Store application, you will automatically be exposed this font.  That means that I don’t have to provide a font family directly.  You can simply write the following HTML code:

<div class="pad"><span class="marginRight10">&#xe188 ;</span>Folder</div>

NOTE:  I purposely added a space before the “;” so that the browser wouldn’t try to render representation.

The CSS for the above HTML look like the following:

.pad {
    margin:20px;
}

.marginRight10 {
    margin-right:10px;
}

Notice that the CSS was used simply for formatting purposes.  Finally the output for this little experiment looks like the following:

This is all it takes to be able to access all of the available icons provided out of the box in your AppBarCommands.  Granted that the AppBarCommands make your life a lot easier by allowing you to specify the icon by name but it is still great to access the font directly anywhere in your application.

Here is a link to the AppBarIcon enumeration.

If you are curious about finding the code to use, you can use the Character Map application in Windows 8. Simply type, “Character Map” and you can click on the application. Then simply select the “Segoe UI Symbol” font in the dropdown control.

Finally select the symbol you want and you will see the code at the bottom of the app as shown below:

The finally thing you need to do is make sure that you replace “U+” with “&#x” and you will be good to go.

Update (2/26/2013): I wanted to also document how you can do this with Knockout.js as well.

In my view model, I simply expose an observable as such:

this.icon = ko.observable("&#xe188 ;");

Again, note that a space has been intentionally added so that it would render the text and not resolve its value. Next, in my HTML, I use the following binding to get it to render properly:

<button data-bind="html: icon, click: doSomething"></button>

This gives a lot of different ways to render custom fonts in our applications.

Hope this helps…

Introducing Milo the Mosquito

November 22, 2012 3 comments

In this post, I am going to describe the game Milo the Mosquito that I created and show some of the screens.

Here is the description of the game:

Milo is an annoying mosquito that just needs to be caught.
Play through the levels and try to catch Milo as fast as you can.
Once you have Milo trapped, tap on him to squish him for good.

The Home screen is as follows:

If you click on the help button, you are presented the Help screen:

When you click play from the Home screen you are presented with the Levels screen:

Next you can click on each level and play the game:

As you can see it is a fairly simple game in that you are trying to catch Milo and squish him before he escapes.  I will now just go over at a high level the architecture and structure I used to create the game.

If you have noticed already, I have been spending a lot of time building applications for Windows 8 in HTML, CSS, and JavaScript.  I have consciously made this decision because I want to be able to author applications that give me the ability to reach across to other platforms without needing to learn a new language or API.  I have held the MVP status in Client Application Development and I have extensive experience in WPF and Silverlight but I wanted to be sure that I could get a good feel for the development experience in building Windows 8 applications in HTML.

The first conscious decision I made with building this game was to use the new HTML 5 feature of the Canvas.  I also decided to use the JavaScript library, CreateJS.  There is a lot of tremendous documentation on this library.  The creators of  Pirates Love Daisies are behind this awesome library.

Within CreateJS, I used the following:

  • EaselJS – to help with managing the canvas
  • PreloadJS – to help manage my assets in the game
  • SoundJS – to help manage my audio in the game
  • TweenJS – to help with creating animations in the game
  • Zoë – to help create spritesheets from Flash

I also used the EasyStar library as a pathfinding engine for Milo to use for determine his escape route.

When working with the canvas, you are left to managing what you are to the canvas and also removing items.  I tried to be as modular as possible by creating top level managers for each screen and implementation.

Finally also created a level editor so that I could use a simple text file represent a level.  The following is the text representation for the level screen you see above:


..............
.XXXXXXXXXXXX.
.XXXXXXXXXXXX.
.XXXXXXXXXXXX.
.XXXXXXXXXXXX.
.XXXXXXXXXXXX.
.XXXXXXMXXXXX.
.XXXXXXXXXXXX.
.XXXXXXXXXXXX.
.XXXXXXXXXXXX.
.XXXXXXXXXXXX.
.XXXXXXXXXXXX.
.XXXXXXXXXXXX.
..............

As you can see, I used “.” as an exit point for Milo.  I represented the playing board by using “X” and finally I represented Milo as an “M”.

I hope this gives you a simple idea into what it takes to build a simple game.  The great thing about using HTML 5 is that you can develop it and test it with you favorite browser and have almost no changes to get it to work in a native Windows 8 application.

Hope this helps…

Developing Windows 8 – Adding a ListView to your settings charm and overcoming dual vertical scrollbars

November 22, 2012 Leave a comment

Here is another tip that I ran into recently when trying to get a ListView setup properly in a setting page. When I was coding for the ListView I came across the following screenshot:

Here is the sample CSS that I used to configure the ListView:

#listview1 {
    height: 100%;
    width: 100%;
}

Clearly this isn’t acceptable and we need to find a way to fix this.

It turns out that the solution is quite simple. It is easier to see this problem when developing traditional web applications but the same applies here. The height of the ListView was actually taller than the visual area that we were viewing and this is the reason for the second vertical scrollbar.

If we modified our CSS to use the following markup:

#listview1 {
    height: calc(100vh - 155px);
    width: 100%;
}

Our screenshot would then look like the following:

We are using a new feature of CSS3, the Calc function. One thing to note is that I am adjusting for the height of my header in the settings pane. You may have a different style or header altogether so be conscious as to how your adjust your height.

Hope this helps…

Developing Windows 8 – Tooltips in your Settings

November 22, 2012 Leave a comment

I ran into a weird situation where I wanted to add tooltips to my Preferences page in the Settings charm.  If you were creating a standard command for your AppBar, you would use the following markup to include a tooltip for your control:

<div id="navBar" data-win-control="WinJS.UI.AppBar" data-win-options="{placement: 'top'}">
    <button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'find', label:'Find', icon:'find', section:'selection', tooltip:'Find (Ctrl+F)'}"></button>
</div>

If you try to use the same format and put the following code in a settings flyout, you will NOT get any tooltip functionality. I had made the assumption that I could use the same format like for my AppBar:

<div class="win-settings-section">
    <div id="toggle" data-win-control="WinJS.UI.ToggleSwitch" data-win-options="{ title: 'Sample Toggle', tooltip:'This sample toggles...' }" />
</div>

In order to get tooltips to work in my settings charm pages, I had to use the following format:

<div class="win-settings-section">
    <div data-win-control="WinJS.UI.Tooltip" data-win-options="{ innerHTML: 'This sample toggles...' }">
        <div id="toggle" data-win-control="WinJS.UI.ToggleSwitch" data-win-options="{ title: 'Sample Toggle' }" />
    </div>
</div>

This is all that you have to do in order to get your tooltips to work in your settings pages. One thing to note, is that you are given a lot more flexibility with this wrapper approach as you can inject any HTML to provide a nice look and feel for your tooltips.

Here is a link to the MSDN page on tooltips for Windows 8 HTML.

Although this may seem trivial for anyone who reads this, it stumped me at first in that I was trying to just copy the same pattern I used for the AppBar.

Hope this helps…

Categories: English Tags: , , , , ,

Upgrading Windows 8 HTML5 code from RP to RTM

August 27, 2012 1 comment

If you have played with any code targeted for Windows 8 Release Preview (RP) and you want it to run using the RTM version, you run into the following error:

Could not find SDK “Microsoft.WinJS.1.0.RC, Version=1.0”.

The solution to this error is actually very simple.  You need to do two things in order to get your code to work:

  • You will need to replace the WinJS reference to the 1.0 version.  First remove the old reference that is shown below:

 

Next add the RTM version reference as shown below:

 

  • Next you will need to globally changes all your JavaScript references in your HTML files as shown below:

 

As you can see your references are now adjusted correctly:

 

Now if you find some examples that haven’t been converted to Windows 8 RTM, you can still get them to work.

Hope this helps….