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

About Jani Nevalainen

Windows developer who's been working on Microsoft Platforms since 1996. Windows Phone dev MVP 2013, Windows Development Platform MVP 2014. Currently working as Technical Evangelist for Microsoft Finland Developer Experience team.
This entry was posted in Universal Apps, Windows Phone 8.1 and tagged . Bookmark the permalink.

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

  1. Pingback: How to make a Windows Store game with C# and XAML, part 1 | .NET Junkyard

  2. Dan says:

    Hi, thanks for posting this tutorial! I worked through part 1 and 2 and I’m stuck with an interesting compiler error. It says ‘Partial declarations of ‘…’ must not specify different base classes’. I guess this is because there are two pages using the same code-behind. Is there a way around this? Should I just go and use the VisualState manager?

    • Hi Dan,

      This should not be an issue. First verify that the GamePage.xaml has x:Class=”MySpaceInvanders.GamePage” set on top of the file, and then that the GamePage.xaml.cs has “namespace MySpaceInvanders” what it is using and the class is defined as: public sealed partial class GamePage : Page

      Most likely it’s missing the partial text.

  3. Pingback: How to make a Windows Store game with C# and XAML, part 2 | POKORNY

  4. Pingback: How to make a Windows Store game with C# and XAML, part 2 | Windows Admins

  5. Pingback: Crewits | DMV Web Designers | Washington DC, Maryland and Virginia Web Design Agency | Mobile Websites Content Management Systems | How to make a Windows Store game with C# and XAML, part 2 - Crewits | DMV Web Designers | Washington DC, Maryland and Virgi

  6. Pingback: How to make a Windows Store game with C# and XAML, part 2 | SDK News

  7. Pingback: How to make a Windows Store game with C# and XAML, part 2 | Nokipedia

Leave a Reply

Your email address will not be published. Required fields are marked *