Building a simple game using XAML/C#: Part 1 – XAML UI

I thought it would be fun to make a game for the Windows developer preview. So, as an exercise in simplicity, I decided to go for a game that loosely resembles “Simon”, the memory game where you try and remember a pattern that is additively generated.

Where to begin…

Have you ever had project catharsis from the scope of a project being daunting? I have. Whenever I do, I just try and start with a simple piece that I know I can do and then I begin working on the details. This is actually the first game that I have programmed in a very long time so it was easiest for me to really break things down before I began and then I could know where to start. I took a scenario-focused approach: how does the game work and how users will interact with it.

First, how will my version of the game Simon work?

  • The game starts and a pattern is shown
  • The user tries to repeat the pattern and
    • Either the user successfully enters the pattern and the pattern gets longer, or…
    • The user fails at entering the pattern and the game ends

This is my favorite part of this project. It’s such an easy game! All I have to do is show buttons, turn them on and off, then test that a user does it in the same way as shown.
Next, how would this game “fit” into an app?

  • The user needs to see a representation of the pattern / pieces and interact with them
  • A user hast to start, restart, and interact with the game as a whole
  • The game needs to iteratively show a pattern to the user with chimes for the piece changes
  • While the game runs, it needs to either keep advancing levels or set the user up into a “game over” state

Now, I know that I need:

  • UI for showing the game state (e.g. animating the pattern and stuff)
  • Animations and sounds for gameplay – which implies a timer / animation system
  • A game state which includes
    • Whether the game is over or the level is complete
    • Whether the level needs to advance

I have what I need, let’s design!

With my back of a napkin scenarios and concept in hand, I took a pass at creating a loose application design and started thinking about patterns. The following is what I came up with for a generic representation of the game:

In my simple game, the main application has a game which has a level. Components are shared between the various systems so that the application can trigger and update game states via the UI. You can begin to see how the game will work and app will run based on the design: the application creates a game which then creates a level with a queue representing the “solution”. The game state will tell if the game is over or whether a new level should be added. To actually play the game, moves are going to be passed to “solve” and tested against the solution queue. If the played moves don’t match the queued moves then the game state is updated to fail. If the solution queue is empty, then it’s time to level up.

There’s a good bit of potential here for design patterns like ensuring encapsulation of features. For example, the game should work like a facade hiding the details of the level and actual gameplay, the level could employ a builder or a factory pattern, a command pattern should be used for application UI, and so on… In order to keep it simple, the game will not explicitly employ patterns at this design phase and instead we’ll save that as a refactoring exercise for the non-prototype version!

So, let’s get it started!
What to do, what to do. There are so many ways to start but before I began, I just wanted to get something together that I could play with. I created a blank project in Visual Studio 11:
File->New Project->Metro Style C# Application

I named it, and then I had a blank project ready to go. I started in MainPage.xaml and updated it so that I would have some nice placeholders for debugging. I replaced the root layout with:

 <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
 <StackPanel Orientation="Vertical">
 <StackPanel Orientation="Horizontal">
 <TextBlock FontSize="30" Margin="10" x:Name="statusBox">Game Instructions</TextBlock>
 </StackPanel>
 <TextBlock FontSize="30" Margin="10" x:Name="levelBox">Level: 1</TextBlock>
 <TextBlock FontSize="30" Margin="10" x:Name="scoreBox">Score: 0</TextBlock>
 <TextBlock x:Name="status2Box">...</TextBlock>
 </StackPanel>
 <Canvas Name="gameCanvas"></span>

 </Canvas>
 </Grid>

Now that I had a nice simple application with a fancy text box that I could set text in and a canvas for drawing to, I updated the text. If you’re following along, you can open the code behind file (MainPage.xaml.cs) by clicking the triangle next to MainPage.xaml in Solution Explorer and double-clicking the code behind file. In the code behind file, there is the MainPage constructor which is an easy entry point into the app. To ensure that everything is working I tried updating the text box to indicate that the application state is initialized.

public MainPage()
 {
   InitializeComponent();
   statusBox.Text = "Click "New Game" to begin...";

ow building and running will show the app in the following state.

Note that I’m running in the simulator. You can turn this on by selecting the options next to the “Start Debugging” button in VS11. Not that exciting? Well, on the bright side, we have updated the UI text and it works! This will enable us to debug should things get hairy moving forward. Also, I’m always suspicious about things not working out the gate causing problems down the line. Getting a nice baseline before diving deep into the code is usually a good idea.

Pretty pictures
Project works, runs full screen, and loosely has some Metro magic going on. At this point I figured I would start getting the UI together. The game Simon has four squares that will represent a pattern. The pattern is generated and the user tries to replicate it. Easy enough, time to mockup! As soon as someone says, four squares, I think Windows logo, so I chose the Windows colors and came up with a simple game mockup that I used for designing.

What’s that you said? Why yes, yes that mockup was created in MSPaint. It’s awesome, yes? Anyways, I know that I need to create four squares for the UI and that I want to use the Windows colors. Fortunately, squares are easy in XAML. I’m not a designer and I also like to place UI elements programmatically so, I jumped back into the code behind for the MainPage initializer and then hacked away some simple UI.

// UI from the mainpage.xaml
Rectangle redRect, greenRect, blueRect, yellowRect, cheatRect;
GradientBrush redBrush, greenBrush, blueBrush, yellowBrush;
public void SetupSquare(Rectangle r, double rectWidth, double rectHeight, GradientBrush br, double offset1, double offset2, double rotation, Color c)
{
  // create the gradients
  GradientStop grPri = new GradientStop();
  grPri.Color = c;
  grPri.Offset = offset1;
  GradientStop grrBlk = new GradientStop();
  grrBlk.Color = Colors.Black;
  grrBlk.Offset = offset2;

  br.GradientStops.Add(grPri);
  br.GradientStops.Add(grrBlk)
  RotateTransform gRot = new RotateTransform();
  gRot.Angle = rotation;
  br.Transform = gRot;</span></div>
  r.Fill = br;
  r.Height = rectHeight;
  r.Width = rectWidth;
}
public void SetupSquares()
 {
  //  -------------
  // | R    |  G   | 
  // |______|______|     
  // | B    |  Y   |
  // |______|______|
  //           
  // All linear gradients are calculated with outer gradient pointing inward</div>
  double height = Window.Current.Bounds.Bottom;
  double width = Window.Current.Bounds.Right;
  double rectWidth = width / 3;  // thirds of the screen for rect width
  double rectHeight = height / 3; // thirds of the screen for height
  double rectSpacing = 15;
  double wMid = rectWidth / 2;    // midpoints for width/height for rect placement
  double hMid = rectHeight / 2;</div>
  centerX = ((wMid * 2) + rectSpacing) / 2; // between the rectangles
  centerY = ((hMid * 2) + rectSpacing) / 2;
  redRect = new Rectangle();
  redBrush = new LinearGradientBrush();</div>
  SetupSquare(redRect, rectWidth, rectHeight, redBrush, 0.0, 1.5, 0.0, Colors.Red);</div>
  Canvas.SetTop(redRect, hMid);
  Canvas.SetLeft(redRect, wMid);
  gameCanvas.Children.Add(redRect);
  greenRect = new Rectangle();
  greenBrush = new LinearGradientBrush();
  SetupSquare(greenRect, rectWidth, rectHeight, greenBrush, 0.0, 1.5, 90.0, Colors.Green);
  Canvas.SetTop(greenRect, hMid);
  Canvas.SetLeft(greenRect, wMid + rectWidth + rectSpacing);
  gameCanvas.Children.Add(greenRect);
  blueRect = new Rectangle();
  blueBrush = new LinearGradientBrush();
  SetupSquare(blueRect, rectWidth, rectHeight, blueBrush, 1.0, -.5, -90.0, Colors.Blue);
  blueRect.Fill = blueBrush;
  blueRect.Height = rectHeight;
  blueRect.Width = rectWidth;
  Canvas.SetTop(blueRect, hMid + rectHeight + rectSpacing);
  Canvas.SetLeft(blueRect, wMid);
  gameCanvas.Children.Add(blueRect);
  yellowRect = new Rectangle();
  yellowBrush = new LinearGradientBrush();
  SetupSquare(yellowRect, rectWidth, rectHeight, yellowBrush, 1.0, -0.5, 0.0, Colors.Orange);
  Canvas.SetTop(yellowRect, hMid + rectHeight + rectSpacing);
  Canvas.SetLeft(yellowRect, wMid + rectWidth + rectSpacing);
  gameCanvas.Children.Add(yellowRect);
 }

So this is a little meatier section of code. I am using the center of the screen as a point of reference that I draw squares around. The squares are colored using the various brushes that were allocated at the beginning. A utility function is used to simplify the square color and size allocation and the squares are saved. Building and running the project at this point should look like the following mockup:

This is probably a good place to stop for part 1. In a follow up post, I will address user input and multimedia.
You can download the skeleton project in this state here.