Connect SensorTag CC2650 to Azure IOT Hub

I needed to create a demo showing the most simple way to get some sensor data to IOT Hub and I thought sharing the code might be helpful to someone else as well. This app is divided to two parts, first part handling the sensor and second part connecting to IOT Hub.

First we start by creating a new empty UWP app, you can give whatever name you want to it. Because Texas Instrument SensorTag is a bluetooth device, we’ll first initialize the bluetooth connection bits (please note that you need to manually pair the Sensortag in the Windows 10 settings, we’re only dealing here with the code which handles paired devices).

Open your Mainpage.xaml.cs file and add the following namespaces:

using Windows.Devices.Bluetooth;
using Windows.Devices.Enumeration;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Storage.Streams;

We will be needing couple of class members, so let’s add this now:

private BluetoothLEDevice tagDevice;
private GattDeviceService gattDevice;

Next we add the code to find the paired SensorTag device. I placed this code in Mainpage_Loaded override, but you can find more suitable place for it in your code:

foreach (var info in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector()))
{
    BluetoothLEDevice bleDevice = await BluetoothLEDevice.FromIdAsync(info.Id);
    if (bleDevice.Name.ToLower().Contains("sensortag"))
    {
        tagDevice = bleDevice;
        foreach (var serv in tagDevice.GattServices)
        {
            if (serv.Uuid.ToString() == "f000aa00-0451-4000-b000-000000000000")
            {
                gattDevice = serv;
                break;
            }
        }
        break;
    }
}

The code above first goes through all the BLE devices connected, and then checks for each of them if they have “sensortag” somewhere in their name. This probably finds also first gen sensortags, but you can always make it more specific if needed. After that we’re looking for a certain service with GattService id, which in this case is id for temperature sensor. Sensortag supports other ids/sensors as well, so you can always add more servies, and make a list of the gattDevice instead.

Next step is to start reading the Sensortag itself, and it can be done with the following code:

if (tagDevice != null && gattDevice != null)
{
    // Test connection
    Guid configuration = Guid.Parse("f000aa02-0451-4000-b000-000000000000"); // temperature profile
    var configurationCharacteristics = gattDevice.GetCharacteristics(configuration).First();

    GattCommunicationStatus status = await configurationCharacteristics.WriteValueAsync((new byte[] { 1 }).AsBuffer());

    if (status != GattCommunicationStatus.Success)
    {
        Debug.WriteLine("Connection failed, ensure the SensorTag is powered on");
    }
    else
    {
        // Setup the data read
        Guid data = Guid.Parse("f000aa01-0451-4000-b000-000000000000"); // temperature data
        GattCharacteristic dataCharacteristic = gattDevice.GetCharacteristics(data).First();
        if (dataCharacteristic.CharacteristicProperties == 
            (GattCharacteristicProperties.Read | 
            GattCharacteristicProperties.Notify))
        {
            dataCharacteristic.ValueChanged += this.dataValueChanged;
            status = await dataCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(
                GattClientCharacteristicConfigurationDescriptorValue.Notify);

            if (status != GattCommunicationStatus.Success)
            {
                Debug.WriteLine("Sensor access denied");
            }
        }
    }
}

The codeblock above first looks for the temperature service from the gatt device, and tests if the connection can be established and if everything is ok and we can read and get a notify for the data change, we’ll setup a callback function for temperature data. Yet again you can setup multiple callbacks for different sensors by using the GetCharacteristics with different sensor data guids. All that is left is to do the callback method now, which is like this:

private async void dataValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
    GattReadResult readResult = await sender.ReadValueAsync(BluetoothCacheMode.Uncached);
    Color textColor;

    if (readResult.Status == GattCommunicationStatus.Unreachable)
    {
        Debug.WriteLine("Connection lost");
    }

    // Read the sensor value
    var result = new byte[readResult.Value.Length];
    DataReader.FromBuffer(readResult.Value).ReadBytes(result);

    // Extract ambiant temperature
    double ambTemp = BitConverter.ToUInt16(result, 2) / 128.0;

    string data = $"{ambTemp}";

    // Code to send data to IOT Hub
    //TagSensor sensor = new TagSensor() {Temperature = ambTemp};
    //await SendEvent(sensor);

    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
            () =>
            {
                try
                {
                    // This is needed in case you want to update UI with sensor data, temperatureText is a TextBlock
                    //temperatureText.Text = data;
                }
                catch (Exception ex) { }
            });
            
    Debug.WriteLine(data);

}

At this point we are able to read the SensorTag temperature values, and get callback for the changes. Next we’ll add the code required to send this to IOT Hub.

First you should create new IOT Hub in Azure portal, and take note of the Connection String – Primary key (can be found in Shared Access Policies, iothubowner), and copy the value to the connectionString -member variables of the MainPage.xaml.cs and the host name to connectionString2:

// IOT Hub
static RegistryManager registryManager;
static string connectionString = "HostName=XXXXX.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=XXXXXXXXXXXXXXXXXXXXXXXXX";
static string connectionString2 = "XXXXX.azure-devices.net";
static string deviceKey;

Add the following Nuget packages to your solution:
– Microsoft.Azure.Devices
– Microsoft.Azure.Devices.Client
and in case it didn’t add automatically, Newtonsoft.JSon as well.

Next you should add the namespaces as well:

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Common.Exceptions;
using System.Runtime.Serialization.Json;

Use the latest stable versions of them.

For the device to be able to connect to the IOT Hub you first need to setup the device in the device registry. That can be done with the following code:

private async Task AddDeviceAsync()
{
    registryManager = RegistryManager.CreateFromConnectionString(connectionString);

    string deviceId = "TiTag1";
    Device device = null;
    try
    {
        device = await registryManager.AddDeviceAsync(new Device(deviceId));
    }
    catch (DeviceAlreadyExistsException)
    {
        device = await registryManager.GetDeviceAsync(deviceId);
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
    if (device != null)
        deviceKey = device.Authentication.SymmetricKey.PrimaryKey;

}

The device id can be anything you want to give it, in this demo I just simply call it TiTag1.

Next add the call to the method in the beginning of the Mainpage_Loaded (remember to change it to private async void Mainpage_Loaded to be able to call async code inside it):

// Create the IoT Hub Device Client instance
await AddDeviceAsync();

Now is a good time to add a class to represent the sensor, where you can add the other sensors later if you like. Add this before Mainpage class:

public class TagSensor
{
    public TagSensor()
    {
        Time = DateTime.Now;
    }

    public DateTime Time;
    public double Temperature;
}

Next we’ll need to serialize the date to Json, and send to IOT Hub, which can be done like this:

private async Task SendEvent(TagSensor sensor)
{
    var serializer = new DataContractJsonSerializer(typeof(TagSensor));
    var stream = new MemoryStream();
    serializer.WriteObject(stream, sensor);
    string json = Encoding.UTF8.GetString(stream.ToArray(), 0, (int)stream.Length);

    var eventMessage = new Microsoft.Azure.Devices.Client.Message(Encoding.UTF8.GetBytes(json));
    await deviceClient.SendEventAsync(eventMessage);
}

Last piece is to remove the comments in dataValueChanged -method from TiTag Sensor… and async SendEvent -lines and you should be good to go. Please let me know in the comments if you are having issues, always happy to help!

Posted in Azure, Universal Apps, UWP, Windows 10 | Leave a comment

Add Windows Hello -sign in to your app

With Windows 10 you have option to use Biometric methods to login, but it looks like there is quite little documentation how to implement it. Another thing is that people confuse Windows Hello to authentication framework which it’s not, even you can use it with such to authenticate. So this article shows you how to implement the login functionality to your UWP app using Microsoft Passport and Windows Hello.

It’s important to understand that this will use what ever is available, it could be iris recognizion on for example on Lumia 950 or fingerprint on your Thinkpad or just pin code if the machine doesn’t have any biometric sensors. The code itself is actually very simple, and this is all you would need:

Add the required reference to app.xaml.cs

using Windows.Security.Credentials;
using Windows.Security.Cryptography;

After that we can implement the login in App.xaml.cs and you can do this in many different ways, but I have a static member variable here:

private static bool authorized = false;

Now all is left is to do the actual login, which you can copy/paste to your code (beginning of OnLaunched -method):

// Do we have capability to provide credentials from the device
if (await KeyCredentialManager.IsSupportedAsync())
{
    // Get credentials for current user and app
    KeyCredentialRetrievalResult result = await KeyCredentialManager.OpenAsync("MyAppCredentials");
    if (result.Credential != null)
    {
        KeyCredentialOperationResult signResult =
            await
                result.Credential.RequestSignAsync(CryptographicBuffer.ConvertStringToBinary("LoginAuth",
                    BinaryStringEncoding.Utf8));
        if (signResult.Status == KeyCredentialStatus.Success)
        {
            authorized = true;
        }
    }
    // No previous saved credentials found
    else
    {
        KeyCredentialRetrievalResult creationResult =
            await
                KeyCredentialManager.RequestCreateAsync("MyAppCredentials",
                    KeyCredentialCreationOption.ReplaceExisting);
        if (creationResult.Status == KeyCredentialStatus.Success)
        {
            authorized = true;
        }
    }
}

When you check IsSupportedAsync you need to handle the situation that the device is not capable to provide this service, and you have to fallback to something else, such as Facebook or Twitter authentication. OpenAsync will check it there are saved credentials per app and user, and use those if can be found with RequestSignAsync. If there were no previous credentials for the app for current user, let’s create one. That’s all there is to it, very confusing topic but it is actually surprisingly easy to use. Hope this helps you!

Posted in Universal Apps | 4 Comments

Figuring out your if your app is run on Phone, Tablet or Desktop

One would think that it’s easy to figure out the answer to header above. If you’ve ever tried that, I think you most likely have become extremely frustrated when you realized that there are just too many combinations and it becomes quite impossible to make a difference between the devices with the provided APIs. For example Surface is a tablet running Desktop SKU while under 8″ screen tablets run Mobile SKU which is same SKU which is on the phones. For IoT there’s IoT Core and IoT Enterprise, which is actually Windows 10 Enterprise with additional IoT license.

In general you should always design for Universal which adapts to available screen space and hardware/capabilities but sometimes you just need to know (for example for analytic reasons) and that’s why I have created this little snippet. It should cover the most cases, but do let me know if the logic fails to identify something and I try to include that as well.

I threw in my best guess for Continuum and Iot as well, after some Twitter discussions with @dotMorten, @ScottIsAFool, @gcaughey and @mahoekst

public enum Device
{
    Phone,
    Tablet,
    Desktop,
    Xbox,
    Iot,
    Continuum
};
...
if (Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Mobile")
{
    if (ApiInformation.IsApiContractPresent("Windows.Phone.PhoneContract", 1))
    {
        Windows.Devices.Input.KeyboardCapabilities keyboard = new Windows.Devices.Input.KeyboardCapabilities();
        if (keyboard.KeyboardPresent > 0)
        {
            runningDevice = Device.Continuum;
        }
        else
        {
            runningDevice = Device.Phone;
        }
    }
    else
    {
        runningDevice = Device.Tablet;
    }
}
else if (Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Desktop")
{
    Windows.Devices.Input.KeyboardCapabilities keyboard = new Windows.Devices.Input.KeyboardCapabilities();
    if (keyboard.KeyboardPresent > 0)
    {
        runningDevice = Device.Desktop;
    }
    else
    {
        runningDevice = Device.Tablet;
    }
}
else if (Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Xbox")
{
    runningDevice = Device.Xbox;
}
else if (Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.IoT")
{
    runningDevice = Device.Iot;
}

// Couldn't figure out, let's assume it's desktop (safest bet)
runningDevice = Device.Desktop;
Posted in Universal Apps, UWP, Windows 10, Windows Phone | 1 Comment

How I do Hamburger menu on SplitView, quick and dirty

I wanted to do a nice hamburger menu on my app, but it seems that all the samples found are doing it in different way compared how the default apps on Windows 10 seem to implement it. I don’t want to have CompactInlay menu always visible on the side of the screen, but just the hamburger button which would open it when clicked. This is how I implemented mine, hope you can get something out of it:

First I created BoolToVisibilityConverter class, so I can later on bind the visibility of the menu to the hamburger button (right click on project, add new item, class):

public class BoolToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return (bool)value ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Then I open the MainPage.xaml and add the reference to the namespace in the page element after xmlns:local -line:

xmlns:utils="using:MyNameSpace.Utils"

where the MyNameSpace.Utils is the namespace where you created the BoolToVisibilityConverter -class in previous step.

After that, you would need to add in the resources the following:

<Page.Resources>
        <utils:BoolToVisibilityConverter x:Name="BoolToVisibilityConverter" />
    </Page.Resources>

Now that we have all the prerequisities in place, we can build the page itself. This is the barebone structure for the main page with hamburger menu and splitview:

<Grid Background="#FFFF8000">
    <Grid.RowDefinitions>
        <RowDefinition Height="50"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <!--Menu bar on top-->
    <RelativePanel Grid.Row="0" >
        <ToggleButton x:Name="HamburgerButton" FontFamily="Segoe MDL2 Assets" Content="?" Width="50" Height="50" Background="Transparent" IsChecked="False"/>
        <TextBlock Text="My title" FontSize="32" Width="300" Height="40" Foreground="Black" RelativePanel.RightOf="HamburgerButton"/>
    </RelativePanel>
    <!--Hamburger menu-->
    <SplitView Grid.Row="1" x:Name="MySplitView" PanePlacement="Left" CompactPaneLength="50" OpenPaneLength="300" 
            IsPaneOpen="{Binding IsChecked, ElementName=HamburgerButton}" DisplayMode="Overlay" >
        <SplitView.Pane>
            <StackPanel Orientation="Vertical">
                <StackPanel x:Name="SettingsPanel" Orientation="Horizontal">
                    <Button x:Name="SettingsButton" FontFamily="Segoe MDL2 Assets" Content="?" Width="50" Height="50"/>
                    <TextBlock Text="Settings" FontSize="18" VerticalAlignment="Center" />
                </StackPanel>
                <StackPanel x:Name="AboutPanel" Orientation="Horizontal">
                    <Button x:Name="AboutButton" FontFamily="Segoe MDL2 Assets" Content="&#xE77B" Width="50" Height="50"/>
                    <TextBlock Text="About" FontSize="18" VerticalAlignment="Center" />
                </StackPanel>
            </StackPanel>
        </SplitView.Pane>
        <!--Main content-->
        <Grid Grid.Row="1">
            
        </Grid>
    </SplitView>
</Grid>

On the code above, the RelativePanel section is for the menu bar, where the button and title are. In the SplitView section there is the SplitView.Pane where the actual menu is built, each item consists of vertical StackPanel, Button and TextBlock. Inside then there is the Grid where the actual page content can be put. That’s all required for simple hamburger menu, hope it’s helpful!

Posted in Universal Apps | Leave a comment

How to make a Windows Store game with C# and XAML, part 5

In this mini post we’ll be finally adding some sounds to our game. You will need to have some sound effects added to your Assets -folder. You need one for laser shooting and one for enemy hit sound. One place you could download some of these for free is Free game content resources. Add one with the name pew.mp3 under Assets (right click, add existing..) and one with the name pow.mp3

Windows 10 finally brings an easy way to add low latency sound to your universal app with managed classes, without need to do interop with DirectX. The main class is AudioGraph and it is good replacement for XAudio2.

We nee to edit GamePage.xaml.cs and add first three using statements, first of them is not needed for the sound but just to get some debug output in case something goes wrong with the initialization of the audio.

using Windows.Media.Audio;
using System.Diagnostics;
using Windows.Storage;
using Windows.Media.Render;

Now we need to add the member variables which will be used to play the audio, and store the audio files in the memory. AudioGraph class is for the audio playing, AudioDeviceOutputNode is the output device where the sound is played and the AudioFileInputNode has the sound file. These go as member variables to GamePage class, add them under the bool fireSuppressor:

private AudioGraph graph;
private AudioDeviceOutputNode deviceOutput;
private Dictionary<string, AudioFileInputNode> fileInputs = new Dictionary<string, AudioFileInputNode>();

In the Loaded we need to add the the following:

InitSound();

Next we need to add the method itself, which will create the audio pipeline, load the sounds and enable us to play them later on:

private async System.Threading.Tasks.Task InitSound()
{
    AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Media);
    CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);

    if (result.Status == AudioGraphCreationStatus.Success)
    {
        graph = result.Graph;

        // Create the output device for audio playing
        CreateAudioDeviceOutputNodeResult deviceOutputNodeResult = await graph.CreateDeviceOutputNodeAsync();

        // Ensure there's audio output ready and available
        if (deviceOutputNodeResult.Status == AudioDeviceNodeCreationStatus.Success)
        {
            deviceOutput = deviceOutputNodeResult.DeviceOutputNode;
            graph.ResetAllNodes();

            await AddFileToSounds("ms-appx:///Assets/pew.mp3");
            await AddFileToSounds("ms-appx:///Assets/Pop.mp3");
            // here you could list all your sounds like row above

            graph.Start();
        }
    }
}

Add this method, which adds a given sample to memory for playing later on:

/// <summary>
/// Load and add resource sound file to memory dictionary for playing
/// </summary>
/// <returns></return>
private async System.Threading.Tasks.Task AddFileToSounds(string uri)
{
    var soundFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri(uri));
    CreateAudioFileInputNodeResult fileInputResult = await graph.CreateFileInputNodeAsync(soundFile);

    if (AudioFileNodeCreationStatus.Success == fileInputResult.Status)
    {
        fileInputs.Add(soundFile.Name, fileInputResult.FileInputNode);
        fileInputResult.FileInputNode.Stop();
        fileInputResult.FileInputNode.AddOutgoingConnection(deviceOutput);
    }
}

That is all what is needed for setting up playing sounds. Next job for us is to hook the sound playing in the correct places in the code and play the actual sounds. Go to OnFire methos and add the following under bullets.Add(bullet); :

// Play the sound
var pew = fileInputs["pew.mp3"];
pew.Reset();
pew.Start();

The previous code is code to play the shooting sound, now we add the explosion sound for hitting enemy. Go to the HitTest and add under the enemies[i].Dead = true; the following code:

// Play the sound
var pop = fileInputs["Pop.mp3"];
pop.Reset();
pop.Start();

That’s all, now just compile and run the game, and enjoy your sound effects on the game! On the next blog post we’ll be talking about scaling the app on different screens properly, doing the Windows 10 adaptive screen magic.

Posted in AudioGraph, Sound, Universal Apps, UWP, Windows 10, Windows Phone | Leave a comment

How to make a Windows Store game with C# and XAML, part 4

After long pause, here’s the next edition of XAML gaming series. If you are serious game developer, you should check out some of the gaming frameworks, such as Unity or Cocos2D. You could also be interested in Win2D library if you prefer XNA type of programming. The idea of this series is to have fun and learn XAML/C# and Windows features at the same time.

In this episode we bring our project to Windows 10, and add Xbox 360/One controller support for our game. In next part we talk about adding sounds and some other fun things.

You will need to have Windows 10 and any edition of Visual Studio 2015 installed to go on with this project. First, make a backup of your game, and copy it somewhere safe before proceeding with this guide, just in case something goes haywire while converting the project as the following steps include irreversable deleting of files.

Conversion preparations

Start your project in Visual Studio 2015 and now that you have the backup safely in different folder, you can delete the MySpaceInvanders.WindowsPhone project from the solution. Next you select all the files in the Shared-project, and cut/paste them to the MySpaceInvanders.Windows project. Don’t forget to cut/paste also Assets and Common –folders and their content.

Open the App.xaml.cs file, and find all code which is inside #if WINDOWS_PHONE_APP -block and remove it. Remove also the line #ELSE (not the code inside the block) and #ENDIF line. Now you should have no conditional compilation inside the App.xaml.cs file. We handle the other files later.

There’s no AnyCPU project in Windows 10 by default, so we remove it from our solution. Open the Configuration Manager (the small arrow next to AnyCPU text), and choose Configuration Manager, and from Active Solution Platform dropdown choose Edit... Now select AnyCPU and click Remove and accept the removal. Now you can close the Configuration Manager. Select x86 configuration as active configuration.

Conversion

Unfortunately there’s no conversion tool for Windows Universal apps to Windows 10 build inside the Visual Studio, but luckily Andy Wigley and Jerry Nixon have provided such script for public availability.

Open https://github.com/Win10DevGuideMVA/ProjectUpgradeUtility in your browser, and download the zip file. Unpack these script files to your MySpaceInvanders.Windows folder, and open command prompt, navigating to that folder and type to command prompt:

cd c:\source\MySpaceInvanders\MySpaceInvanders.Windows

where the folder matches your local folder and press enter. You are ready to do the actual conversion, so just run the script by typing:

Run_Upgrade_to_uwp.bat

Your output should match something like the following screenshot (Two Trues and one Done without any errors):
conversionFigure 1.

You need to do couple of more steps before you can run your solution.

First open the Package.AppxManifest in code (right click the file in Solution Explorer and select View Code). You must change the text Square30x30Logo to Square44x44Logo. You need later on to upgrade the graphics to match this size as the old icon is too small and will give you error if you try to submit your game to the store.

If you have section called build:Metadata you should remove it completely. Now save the file, change the Build Configuration to ARM and X64 and repeat the previous steps for both configurations, saving the file every time and select lastly the x86 configuration back.

Now you need to remove one more #if WINDOWS_PHONE_APP conditional section from the code, this time from Startpage.xaml.cs where it checks the screen width and height. Your StartPage constructor should look like this:

public StartPage()
{
    this.InitializeComponent();

    ApplicationView view = ApplicationView.GetForCurrentView();

    bool isInFullScreenMode = view.IsFullScreenMode;

    if (!isInFullScreenMode)
    {
        view.TryEnterFullScreenMode();
    }

    Loaded += (sender, args) =>
    {
        CreateStar();
        Move.Completed += MoveStars;
        Move.Begin();
    };

    App.ScreenWidth = Window.Current.Bounds.Width;
    App.ScreenHeight = Window.Current.Bounds.Height;
}

After you’ve done that, you should be able to compile the project without errors and try it out.

Post-conversion

When you start the game, you notice that all the texts from the start screen are missing!

This is a great opportunity to learn a little bit of error resolving with Visual Studio 2015 and about a great new feature called Live Visual Tree. While your app is running, switch back to Visual Studio with alt+tab and go to Debug, Windows and select Live Visual Tree. Expand the window so that you can see it clearly.

You should see tree nodes called StartPage and under it Grid and StartButton. There are two TextBlock items there as well. Now go on and select one of them. Right click it and select Show properties. You can see what values have been set to the control while it’s running and you are able to edit them while your game is running.
Figure 2.Figure 2.

First thing to check is that what color we have set for the text foreground. There’s no Foreground set on Local -section, so it must be inherited from somewhere else. You can see those values in the Default -section.

Now that you found the Foreground, it is showing Black. Where did that come from? In Windows 10 there’s been one big change in application color schemas, the default theme has been set to light. In light theme the text is black and background is white. There’s easy fix for us – stop the debugger, go to the beginning of the xaml -file, and add the following property to the page element:

RequestTheme="Dark"

Add it also to the GamePage.xaml in the same place, for example as a last property just after mc:Ignorable=”d” -text but before the closing tag.

Now all the text should be visible again and you’re good to go.

You could add a small visual candy to the start screen at this point. In the XAML designer select the UNIVERSAL -text block and click Brush in the property window (bottom right of VS), and select the third box below it (Gradient Brush). Repeat the same for the INVANDERS -text. Change the Black in GradientStop color to DarkGrey for both textblocks in XAML of StartPage.xaml and run the app. Now there’s a small chrome effect in the texts.

Let’s get on with the show and continue the conversion. Open the Ship.xaml.cs and remove the #if WINDOWS_PHONE_APP section (and #else and #endif -lines as well). Now do the same in the GamePage.xaml.cs as well.

We need to change shipHorizontalPosition -variable initializer in GamePage.xaml.cs to following (remove readonly and adjust the size):

private double shipHorizontalPosition = App.ScreenHeight - 80;

Windows 10 has changed so that the Store apps can be windowed as well. Right now we don’t add the code to handle resizing (subject for later posts) but add request to run in full screen mode, which is logical for games. Open the StartPage.xaml.cs and add to the top:

using Windows.UI.ViewManagement; 

Next add the following code to constructor after the InitializeComponent:

ApplicationView view = ApplicationView.GetForCurrentView();

            bool isInFullScreenMode = view.IsFullScreenMode;

            if (!isInFullScreenMode)
            {
                view.TryEnterFullScreenMode();
            }

Now you are ready to run the game!

Xbox 360/One controller support

Now we can finally add some Windows 10 goodies to the project. I think adding the controller support is really fitting as it’s useful not only to games but good to learn because it will be relevant for apps as well to enable your app to be controller on Xbox One later on when the Store opens for submissions for it.

We need to take the controller in use in only one place and then use that object through our app. Open the App.xaml.cs file and add to the top:

using Windows.Gaming.Input;

and following member variable:

public static Gamepad GameController;

When we are starting our app, we need to listen to when the app gets the Xbox controller connection by adding handler for GamepadAdded event in constructor after this.Suspending += this.OnSuspending; -line:

Gamepad.GamepadAdded += Gamepad_GamepadAdded;

Add the following method just below the constructor:

private void Gamepad_GamepadAdded(object sender, Gamepad e)
        {
            GameController = Gamepad.Gamepads.First();
        }

By adding the code above, you have now access to Xbox controller through out your app. At this point your App.xaml.cs should look something like this:

using System;
using System.Linq;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using MySpaceInvanders.Common;
using Windows.Gaming.Input; // XBOX


namespace MySpaceInvanders
{
    /// <summary>
    /// Provides application-specific behavior to supplement the default Application class.
    /// </summary>
    public sealed partial class App : Application
    {
        public static double ScreenWidth { get; set; }
        public static double ScreenHeight { get; set; }
        public static int Highscore { get; set; }

        public static Gamepad GameController; // XBOX

        /// <summary>
        /// Initializes the singleton instance of the <see cref="App"/> class. This is the first line of authored code
        /// executed, and as such is the logical equivalent of main() or WinMain().
        /// </summary>
        public App()
        {
            this.InitializeComponent();
            this.Suspending += this.OnSuspending;
            Gamepad.GamepadAdded += Gamepad_GamepadAdded; // XBOX

        }
        private void Gamepad_GamepadAdded(object sender, Gamepad e)
        {
            GameController = Gamepad.Gamepads.First();
        }

        /// <summary>
        /// Invoked when the application is launched normally by the end user.  Other entry points
        /// will be used when the application is launched to open a specific file, to display
        /// search results, and so forth.
        /// </summary>
        /// <param name="e">Details about the launch request and process.</param>
        protected async override void OnLaunched(LaunchActivatedEventArgs e)
        {
#if DEBUG
            if (System.Diagnostics.Debugger.IsAttached)
            {
                this.DebugSettings.EnableFrameRateCounter = true;
            }
#endif

            Frame rootFrame = Window.Current.Content as Frame;

            // Do not repeat app initialization when the Window already has content,
            // just ensure that the window is active
            if (rootFrame == null)
            {
                // Create a Frame to act as the navigation context and navigate to the first page
                rootFrame = new Frame();

                //Associate the frame with a SuspensionManager key                                
                SuspensionManager.RegisterFrame(rootFrame, "AppFrame");

                // TODO: change this value to a cache size that is appropriate for your application
                rootFrame.CacheSize = 1;

                if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    // Restore the saved session state only when appropriate
                    try
                    {
                        await SuspensionManager.RestoreAsync();
                    }
                    catch (SuspensionManagerException)
                    {
                        // Something went wrong restoring state.
                        // Assume there is no state and continue
                    }
                }

                // Place the frame in the current Window
                Window.Current.Content = rootFrame;
            }

            if (rootFrame.Content == null)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                if (!rootFrame.Navigate(typeof(StartPage), e.Arguments))
                {
                    throw new Exception("Failed to create initial page");
                }
            }

            // Ensure the current window is active
            Window.Current.Activate();
        }

        /// <summary>
        /// Invoked when application execution is being suspended.  Application state is saved
        /// without knowing whether the application will be terminated or resumed with the contents
        /// of memory still intact.
        /// </summary>
        private async void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();
            await SuspensionManager.SaveAsync();
            deferral.Complete();
        }
    }
}

Let’s start by adding ship movement and firing to the game. Open the Gamepage.xaml.cs -file, and add the following using statement:

using Windows.Gaming.Input;

For better gameplay experience, I have added also bit which prevents Xbox controller autofiring all the time when the trigger is pressed. If you don’t like this, you can just comment it out later on. Add the following member variable:

bool fireSuppressor; // XBOX, prevent autofire

We need a place where we can read the controller values enough often without affecting the gameplay. I have opted in using the MoveStars -method which is not necessary the elegant solution but works anyway nicely. Add the following code to the very beginning of MoveStars -method:

if (App.GameController != null)
            {
                GamepadReading reading = App.GameController.GetCurrentReading();
                
                // Use 0.4 so the stick don't have to be exactly to right or left, but is more forgiving
                if ((double)reading.RightThumbstickX < -0.4)
                {
                    MoveShip(-5);
                }
                else if ((double)reading.RightThumbstickX > 0.4)
                {
                    MoveShip(5);
                }

                if ((int)reading.RightTrigger > 0 && fireSuppressor == false)
                {
                    fireSuppressor = true;
                    OnFire(null, null);
                }
                else if((int)reading.RightTrigger == 0) // require depress of trigger before shoot another
                {
                    fireSuppressor = false;
                }
            }

In the code above we ask from the controller what are all the current readings in it. After that we check if the right thumb stick has been moved. I checked values above and below 0.4 so the user don’t have to move the stick exactly horizontally for the ship to move. After moving the ship I’m checking if the right trigger has been pressed, and it has been released between previous visit to this loop, forcing the player to pull the trigger for each shot.

Now you can test the game and you should be able to move the ship with right thumb stick and shoot with right trigger. I tested it with connecting Xbox One controller with the charging cable to the PC and it worked like a charm. The same code should run as it is with Xbox 360 controller as well.

One more addition is that we should be able to start the game with the controller as well. Go to the Startpage.xaml, change the StartButton Content to:”Start (A)”. Open the StartPage.xaml.cs and add the following using:

using Windows.Gaming.Input; // XBOX

After you’ve done that, find the MoveStars -method. Add the following code to the beginning of it:

           if (App.GameController != null)
            {
                GamepadReading reading = App.GameController.GetCurrentReading();

                if (reading.Buttons == GamepadButtons.A)
                {
                    OnStart(null, null);
                }
            }

Find the OnStart -method, and add the following to the beginning of it:

Move.Completed -= MoveStars;
            Move.Stop();

That’s it, now you can test your game and you should be able to start it by pressing the A-button on your Xbox controller, move your ship and shoot. I hope you are having fun with these and do leave comments what you would like to see next incorporated to the game (sounds are coming next, otherwise I’m open to suggestions).

Posted in Universal Apps, Windows 10 | Tagged , , , , | 4 Comments

Windows 10 resources

There’s been quite many people asking me Windows 10 development questions and how to do certain things in new UWP apps. Obvious answer would have been lmgtfy.com or letmebingthatforyou.com but instead I decided to just put up my own list of best resources that I have found so far. I plan to update this list as new material surfaces, so you would have always up-to-date list of pre-screened materials of the highest quality. Without further delay, here’s my favorite Win 10 dev links:

Developer’s Guide to Windows 10 is the best crash course for Windows 10, highly recommended as a starting point for anyone planning to start developing apps on Windows 10 family of products.

Windows Universal App Samples is a github repository with all Microsoft official Windows 10 samples for you to check out how to implement correctly Win 10 features in your own app.

How-to guides are perfect step by step guides for more entry level developers to start implementing features Win 10 to your apps.

Stackoverflow UWP tag is a good place to post your questions if you don’t find any answers to your questions or if you want to check out if someone else has had the same issue and managed to solve it. Quite obvious place, but I have fetched the answers to problems presented to me so many times that I think it’s still worth mentioning.

Dot Net By Example is a blog run by Windows Development Platform MVP, Joost Van Schaik, who is beside being a great guy, also mapping wizard, so that’s the place where I check first when I have any issues related to mapping on Windows. He has also some great IOT posts in his blog.

Windows 10 Design guidelines is where you should take a look before deciding on your application’s UX. Although you are pretty free to do whatever you want, it still might give you some great tips what works best on multiple screen sizes and resolutions.

Windows 10 Tutorials is really simple step by step series of blog posts to do many of the Windows features such as tiles, notifications, media player and toasts for example.

Here’s a list of blogs/posts/tweets for certain specific scenarios in app development:
Back Button in Windows 10
Playing sounds

Hosted web apps:

What are the things need to take in consideration when packaging a website
Project Westminster in a nutshell
Building simple Hosted Web Apps
ManifoldJS Quick Start
ManifoldJS getting started

How to handle back button
Can be done in JS on page ex, example
Using ManifoldJS to get more out of web sites

How to handle opening links, that they will open up inside your app and not in the browser
Handling opening links 1
Handling opening links 2

Hybrid elements, for example using native map component to show positions in the map
Packaged vs Hosted
Windows Apis sample

Posted in Universal Apps | 1 Comment

How to make a Windows Store game with C# and XAML, part 3

Moving the ship
When we’re doing a universal app, we have to take in account that there are several possible ways for users to control the game. Phones and tablets have touch screens, but on desktop still most of us prefer to use keyboard to play games.

For doing the movements, we need to be aware of the screen dimensions. Add these member variables to App.xaml.cs class:

public static double ScreenWidth { get; set; }
public static double ScreenHeight { get; set; }
public static int Highscore { get; set; }

We set these values in StartPage.xaml.cs, at the end of the constructor, after the Loaded -lambda:

#if WINDOWS_PHONE_APP
            App.ScreenWidth = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Bounds.Width;
            App.ScreenHeight = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Bounds.Height;
#endif
#if WINDOWS_APP
            
            App.ScreenWidth = Window.Current.Bounds.Width;
            App.ScreenHeight = Window.Current.Bounds.Height;
#endif

Here we used #if statements to run different code depending on the platform we’re running, the code will be compiled to include just the platform specific code for each build for Phone and Windows.

Now we open the GamePage.xaml.cs and add the following member variables to keep track of the ship position:

private double shipPosition;
private readonly double shipHorizontalPosition = App.ScreenHeight - 50;

Now we’re ready to create the actual method to move the ship. We add first this to the top of the GamePage.xaml.cs:

using Windows.System;

And then this to the end of the GamePage.xaml.cs:

private void MoveShip(int amount)
{
    shipPosition += amount;
 
    // Let's make sure that the ship stays in the screen
    if (shipPosition > LayoutRoot.ActualWidth - 30)
    {
        shipPosition = LayoutRoot.ActualWidth - 30;
    }
    else if (shipPosition < 0)
    {
        shipPosition = 0;
    }
 
    Rocket.Margin = new Thickness(shipPosition, shipHorizontalPosition, 0, 0);
}

The method moves the ship the amount specified in the calling function (in pixels), and checks that it doesn’t go over the boundaries from left or right.

Next we’ll capture the keyboard in case the user is playing with desktop machine. Let’s create the event handler for key events. Open GamePage.xaml.cs constructor, and add the following after InitializeComponent():

Loaded += (sender, args) =>
{
    // Resize move controls to fit the area
    LeftCanvas.Width = LeftCanvas.Height = (LeftArea.ActualWidth / 2) - 10;
    RightCanvas.Width = RightCanvas.Height = (LeftArea.ActualWidth / 2) - 10;

    // Position the ship to the bottom center of the screen
    shipPosition = LayoutRoot.ActualWidth / 2;
    Rocket.Margin = new Thickness(shipPosition, shipHorizontalPosition, 0, 0);
 
    Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
};

Next we add the actual code to handle the key presses by adding the following method:

private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
{
    switch (args.VirtualKey)
    {
        case VirtualKey.Left:
            MoveShip(-5);
            break;
        case VirtualKey.Right:
            MoveShip(5);
            break;
        case VirtualKey.Space:
            OnFire(null, null);
            break;
        default:
            break;
    }
}

Star field background
We had one type of particle engine on the start screen, but I think we need something of a more traditional kind to create sense of moving for the ship. First we need to add one using –statement to the top of the file:

using Windows.UI;

Then we need to add some more member variables for the starfield:

private const int StarCount = 200
private List<Dot> stars = new List<Dot>(StarCount);
private Random randomizer = new Random();

Here’s altered versions of CreateStar and MoveStars methods, which we add to the GamePage.xaml.cs:

void MoveStars(object sender, object e)
{
    if (stars.Count < StarCount)
    {
        CreateStar();
    }

    foreach (Dot star in stars)
    {
        Canvas.SetLeft(star.Shape, Canvas.GetLeft(star.Shape) + star.Velocity.X);
        Canvas.SetTop(star.Shape, Canvas.GetTop(star.Shape) + star.Velocity.Y);

        if (Canvas.GetTop(star.Shape) > LayoutRoot.ActualHeight)
        {
            int left = randomizer.Next(0, (int)LayoutRoot.ActualWidth);
            Canvas.SetLeft(star.Shape, left);
            Canvas.SetTop(star.Shape, 0);
        }
    }
    Move.Begin();
}
private void CreateStar()
{
    var star = new Dot()
    {
        Shape = new Ellipse() { Height = 2, Width = 2 },
        Velocity = new Point(0, randomizer.Next(1, 5))
    };

    int left = randomizer.Next(0, (int)LayoutRoot.ActualWidth);
    Canvas.SetLeft(star.Shape, left);
    Canvas.SetTop(star.Shape, 0);
    Canvas.SetZIndex(star.Shape, 1);
            
    // Set color
    byte c = (byte)randomizer.Next(10,255);
    star.Shape.Fill = new SolidColorBrush(Color.FromArgb(c, c, c, c));

    stars.Add(star);
    LayoutRoot.Children.Add(star.Shape);
}

Now we go to the constructor of the same class, and add inside the end of the Loaded lambda the following code:

// Starfield background
CreateStar();
Move.Completed += MoveStars;
Move.Begin();

Now if you run the game, you see how stars are falling in different speeds from the top of the screen, creating sense of depth and speed.

Adding enemies
What would a shoot’em up be without any enemies to shoot? Next we’ll add some enemies to the screen to get some action to the screen.

Let’s create a new UserControl, and call it Bobo by right clicking the Shared project, and Add, New Item, User Control. You could give it some nice bitmap images, but for this exercise I’m using XAML to draw the the creature. Open Bobo.xaml and copy/paste the following on top the XAML:

<UserControl
    x:Class="MySpaceInvanders.Bobo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Width="60" Height="60">
 
    <Canvas Width="60" Height="60">
        <Ellipse x:Name="InsideEllipse" Width="60" Height="60" Margin="0,0"/>
        <Polygon Stroke="Black" Fill="Green" Points="10,10,5,0,15,5"/>
        <Polygon Stroke="Black" Fill="Green" Points="45,5,55,0,50,10"/>
        <Ellipse Width="5" Height="5" Fill="Gold" Margin="20,20" />
        <Ellipse Width="5" Height="5" Fill="Gold" Margin="35,20" />
        <Ellipse Width="30" Height="8" Fill="HotPink" Margin="15,40" />
    </Canvas>
</UserControl>

Open the Bobo.xaml.cs and add the following member variables to the class:

public int AreaWidth { get; set; }
public Point Location { get; set; }
public bool Dead { get; set; }
public int Worth { get; set; } // amount of score for kill
public int Type; // 1 - green, 2 - blue, 3 - mega
private readonly Random randomizer = new Random();
public double Velocity;
private int direction;
private int directionCount = 0; // don't change direction on every loop

Add also the velocity and type randomizer to the constructor, just after the InitializeComponent –call:

Velocity = randomizer.Next(1, 3);
Type = randomizer.Next(1, 4);
if (Type == 3)
{
    Velocity = 4;
}
SetType();

Now we have three different types of enemies, and one of them moves faster than the others. For the enemy to move on the screen, we’ll add the Move method for it:

public void Move()
 {
     int move;
 
     // Randomize the move direction
     if (directionCount == 0)
     {
         direction = randomizer.Next(1, 3);
     }
     if (direction == 1)
     {
         move = -1;
     }
     else
     {
         move = 1;
     }
     directionCount++;
 
     // Change direction every 30 count
     if (directionCount > 30)
     {
         directionCount = 0;
     }
 
     // Check that the bobo doesn't go through the game area walls
     if (Location.X + direction < 0)
     {
         move = 0;
     }
     if (Location.X + direction > AreaWidth)
     {
         move = AreaWidth;
     }
 
     // Set the new location
     Location = new Point(Location.X + move, Location.Y + Velocity);
 }

We need to add also method to set the color according to the type of the enemy and give them unique kill score. Add the following method to Bobo.xaml.cs:

private void SetType()
{
    switch (Type)
    {
        case 1:
            SetFill(Color.FromArgb(0xFF, 0x00, 0xA2, 0x07), Color.FromArgb(0xFF, 0x3A, 0xFF, 0x00));
            Worth = 10;
            break;
        case 2:
            SetFill(Color.FromArgb(0xFF, 0x00, 0x00, 0xa0), Color.FromArgb(0xFF, 0x00, 0x0F, 0xff));
            Worth = 20;
            break;
        case 3:
            SetFill(Color.FromArgb(0xFF, 0xaf, 0x00, 0x00), Color.FromArgb(0xFF, 0xff, 0x0F, 0x00));
            Worth = 50;
            break;
    }
}

private void SetFill(Color start, Color end)
{
    var startGradient = new GradientStop();
    var endGradient = new GradientStop();
    startGradient.Color = start;
    startGradient.Offset = 1;
    endGradient.Color = end;
    var collection = new GradientStopCollection();
    collection.Add(startGradient);
    collection.Add(endGradient);

    InsideEllipse.Fill = new LinearGradientBrush(collection, 0);
}

Now we have a nasty looking foe for our ship to shoot at. Next we open the GamePage.xaml.cs and add again some prerequisites for our swarm of enemies. Add the following member variables:

private List<Bobo> enemies = new List<Bobo>();
private int maxEnemies = 20;
private DispatcherTimer timer = new DispatcherTimer();
private int Level { get; set; } // Player level 
private int Score { get; set; } // Game score

You can adjust the game difficulty by increasing maxEnemies at later level of the game for example.

We have everything set for our enemies to appear on the screen. We need to just add them to the GamePage.xaml.cs. First edit the Loaded –lambda on constructor to include the following at the bottom of it:

timer.Tick += TimerOnTick;
timer.Interval = new TimeSpan(0, 0, 0, 2);
timer.Start();

And then the Tick method to call:

/// <summary>
/// Create a new enemy if not max amount on the screen already
/// </summary>
/// <param name="sender"></param>
/// <param name="o"></param>
private void TimerOnTick(object sender, object o)
{
    if (enemies.Count < maxEnemies)
    {
        var enemy = new Bobo
        {
            AreaWidth = (int)LayoutRoot.ActualWidth,
            Location = new Point(randomizer.Next(0, (int)LayoutRoot.ActualWidth - 80), 0)
        };
        if (enemy.Type == 3)
        {
            // Make the red enemy smaller and more difficult to hit
            var scaleTransform = new ScaleTransform();
            scaleTransform.ScaleX = scaleTransform.ScaleX * 0.50;
            scaleTransform.ScaleY = scaleTransform.ScaleY * 0.50;
            enemy.RenderTransform = scaleTransform;
            enemy.Width = 30;
            enemy.Height = 30;
        }
        enemy.Velocity = enemy.Velocity * ((Level / (double)10) + 1);
        enemies.Add(enemy);
        Canvas.SetZIndex(enemy, 7);
        LayoutRoot.Children.Add(enemy);
    }
}

All this code will create different types of monsters to the screen, but they’re still sitting static on the top. That’s kind of boring, so let’s add the long awaited game loop to move them:

private void GameLoop(object sender, object e)
{
    if (goingRight)
        MoveShip(5);
    if (goingLeft)
        MoveShip(-5);
    // TODO - collision test

    // TODO - move bullets

    // Move enemies
    for (int i = 0; i < enemies.Count; i++)
    {
        if (enemies[i].Dead == false)
        {
            enemies[i].Move();
            enemies[i].Margin = new Thickness(enemies[i].Location.X, enemies[i].Location.Y, 0, 0);
        }
 
        if (enemies[i].Margin.Top > App.ScreenHeight || enemies[i].Dead)
        {
            LayoutRoot.Children.Remove(enemies[i]);
            enemies.Remove(enemies[i]);
        }
    }
}

Now we just have to make sure our game loop gets called, so we open the constructor, and add as very last line, after the Loading –lambda has closed, the following line:

CompositionTarget.Rendering += GameLoop;

Go ahead, try the project now, and you should see the star field moving, ship should respond to the keyboard and enemies should move randomly from top to down.

Open fire!
Now our little game seems to be a bit boring, enemies come and sail through your ship and you can’t shoot. We need to add collision detection and possibility to shoot the enemies to make it a bit more interesting. Let’s start with shooting! Add the following member variables to GamePage.xaml.cs:

private List<Ellipse> bullets = new List<Ellipse>(); // Bullets on the screen
private bool gameRunning = true; // Did we die already

and for ellipses we need to add also this using:

using Windows.UI.Xaml.Shapes;

Now we edit the OnFire –method we added on the second part of the tutorial. Add the following code to it:

if (gameRunning)
{
    var bullet = new Ellipse
    {
        Width = 5, Height = 5, Fill = new SolidColorBrush(Colors.Red)
    };
    bullet.Margin = new Thickness(shipPosition + (Rocket.Width/2) - (bullet.Width/2),
        shipHorizontalPosition + 2, 0, 0);
    LayoutRoot.Children.Add(bullet);
    bullets.Add(bullet);
}

The code above checks that the player is still alive, and if yes, creates a new ellipse as a bullet and adds it to the bullet list, so we can later easily check if any of the bullets hit anything on the screen. At this point we have static bullets in the screen, so logical step is to add moving functionality to the game by adding this:

private void MoveBullet(Ellipse ellipse)
{
    if ((ellipse.Margin.Top - 10) > 0)
    {
        ellipse.Margin = new Thickness(ellipse.Margin.Left, ellipse.Margin.Top - 10, 0, 0);
        HitTest(ellipse);
    }
    else
    {
        bullets.Remove(ellipse);
        LayoutRoot.Children.Remove(ellipse);
    }
}

The code above moves the bullet 10 pixels upwards until it goes off the screen. At that point it is removed from the bullet list. Let’s add the HitTest method to see if our bullets actually hit anything:

private void HitTest(Ellipse ellipse)
{
    for (int i = 0; i < enemies.Count; i++)
    {
        var enemyInFire = new Rect(enemies[i].Location.X, enemies[i].Location.Y, enemies[i].ActualWidth, enemies[i].ActualHeight);
        if (enemyInFire.Contains(new Point(ellipse.Margin.Left, ellipse.Margin.Top)))
        {
            Score += enemies[i].Worth;
            ScoreBoard.Text = Score.ToString();
            if (Score > App.Highscore)
            {
                App.Highscore = Score;
                HighscoreBoard.Text = Score.ToString();
            }
            LayoutRoot.Children.Remove(ellipse);
            bullets.Remove(ellipse);
            enemies[i].Dead = true;
            return;
        }
    }
}

To move the bullets, add this to the GameLoop -method, over the // TODO – move bullets text:

for (int i = 0; i < bullets.Count; i++)
{
    MoveBullet(bullets[i]);
}

At this point, you’re ready to shoot some aliens from outer space! But it kind of gets boring as there’s no way you can die yet, as we’re not testing if the aliens hit you. Let’s add few more things and it starts to come together. First we need the famous game over notification. Add this member variable to GamePage.xaml.cs:

private TextBlock GameOver = new TextBlock();

After that we need a crash test method:

private void CrashTest()
{
    for (int i = 0; i < enemies.Count; i++)
    {
        var enemyCreature = new Rect(enemies[i].Location.X, enemies[i].Location.Y, enemies[i].ActualWidth, enemies[i].ActualHeight);
        enemyCreature.Intersect(new Rect(Rocket.Margin.Left, Rocket.Margin.Top, Rocket.ActualWidth,
            Rocket.Margin.Top));
        if (!enemyCreature.IsEmpty)
        {
            CompositionTarget.Rendering -= GameLoop;
            Move.Completed -= MoveStars;
 
            GameOver.Text = "Game Over!";
            GameOver.FontSize = 48;
            GameOver.VerticalAlignment = VerticalAlignment.Center;
            GameOver.HorizontalAlignment = HorizontalAlignment.Center;
            Grid.SetColumn(GameOver, 1);
 
            MainGrid.Children.Add(GameOver);
            gameRunning = false;
 
            if (App.Highscore < Score)
            {
                App.Highscore = Score;
            }
        }
    }
}

Finally we need to add to the GameLoop call to the CrashTest, overwriting the // TODO – collision test with call to our method: CrashTest();

If you try the game, you soon realize that if the enemies crash to your ship, that’s the end of you! This is the end of part three of Universal Games for Windows. On the next post we’ll continue to improve the game by adding universal high score system, levels, navigation and other relevant things to finish up the game.

Download the solution so far from here

Posted in Universal Apps, Windows Phone 8.1 | Tagged | 16 Comments

How to make a Windows Store game with C# and XAML, part 2

Creating the game field and player

On previous parts we set up the project and created a nice start screen. But game needs more than just the start screen. On this post we’ll create a game screen, enable navigation to it from the start screen, and add the player ship to it.

We create the game field by creating a new blank page called GamePage. We add it to the Shared –project (right click, Add, New Item, Blank Page). Because we support Windows and Windows Phone, we need to adjust our game page depending if we’re on a small phone screen or a larger screen such as tablet or desktop. Typically this is done by using VisualState manager, but for the sake of keeping simple as possible, on this tutorial we’ll just do required adjustment in code.

Next step is to add the player ship to Shared project, so create a new user control and name it Ship.

Replace the Ship.xaml with the following:

<UserControl
    x:Class="MySpaceInvanders.Ship"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MySpaceInvanders"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:foundation="using:Windows.Foundation"
    mc:Ignorable="d">

    <Polygon x:Name="BodyShape" Stroke="Black" Fill="Red"/>
</UserControl>

and then the constructor content in Ship.xaml.cs with:

public Ship()
        {
            this.InitializeComponent();
#if WINDOWS_PHONE_APP
            Width = 20;
            Height = 40;
            BodyShape.Points = new PointCollection()
            {
                new Point(0, 40), new Point(10,0), new Point(20,40)
            };
#else
            Width = 40;
            Height = 80;
            BodyShape.Points = new PointCollection()
            {
                new Point(0, 80), new Point(20,0), new Point(40,80)
            };
#endif
        }

In that code we’re using #if WINDOWS_PHONE_APP to define the code which we use to give size to the control when running on phone and in #else we are defining the shape for Windows app. Currently they are just different size, and we could have handled that in XAML by just stretching the ship accordingly but this leaves us option to have different ship shape in each platform.

Copy the following to the MySpaceInvanders.Shared -project’s GamePage.xaml, overwriting all the existing markup:

<Page
    x:Class="MySpaceInvanders.GamePage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MySpaceInvanders"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" >
<Page.Resources>

</Page.Resources>
    <Grid x:Name="MainGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="LeftArea" Width="2*"/>
            <ColumnDefinition x:Name="MiddleArea" Width="12*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>
        <Grid Grid.Column="0" Background="RoyalBlue">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>

The code above divides the field in three different sectors, one for scores and ship controls, one for play field and for the fire button. Copy the following code under the code above:

            <TextBlock Text="Highscore:" Grid.Row="0" Margin="5,0"/>
            <TextBlock x:Name="HighscoreBoard" Grid.Row="0" Text="0" Margin="5,32"/>
            <TextBlock x:Name="ScoreTitle" Text="Score:" Grid.Row="0" Margin="5,64"/>
            <TextBlock x:Name="ScoreBoard" Grid.Row="0" Text="0" Margin="5,73,0,0"/>
            <Grid x:Name="LeftCanvas" Grid.Row="2" 
                    VerticalAlignment="Bottom" 
                    HorizontalAlignment="Left" 
                    PointerPressed="ToLeftPressed" 
                    PointerReleased="ToLeftReleased" 
                    PointerExited="ToLeftExited" >
                <Ellipse x:Name="ToLeft" Stretch="Uniform" Fill="Azure"/>
                <Polygon Stroke="Black" Fill="Blue" Stretch="Uniform"
                         Points="5,40,60,10,60,70" RenderTransformOrigin="0.5,0.5">
                      <Polygon.RenderTransform>
                        <ScaleTransform ScaleX="0.75" ScaleY="0.75"/>
                    </Polygon.RenderTransform>
                </Polygon>
            </Grid>
            <Grid x:Name="RightCanvas" Grid.Row="2" 
                    VerticalAlignment="Bottom" 
                    HorizontalAlignment="Right" 
                    PointerPressed="ToRightPressed" 
                    PointerReleased="ToRightReleased" 
                    PointerExited="ToRightExited" >
                <Ellipse x:Name="ToRight" Stretch="Uniform" Fill="Azure"/>
                <Polygon Stroke="Black" Fill="Blue" Stretch="Uniform"
                         Points="75,40,25,10,25,70" RenderTransformOrigin="0.5,0.5">
                    <Polygon.RenderTransform>
                        <ScaleTransform ScaleX="0.75" ScaleY="0.75"/>
                    </Polygon.RenderTransform>
                </Polygon>
            </Grid>
        </Grid>

The code above sets the score, highscore and player moving controls to the screen. Notice that we are using PointerReleased and PointerExited events for controlling the ship, those are only events which will give you smooth control over the ship movement. Copy the following code under the code above:

<Canvas x:Name="LayoutRoot" 
                Background="Black" 
                Grid.Column="1">
            <Canvas.Resources>
                <Storyboard x:Name="Move"/>
            </Canvas.Resources>

            <local:Ship x:Name="Rocket"/>
        </Canvas>

The code above sets the playing field, and sets the ship on the screen. Copy the following code under the code above:

<Grid x:Name="FireButton" Grid.Column="2" 
              VerticalAlignment="Bottom" 
              HorizontalAlignment="Right" 
              Tapped="OnFire">
            <Ellipse Width="100" Height="100" 
                     VerticalAlignment="Top" 
                     HorizontalAlignment="Center">
                <Ellipse.Fill>
                    <LinearGradientBrush>
                        <GradientStop Color="#9AA20000" Offset="1"/>
                        <GradientStop Color="Red"/>
                    </LinearGradientBrush>
                </Ellipse.Fill>
            </Ellipse>
            <Ellipse Width="70" Height="70" 
                     VerticalAlignment="Center" 
                     HorizontalAlignment="Center">
                <Ellipse.Fill>
                    <LinearGradientBrush>
                        <GradientStop Color="#00FF8585" Offset="0"/>
                        <GradientStop Color="#1AFFFFFF" Offset="1"/>
                        <GradientStop Color="#3FF5C2C2" Offset="0.349"/>
                    </LinearGradientBrush>
                </Ellipse.Fill>
            </Ellipse>
        </Grid>
    </Grid>
</Page>

Code above draws the firing button on the screen. We’re using two ellipses to give impression of dimension for the button surface.

As mentioned earlier, we’re doing the differences in code to handle phone and desktop/tablet versions. For the GamePage we do it so, that we open the GamePage.xaml.cs and edit the constructor public GamePage() and add the following just under the this.InitializeComponent:

#if WINDOWS_PHONE_APP
            MiddleArea.Width = new GridLength(6, GridUnitType.Star);
            Style style = new Style(typeof(TextBlock));
            style.Setters.Add(new Setter(TextBlock.FontSizeProperty, 24));
            style.Setters.Add(new Setter(VerticalAlignmentProperty, VerticalAlignment.Top));
            style.Setters.Add(new Setter(HorizontalAlignmentProperty, HorizontalAlignment.Left));
            Resources.Add(typeof(TextBlock), style);
            HighscoreBoard.Margin = new Thickness(5, 22, 0, 0);
            ScoreTitle.Margin = new Thickness(5, 44, 0, 0);
            ScoreBoard.Margin = new Thickness(5, 73, 0, 0);
#else
            MiddleArea.Width = new GridLength(12, GridUnitType.Star);
            Style style = new Style(typeof(TextBlock));
            style.Setters.Add(new Setter(TextBlock.FontSizeProperty, 32));
            style.Setters.Add(new Setter(VerticalAlignmentProperty, VerticalAlignment.Top));
            style.Setters.Add(new Setter(HorizontalAlignmentProperty, HorizontalAlignment.Left));
            Resources.Add(typeof(TextBlock), style);
            HighscoreBoard.Margin = new Thickness(5, 32, 0, 0);
            ScoreTitle.Margin = new Thickness(5, 64, 0, 0);
            ScoreBoard.Margin = new Thickness(5, 96, 0, 0);
#endif

Now that we have the UI set, we’ll add some functionality to enable ship to move later on. Open the GamePage.xaml.cs and add these members to the class:

private bool goingLeft = false, goingRight = false;

After that we need to add the event handlers under the constructor:

private void ToLeftPressed(object sender, PointerRoutedEventArgs e)
        {
            goingLeft = true;
        }
 
        private void ToRightPressed(object sender, PointerRoutedEventArgs e)
        {
            goingRight = true;
        }
 
        private void ToLeftReleased(object sender, PointerRoutedEventArgs e)
        {
            goingLeft = false;
        }
 
        private void ToLeftExited(object sender, PointerRoutedEventArgs e)
        {
            goingLeft = false;
        }
        private void ToRightReleased(object sender, PointerRoutedEventArgs e)
        {
            goingRight = false;
        }
 
        private void ToRightExited(object sender, PointerRoutedEventArgs e)
        {
            goingRight = false;
        }
private void OnFire(object sender, TappedRoutedEventArgs e)
{
}

To enable navigation to game screen from the start page, we’ll open the StartPage.xaml.cs and add to the OnStart -method the following code:

this.Frame.Navigate(typeof (GamePage));

Now we can test that launching the app, and pressing the Start-button should show us a screen with controls and ship, which is still not positioned correctly and not moving.

Check out the part 3

Posted in Universal Apps, Windows Phone 8.1 | Tagged | 10 Comments

How to make a Windows Store game with C# and XAML, part 1

I believe that games are still one of the most fun ways to get to know a new programming language. As there’s currently shortage of beginner level game programming tutorials for Universal Apps, I thought I’d share you how I did a simple shoot’em up for Windows and Windows Phone with shared code.

I tried to include all the steps, so you can follow it like a hands on lab while doing your own version. You can find the finished tutorial from the Windows Store and Windows Phone Store to download and try it out. I also made the finished tutorial source available for you to play with.

Creating the project
Creating the game project doesn’t differ from creating a normal app, so you would open the Visual Studio, go to File.. New, Project, and select from under Visual C#, Store Apps and Universal Apps. As this is the most basic version of a game, we’re not doing MVVM but keep it as simple as possible. For the same purpose, we select Hub App as a project type, and give it a name, for example “MySpaceInvanders”.
1
When you got the project set up, you got three projects in your solution tree in the right, “MySpaceInvanders.Windows”, “MySpaceInvanders.WindowsPhone” and “MySpaceInvanders.Shared”. We’ll do some housekeeping, and remove everything else from the solution by pressing Delete key on top of the files, until you’re left with a solution which looks like this:
2
We’re going to put all the logic to the Shared project so it will be really easy to upkeep and keep adding features.

Next we’ll do some basic settings for the projects by going to the project settings. First open the Package.appxmanifest in MySpaceInvanders.WindowsPhone.
On the Application –tab, select from Supported rotations “Landscape”. Now open the same file from MySpaceInvanders.Windows, and select also only “Landscape” and save your changes. Go to Visual Assets –tab in Package.appxmanifest and change Background color to #000000 for both projects as well.

Creating a start page
We’re forgetting the splash screens for now, and focusing on the first screen which will be where the game can be started, and high scores are visible. Right click on the solution explorer on the Shared –project, select Add, New Item, and Blank Page. Give the page name “StartPage.xaml” and click ok. Next we’ll set it as a start page by opening the App.xaml.cs file in the Shared –project, and going to the OnLaunched -method. There you will find a line of code like this:

if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))

Now we changed the MainPage text from that line to StartPage to launch our custom start up page when the app launches.

Open the StartPage.xaml, and copy the following on top of the <Grid> … </Grid> area of code:

<Grid>
    <Button x:Name="StartButton" Content="Start" 
            Margin="0,12,0,0" 
            HorizontalAlignment="Center" 
            VerticalAlignment="Bottom" 
            Height="105" Width="370" 
            FontFamily="Georgia" 
            FontSize="48" 
            Click="OnStart"/>
    <TextBlock Text="UNIVERSAL "
               HorizontalAlignment="Center" 
               VerticalAlignment="Top" 
               Margin="0,53,0,0" TextWrapping="Wrap" 
               FontFamily="Georgia" FontSize="48"/>
    <TextBlock Text="INVANDERS" 
               HorizontalAlignment="Center" 
               VerticalAlignment="Top" 
               Margin="0,103,0,0" 
               TextWrapping="Wrap" 
               FontFamily="Georgia" FontSize="48"/>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBlock Text="Highscore:" 
                   Grid.Column="0" 
                   HorizontalAlignment="Right" 
                   VerticalAlignment="Top" 
                   Margin="0,203,0,0" 
                   TextWrapping="Wrap" 
                   FontFamily="Georgia" 
                   FontSize="32"/>
        <TextBlock x:Name="HighScoreBlock" Text="0" 
                   Grid.Column="1" 
                   HorizontalAlignment="Left" 
                   VerticalAlignment="Top" 
                   Margin="0,203,0,0" 
                   TextWrapping="Wrap" 
                   FontFamily="Georgia" 
                   FontSize="32"/>
    </Grid>
    <Canvas x:Name="LayoutRoot">
        <Canvas.Resources>
            <Storyboard x:Name="Move"/>
        </Canvas.Resources>
    </Canvas>
</Grid>

Add the following to StartPage.xaml.xs:

private void OnStart(object sender, RoutedEventArgs e)
{
 
}

Adding some animation
Now that we have the start screen set up, it looks kind of dull. Let’s put emitter there to shoot some stars to make it look more alive. If you look at the XAML we just added, you notice a Canvas element which has a Storyboard element inside it. That is our animation container, which will show the emitter.

First we need a particle for the emitter. We’ll create class called Dot by right clicking the MySpaceInvanders.Shared -project, and selecting Add, New Item, Class. Make sure the Name –field has Dot.cs written in it before clicking ok. Next we’ll open the Dot.cs and add some properties to the particle. Each particle will have two different properties: Shape and Velocity. Add the following member variables to class Dot

public Ellipse Shape { get; set; }
public Point Velocity { get; set; }

Next we need to create the emitter itself, which will be shooting these particles we just created. Open the StartPage.xaml.cs, add on the top of the file:

using Windows.UI;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

Then we need to add these member variables to StartPage class

private const int StarCount = 200;
private List<Dot> stars = new List<Dot>(StarCount);
private Random randomizer = new Random();

After we have a list to keep the particles, and set the number of particles, we’ll create a new method:

private void CreateStar()
{
    var star = new Dot()
    {
        Shape = new Ellipse() { Height = 2, Width = 2},
        Velocity = new Point(randomizer.Next(-5, 5), randomizer.Next(-5, 5))
    };

    // Center the star
    Canvas.SetLeft(star.Shape, LayoutRoot.ActualWidth / 2 - star.Shape.Width / 2);
    Canvas.SetTop(star.Shape, (LayoutRoot.ActualHeight / 2 - star.Shape.Height / 2) + 20);

    // Prevent stars getting stuck
    if ((int)star.Velocity.X == 0 && (int)star.Velocity.Y == 0)
    {
        star.Velocity = new Point(randomizer.Next(1, 5), randomizer.Next(1,5));
    }

    // Set color
    
    stars.Add(star);
    LayoutRoot.Children.Add(star.Shape);
}

Now we have created a particle, but it’s sitting idle on the screen, as generic and dull as the next one. Let’s give it some personality by adding some color to it by adding the following code under //Add color –line:

var colors = new byte[4];
    randomizer.NextBytes(colors);
    star.Shape.Fill = new SolidColorBrush(
        Color.FromArgb(colors[0], colors[0], colors[0], colors[0]));

We’re using the Random class to get a new color value. If you prefer to have colorful particles, you can change the Color constructor like this:

Color.FromArgb(colors[0], colors[1], colors[2], colors[3]);

At this point we have a lot of particles staying static at one point. What we need is a method to move particles, reset those which have gone off the screen back to the center. Add the following code under the CreateStar method:

void MoveStars(object sender, object e)
{
    if (stars.Count < StarCount)
    {
        CreateStar();
    }

    foreach (var star in stars)
    {
        double left = Canvas.GetLeft(star.Shape) + star.Velocity.X;
        double top = Canvas.GetTop(star.Shape) + star.Velocity.Y;

        Canvas.SetLeft(star.Shape, left);
        Canvas.SetTop(star.Shape, top);

        // Star is off the screen
        if ((int)left < 0 ||
            (int)left > LayoutRoot.ActualWidth ||
            (int)top < 0 ||
            (int)top > LayoutRoot.ActualHeight)
        {
            Canvas.SetLeft(star.Shape, LayoutRoot.ActualWidth / 2 - star.Shape.Width / 2);
            Canvas.SetTop(star.Shape, (LayoutRoot.ActualHeight / 2 - star.Shape.Height / 2) + 20);
        }
    }
    Move.Begin();
}

As the effect of all the stars coming to screen at once is quite ugly, we’re adding them one by one each pass to the screen until we have max number of them visible. After that the method goes through all the particles and sets their new position according to their velocity. In the last part we’re checking if the particle has gone off the screen and center it back if it’s not visible anymore.

Now we need to just activate these methods and we’re set to try how does it look like. Add the following code to constructor, just after InitializeComponent() –line:

Loaded += (sender, args) =>
{
    CreateStar();
    Move.Completed += MoveStars;
    Move.Begin();
};

Now you’re set to try how does it look! Just select the Windows project and run on local machine. Keep building the game on the part 2

Posted in Universal Apps, Windows Phone 8.1 | 8 Comments

Taking high res photos with Windows Phone 8.1

There was previously no access to high res resolutions on the camera, but you had to know which model supports which high resolution. Now with the universal apps, you can actually get the all supported resolutions from the camera easily, including the high res and init your camera to use them. Here’s a quick sample snippets to init your camera, select the highest possible resolution and change your camera to use that.

Assumption is that you have CaptureElement in your XAML called captureElement, and MediaCapture element called mediaCapture as a member variable in your code behind in MainPage.xaml.cs

Select the back camera:

var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(Windows.Devices.Enumeration.DeviceClass.VideoCapture);
var backCameraId = devices.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back).Id;
await mediaCapture.InitializeAsync(new MediaCaptureInitializationSettings
{ VideoDeviceId = backCameraId});

Next query all the supported resolutions, and select the highest possible and set that to the camera.

var resolutions = this.mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo);

if (resolutions.Count >= 1)
{
var hires = resolutions.OrderByDescending(item => ((VideoEncodingProperties)item).Width).First();

await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, hires);
}

Now you’re ready to start video preview and do photo capturing with these last calls

captureElement.Source = mediaCapture;
await mediaCapture.StartPreviewAsync();

Check out my previous post about setting the camera preview correctly, otherwise your image is going to be tilted quite funkily.

Posted in Universal Apps, Windows Phone 8.1 | Tagged , | 3 Comments

Windows Phone 8.1 camera orientation

Update: The code was missing global bool variable to check if we’re using the front camera, added to code
Using the cameras of Windows Phone 8.1 live viewfinder in Universal apps can be a bit of a challenge. The behavior is different with front and main cameras and most likely you end up with upside down image on your preview, if you run the same code which works for Windows 8.1 when using the front camera. The design of the camera driver is based on WP8.1 chassis specs, and camera orientation is dependent on the native landscape orientation of the display.

Issue here is that the rotation of the front camera and display happens in opposite direction, resulting to inverted image. This all can be a bit confusing, so let’s give you a code which runs on WP8.1 correctly. Note that you need to ifdef this code in Windows for the rotations, or your front camera on tablet will be incorrectly rotated.

First we define the capture element to the XAML like this:

<CaptureElement x:Name="captureElement" 
HorizontalAlignment="Center" 
VerticalAlignment="Center" 
Stretch="UniformToFill">
</CaptureElement>

In the following code we check if front camera is available, and take it in use, otherwise fall back to the main camera. After that we set the camera mirroring according to the chosen camera, as it differs with front and main camera as well. Lastly we subscribe to the orientation change event:

bool frontCam;

...

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    mediaCapture = new MediaCapture();
    DeviceInformationCollection devices = 
await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);

    // Use the front camera if found one
    if (devices == null) return;
    DeviceInformation info = devices[0];

    foreach (var devInfo in devices)
    {
        if (devInfo.Name.ToLowerInvariant().Contains("front"))
        {
            info = devInfo;
            frontCam = true;
            continue;
        }
    }

    await mediaCapture.InitializeAsync(
        new MediaCaptureInitializationSettings
        {
            VideoDeviceId = info.Id
        });
            
    CaptureElement.Source = mediaCapture;
    CaptureElement.FlowDirection = frontCam ? 
FlowDirection.RightToLeft : FlowDirection.LeftToRight;
    await mediaCapture.StartPreviewAsync();

    DisplayInformation displayInfo = DisplayInformation.GetForCurrentView();
    displayInfo.OrientationChanged += DisplayInfo_OrientationChanged;

    DisplayInfo_OrientationChanged(displayInfo, null);
}

Now we need to adjust the orientation of the capture element according to the screen orientation (the animation makes your eyes bleed, but there’s no way to disable orientation animations for a control). This code is modified from the MSDN Windows 8.1 advanced camera sample.

private void DisplayInfo_OrientationChanged(DisplayInformation sender, object args)
{
if (mediaCapture != null)
{
mediaCapture.SetPreviewRotation(frontCam
? VideoRotationLookup(sender.CurrentOrientation, true)
: VideoRotationLookup(sender.CurrentOrientation, false));
var rotation = VideoRotationLookup(sender.CurrentOrientation, false);
mediaCapture.SetRecordRotation(rotation);
}
}

For the last piece we need to check the video rotation according to the chosen camera like this:

private VideoRotation VideoRotationLookup(DisplayOrientations displayOrientation, bool counterclockwise)
{
switch (displayOrientation)
{
case DisplayOrientations.Landscape:
return VideoRotation.None;

case DisplayOrientations.Portrait:
return (counterclockwise) ? VideoRotation.Clockwise270Degrees : VideoRotation.Clockwise90Degrees;

case DisplayOrientations.LandscapeFlipped:
return VideoRotation.Clockwise180Degrees;

case DisplayOrientations.PortraitFlipped:
return (counterclockwise) ? VideoRotation.Clockwise90Degrees :
VideoRotation.Clockwise270Degrees;

default:
return VideoRotation.None;
}
}

That’s all it requires, have fun with it!

Posted in Universal Apps, Windows Phone 8.1 | Tagged , , | 15 Comments

Format your date in Universal app according to user preferences

With the new Universal app model, many things have changed, and there’s very little documentation available to find out how you need to address certain things in the new app model. One of those things is formatting your date according to the region settings chosen by the user. CultureInfo is no longer recommended class to be used, and if you tried to dig out yourself the chosen regional format, you might have found it to be quite difficult in cases where user has chosen to use different language (en-US) and different regional settings, for example de or fi.

It’s pretty easy still, only figuring it out where to find that info is not. So here’s the codeblock which formats datetime according to the chosen regional setting:

DateTime date = DateTime.Now;
GeographicRegion userRegion = new GeographicRegion();
var userDateFormat = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("shortdate",new [] {userRegion.Code});
var dateDefault = userDateFormat.Format(date);

We use the GeographicRegion to get the chosen region, and then we create DateTimeFormatter according to that culture, which we use to format the date on the last line. Hope this snippet helps you!

Posted in Universal Apps, Windows Phone, Windows Phone 8.1 | Tagged , , , | 1 Comment

How to call your app

With yesterdays announcements at BUILD, there were some new terms introduced along with the new app models. I thought they were a bit mouthful, so I decided to draw this small chart to help you easily figure out what is what.

Naming

First we have the apps build with the traditional, Silverlight -based classic Windows Phone app model apps. If you you target 8.0 they’re called Windows Phone Silverlight 8.0 apps, and if you target WP 8.1 then they’re Windows Phone Silverlight 8.1 apps.

If you are creating Windows Phone Store apps, depending on your choice of technology, they’re either Windows Phone Store apps using XAML /HTML.

Interestingly we don’t make the difference when we talk about Windows Store apps for Windows, but refer to them generally as Windows Store apps.

Lastly there are the Universal Windows apps, which are build with the shared project tooling targeting both Windows and Windows Phone.

Hope that cleared some of the confusion!

Posted in Universal Apps, Windows Phone, Windows Phone 8.1 | Tagged | Leave a comment

What there is and what there might be

As there is no one good public source for Windows Phone chassis specs, I decided to put together a small table which will list the things all Windows Phones have common and what are the optional things devs need to test for the existence.

WP8 chassis

Display part is quite self explanatory, interesting thing is that the specs go up to 7″ screens, which works out for phablets quite nicely. Screen resolutions are also something that devs need to realize, but fortunately the platform is quite nice about them and you don’t have to design for three different resolutions but it scales them automatically. The sensor part is a bit more complicated, and I’ll give a quick overview of them.

First of all, there are some sensors which are found in each WP no matter who’s the manufacturer, let’s call them base sensors. The base sensors are in the minimum hardware specifications, and can be found even in the low end models.

Base sensors

Assisted Global Navigation Satellite System receiver (A-GNNS) is for quick satellite fix, and helps you to get a faster location data for poor GPS signal or when the signal is not available.This sensor you don’t access yourself from the code but the system will take care of it when you deal with the GPS.

Ambient Light sensor can sense light from range of 0 lux up to 4000 lux or more. For this sensor, you have no access from your code either, so you can’t sense the lighting conditions but this information is delivered to OS itself only.

Proximity sensor will detect if the phone is in your pocket or on your ear, and will turn off the display to save battery. Again this sensor is not accessible from the code. Malfunction of this sensor will lead to situation where you can’t end the phone call as screen stays black. In these cases, it is advised to take the phone to repair center, and ask them to put some silicon around the sensor, that helped me (had this issue with three different WPs).

Vibration is the first sensor of these which you can actually access from your code, using Microsoft.Devices.VibrateController – .NET class or Windows.Phone.Devices.Notification.VibrationDevice – Windows Phone Runtime API. In hardware, vibration is done either by motor, speaker or haptics transducer.

Next up is the Accelerometer, which is three-axis with HW sampling rate up to 100 Hz. The accelerometer detects changes in the physical acceleration of your phone and fires events as X,Y,Z orientations change. This sensor can be accessed with WPRT in Windows.Devices.Sensors.Accelerometer and it delivers from SensorBase<T> class.

Optional sensors

There are a few sensors in WP which may or may not be there, depending on the make and model of your phone. When using these sensors, be sure to check at the beginning that they do exists in your code, before using them.

First and maybe even the most interesting of these all is the NFC, near field communication. I’ll write a separate post about doing NFC with WP, but what is important here is to remember to check if your client is enabled with NFC with the following code snippet:

ProximityDevice device = ProximityDevice.GetDefault()
if (device != null)
{
  // do your stuff
}

Magnetometer, also known as Compass is three-axis with sampling rate of 60 Hz. You can access it from Windows.Devices.Sensors.Compass class, and it also delivers from SensorBase<T> class. Interesting side-note is that if your app has ID_CAP_LOCATION, this will give your app more accurate computation of the declination which is different in different point on the earth and changes with time.

Lastly there is the Gyroscope, which is three-axis with sampling rate from 5 Hz to 250 Hz or more. If your device has a gyroscope, it must also have a magnetometer. You can access it through Windows.Devices.Sensors.Gyrometer and it also delivers from SensorBase<T> class.

That wraps it up for now, and in the next post I’ll talk more about using the NFC sensor.

Posted in Windows Phone, Windows Phone 8 | Tagged , , , , , , | Leave a comment

Windows Phone Development MVP

Yesterday I got an email from MVP Awards with the information that I’ve received the Most Valuable Professional -award from Microsoft for my Windows Phone community activities. With a quick check it seems I’m the first in Finland and in whole Nordics to receive MVP for Windows Phone dev, what an incredible honor! That definately motivates me to try to be even more active on the community!

Posted in Uncategorized | Leave a comment

Windows Phone 8 and the music resume -rules in the marketplace

Seems that this old issue is still causing some scratching of head among the devs, how to implement this properly in Windows Phone. This has changed a bit from WP7, and the rule has been updated (6.5.1. & 6.5.3) to apply only to XAML apps. Now you don’t have to worry about radio anymore, as that’s not in the mix with WP8.0.

Here are the few scenarios where you need to fill this requirement.

First we implement the code for normal apps, which want to play a non-interactive full motion video, or a non-interactive audio segment (e.g. cut-scene or media clip) – in this scenario you don’t need to ask user’s consent for this action.

Here are the steps needed to implement it properly. Open your MainPage.xaml.cs file, and insert these namespaces,  and after that also insert them to your App.xaml.cs as well:

using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Media;

And then add a boolean variable to your App.xaml.cs to mark if resume is needed:

public bool needToResumeMusic = false;

Then you go to the class where you need to play your own media. First add this code as a class level variable:

App thisApp = (App)Application.Current;

Next you open the method where you are going to play your own media, and add this code before it:

FrameworkDispatcher.Update();

if (!MediaPlayer.GameHasControl)
{
    thisApp.needToResumeMusic = true;
    MediaPlayer.Pause();
}

Please note that the Update is critical to be there, or the app will have serious stability issues.

Then you need to put only the resume part to your code, and if you’re using for example MediaElement to play music/video, it has MediaEnded -event which you implement like this:

void Player_MediaEnded(object sender, RoutedEventArgs e)
{
      // Do your cleanup here
      ...
      if (thisApp.needToResumeMusic)
      {
         MediaPlayer.Resume();
      }
}

Now it can handle the switching of background music, but there are two scenarios which you still would want to handle. User might navigate away or kill your app while you’re in the process of playing your music, and you would want to resume the background music on those cases as well. That’s why you edit your App.xaml.cs with these changes:

private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
    if (needToResumeMusic)
    {
       MediaPlayer.Resume();
    }
}
private void Application_Closing(object sender, ClosingEventArgs e)
{
   if (needToResumeMusic)
   {
      MediaPlayer.Resume();
   }
}

Second scenario is that you want to play a background music in your own app, in which you would just add dialog box asking for consent just before the GameHasControl -check and move the Resume to the exit of your app.

So, it’s pretty simple to tackle this nasty little rule without too much coding. Hope it clears things and helps you pass the store certification!

Music Resume Sample – includes code, just put your own media file there and change the name of the file to play to test this.

Posted in Windows Phone, Windows Phone 8 | Tagged , , | Leave a comment

Windows Phone 8 Kernel Architecture

Okay, there has to be a good descriptive picture the WP8 kernel, as it has been a huge advertisement point for the whole unified model for Windows and Windows Phone. Or that’s what I thought, until I tried to find one for almost a day with no success. Maybe I’m not the only one, and I thought I draw my own version based on all the information I could dig up (almost only good source was the Windows Phone Internals Preview 1), mixed with some BUILD videos about Windows 8. As amazing it is, there’s absolutely nothing in MSDN about the kernel structure of WP, so here’s something for those with endless thirst for knowledge:

From top to bottom, the famous shared core consist of two distinct parts, Windows Core System and Mobile Core. The Windows Core system is the part that actually shares code with Windows and is the bare essential of OS kernel. The Mobile Core is the part that shares functionality and code with the Windows kernel, but it’s no longer 1:1 copy, but tuned to mobile needs, with less functions than the big Window’s kernel. So together the Core System with Mobile core are the only areas with codeshare between the two platforms. There are areas where the APIs are the same, but the code behind differs between Windows and Windows Phone.

Above the shared core sits the Windows Phone system, with prebuild apps like people hub and Music & Videos, Windows Phone Shell, Connection management and Platform services etc. The platform services itself consists of four major elements, which provide services to all applications.

Package Manager is the part which handles the lifecycle of an application from installing to uninstalling, and the metadata while it’s installed on the system. That data includes information about pinning and extensibility points the app has registered.

Execution Manager handles the applications and background agents and their execution logic. It is responsible for creating the host process and application state messages, such as app startup/shutdown and deactivation.

Navigation Server is handling all the moving between foreground applications on the phone. It handles it by telling execution manager what application to launch or reactivate and keeps track of the navigation stack.

Resource Manager monitors the system resources of all the active processes and enforces constraints on them, focus on CPU and Memory. If the app is misbehaving, Resource Manager can terminate the app to ensure the stable and quick response of the phone.

That’s the quick version of the shared core for Windows ecosystem, hope you find it useful!

Posted in Windows Phone, Windows Phone 8 | Tagged , | Leave a comment

Windows Phone 8, let’s get the party started!

Finally the SDK is out and we can talk about all the great stuff that the SDK brings to us. There are some big changes with unified programming model, but also some differences, like HTML5/JScript not being there as a project template (you can still embed the browser control..) and XNA not being present but replaced with DirectX.

For a short capture of the coolest things with WP8 I would say these things everyone doing WP dev should check out and learn:

  • Lock screen – This is new thing to WP devs, pretty same to big Windows. Now you can provide background images and notifications to the lock screen of the phone, notification stuff is pulled from your program’s primary tile (text, icon, count) but background images you can define inside your app
  • Navigation – There’s a new WinRT based navigation API to use beside to old trustworthy API from 7.x. Now you can do actual navigation apps, that won’t die if user goes away from the app, but can continue to track on the background. You can also ask directions easily with ms-drive-to and ms-walk-to URI schemes within your app.
  • In App Speech support – Now you can actually integrate speech support to your own app with voice commands, speech recognition, and text-to-speech. Voice commands can be deep links to your app (HelloWorld show image), speech recognition you can use inside your app to command your app/game (vessel turn left) and text-to-speech is a “robot” speaking your text to the user.
  • Wallet – Create added value to your membership app, create coupons for your shopping app… endless possibilities here, NFC is the big thing here on WP8, and you should not pass up the opportunity to add these functionalities if applicable to your app.
  • In-app purchases – If you want to monetize your app, think about micropayments. Buy a new report template within your app, buy new tools/weapons in your game.. options are endless. Micropayments are the next sliced bread in WP marketplace, so don’t miss out on the opportunities they offer, and with this API, you got a solid backend ready with couple of easy steps within your app.
  • Localization of your apps -there’s now build in templates for this. Localization is one of they key elements to make money with your app in different marketplaces. There are really cheap crowdsourcing places to go to get your apps ready for example to China market, the user base is so huge that micropayments will definitely boost your income

Other noteworthy changes are the new map control, Pivot & Panorama ditched from SDK and moved to ROM, Bluetooth APIs, inclusion of Windows.NET.Networking, revamped storage apis, associating your app with certain filetypes and now the store compiles your .NET code in the cloud, ensuring the fastest possible startup for your apps at consumer devices. I’ll be posting more in detailed look for each of these categories later on.

Posted in Windows Phone | Leave a comment

What changes with Windows Phone 8 development

Thought I give a short summary for you who are interested in bringing your WP7.5 app to WP8 for what you should look out for.

In general you shouldn’t recompile your WP7.5 app to WP8, for two reasons. Firstly, WP7.5 apps will work on WP8 as is, without any need to rework the code. Secondly, recompiling apps is only going to get you in trouble, because there are some changes in the way .NET Framework and CLR has been implemented on WP8 compared to WP7.5. There is a totally new kernel on WP8 and for example totally new garbage collector implementation on WP8. Also precision is not the same in all cases with WP7.X and WP8 with number handling.

What you should consider is to bring your app to Windows 8 with the same trouble, as now with the shared kernel and programming model (XAML+C#/C++) you are able to double your presence in the markets. We’ve been able to reuse pretty much 99% of the code in couple of titles we’ve done targeting Win8 and Windows Phone 8 platforms with C++ DX based games.

Windows Phone 8 will also include in-app purchasing , so finally you can bring additional paid content to your apps/games. Micro payments have proved to be a very efficient way to a developer to earn more money, as buying decision bar is much lower with small amounts, and there will be more purchases for items/features than you would expect with right kind of content.

These are just a tip of the iceberg, and when the NDA is lifted, I’ll talk more about other cool features that are hidden in the SDK, that will make WP8 rock!

Posted in Windows Phone, Windows Phone 8 | 2 Comments