Monthly Archives: February 2015

How to Draw a Diagonal Line Using Only XAML (and no path data)

I’ve been playing around with an app to maintain a score. The first thing that I wanted to do was to split the screen, but I wanted a diagonal split; similar to this:

phonescreen

There are a number of ways that this can be achieved; however, this is a method using only XAML. The same method will (I believe) work on Windows 8, WPF and Windows Phone.

First, split the screen into three rows or columns (which depends on how you want the orientation):

        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

This needs to be an odd number of rows / columns if you want the line to be central; additionally, an increased number of rows or columns will result in a smaller incline. Next, draw a transparent rectangle across the middle grid square:

        <Rectangle Name="Placeholder" Grid.Row="1" 
                   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                   Opacity="0"/>

Finally, simply draw a line, binding the X2, Y2 values to the height and width of your rectangle:

        <Line Grid.Row="1" 
              X1="0" X2="{Binding ActualWidth, ElementName=Placeholder}"
              Y1="0" Y2="{Binding ActualHeight, ElementName=Placeholder}"
              StrokeThickness="2" Stroke="Blue"/>

Conclusion

I’m not saying the is the best, most efficient, or only way of doing this. However, it does mean that I can do it on both Windows Phone and Windows Store (and in WPF if I were so inclined) using a single shared project.

Adding a tile to Windows Phone (Annoying and unhelpful errors – Part 2)

Following on from this post, I encountered the following error:

Value does not fall within the expected range.

Here’s the culpable code again:

SecondaryTile tileData = new SecondaryTile()
{
    TileId = title,
    DisplayName = title,
    Arguments = arguments
};
tileData.VisualElements.Square150x150Logo = new Uri("ms-appx:///assets/TileIcon150x150.png");
tileData.VisualElements.ShowNameOnSquare150x150Logo = true;

And, as is typical with these things, it worked yesterday, when I wrote the above post. So, why now, when I run it, does it point to the instantiation of `SecondaryTile` above and cry foul?

This time, it was caused by the ID containing an invalid character (a space). Something similar to the following will fix it:

SecondaryTile tileData = new SecondaryTile()
{
    TileId = title.Replace(" ", ""),
    DisplayName = title,
    Arguments = arguments
};
tileData.VisualElements.Square150x150Logo = new Uri("ms-appx:///assets/TileIcon150x150.png");
tileData.VisualElements.ShowNameOnSquare150x150Logo = true;

Running an Android App for the first time

Introduction

This is pretty much my first try on Android. I’ve downloaded tools in the past… and even faced one or two of the problems below, but I’ve never really stuck with it and actually run anything. The reason it reads like I don’t know what I’m doing and just flailing around in the dark is because I don’t and I am.

Software

In the past, the Android system has seemed to me, as a Visual Studio Developer, a little scattered. This is definitely still the case, but now less so. Android Studio seems to be the first step into a “download and run” system… but that is still a way off.

Steps

The first thing to do is to download Android Studio. Create a new project and build. You may get none of the following issues, but if you do, then this is how I got around them.

Androidpost1

This appears to be answered by this question. The problem was definitely the same one; when I compiled, I get this error:

C:\Users\Paul\AppData\Local\Android\sdk\tools\emulator.exe -avd MonoForAndroid_API_15 -netspeed full -netdelay none
emulator: ERROR: This AVD’s configuration is missing a kernel file!!

The suggested solution is to install the “ARM EABI v7a System Image”.

androidpost2

I enabled it, however, this did not fix the issue for me.

I then tried running Android Virtual Device Manager:

androidpost3

After creating a new AVD like the Nexus One above, ironically, Android Studio advises you to use x86. So I did… and got this error:

androidpost4

But it’s already installed:

andoidpost5

Weirdly, “Installed” is a misnomer; it doesn’t mean “installed”, it means… err… “not installed”. The way to properly install it is to go to the “extras” directory in explorer and run the installer from there:

androidpost6

I then got this error:

androidpost7

Okay – so this error is caused because you apparently can’t run Hyper-V and the HAXM emulator at the same time. I didn’t want to disable Hyper-V and, having tried several work-arounds, came to the conclusion that whatever the speed implications of not using the HAXM emulator, it was not as bad as having to reboot my machine to switch dev environments. So, I moved to ARM EABI-v7A:

androidpost8

As promised – this is slow! But it works:

androidpost9

Console Games – Catch – Part 2 (Introducing a game timer)

Based on the previous post on this, our next task is to introduce our falling objects.

This is my second go at this post, because I originally wrote it on the basis that we would introduce an actual timer into the game. On reflection, I decided against this for two reasons:
1. Timers are a difficult concept (this is aimed at teaching children to program).
2. We’re already using a rapidly iterating infinite loop, so why not use that.

Since we’re not using a timer, we’ll need to replicate a small amount of the timer functionality; Main currently looks like this:

        static void Main(string[] args)
        {
            Console.CursorVisible = false;
            DrawScreen();
            while (true)
            {
                if (AcceptInput())
                {
                    DrawScreen();
                }
            }
        }

Let’s add a timer variable into the mix:

        static void Main(string[] args)
        {
            Console.CursorVisible = false;
            DrawScreen();
            while (true)
            {
                bool autoUpdate = DateTime.Now >= nextUpdate;
                if (AcceptInput() || autoUpdate)
                {
                    DrawScreen();

                    if (autoUpdate)
                    {
                        AddStar();

                        nextUpdate = DateTime.Now.AddMilliseconds(500);
                    }                    
                }
            }
        }

That is, effectively, our timer. The AddStar method can simply add a new point at random:

        private static void AddStar()
        {
            Random rnd = new Random();
            _points.Add(new Position() { left = rnd.Next(Console.WindowWidth), top = 0 });
        }

Admittedly there’s not too much “falling” at the minute, but that can be easily addressed.

Falling Stars

So, to make the stars fall, we just need a MoveStars method; like this:

        private static void MoveStars()
        {
            for (int i = 0; i <= _points.Count() - 1; i++)
            {
                _points[i] = new Position() { left = _points[i].left, top = _points[i].top + 1 };
            }
        }

And call it from main just below AddStar():

. . .
if (autoUpdate)
{
    AddStar();
    MoveStars();

    nextUpdate = DateTime.Now.AddMilliseconds(500);
}                    
. . .

And then…

That’s it; Not exactly a ‘game’ yet – but still it looks the part. In the next and final post in this series I’ll add collision detection and keep score. I’ve uploaded this to GitHub in the same way as I did with the Snake game. Find it here.

consolecatch

Console Games – Catch – Part 1

I’ve written a series of posts based on teaching programming to children (specifically my 9 year old children). Currently, we’ve managed to produce a snake game, but we’re also working on a “Catch” game. This is a game whereby things drop from the top of the game screen, and the player must “Catch” them.

Before starting, it’s worth refering back to my first post for the basis of the game.

The initial set-up is the same; the difference for this game will mainly be that the player can only either move left, or right:

private static bool AcceptInput()
{
    if (!Console.KeyAvailable)
        return false;

    ConsoleKeyInfo key = Console.ReadKey();

    switch (key.Key)
    {
        case ConsoleKey.LeftArrow:
            _left--;
            break;
        case ConsoleKey.RightArrow:
            _left++;
            break;
    }

    return true;
}

Additionally, I’ve used a more bucket-like drawing for this game:

private static void DrawScreen()
{
    Console.Clear();
    Console.SetCursorPosition(_left, _top);
    Console.Write(@"\_/");
}

The main function and variables look like this still (the only change being the default for top, which should resolve to the height of the screen – 0, 0 being the top left):

private static int _left = 0;
private static int _top = Console.WindowHeight - 1;

static void Main(string[] args)
{
    Console.CursorVisible = false;
    DrawScreen();
    while (true)
    {
    if (AcceptInput())
    {
        DrawScreen();
    }
 }
 

So, now we have a basis, the “bucket” moves along the bottom of the screen. The next task is to introduce the “falling things”.