Building Games for the Windows Phone 7 Platform

Day 2 of my Windows Phone 7 series. It has been a very busy month for me, but here it goes. In this post you will learn how to develop your own 2D game using XNA and deploy it on Windows Phone 7/Xbox 360/Windows Game. This post will be straight forward tutorial just like other XNA tutorials that you could see.  This tutorial assumes that the readers have a basic C#/.Net understanding. I hope that it will help you to understand the basics of the framework and that it will motivate you to go further in. Just an overview of XNA, XNA framework is a .NET Game development of Microsoft that you use to develop in Xbox 360, Windows and now with Windows Phone 7. XNA Framework lets you focus on your game not on the platform because of its easy-to-use API’s. It is a powerful .NET API to help you handle graphics, sounds, videos, inputs networking and storage. The rest of the information about XNA can be found here. When I was still on my college lower years, I sometimes ask myself how to start developing my first simple game? How to handle objects? How to change map? Thanks to XNA Community and free e-books and blogs, I get to learn how to code my own.

Before we start developing with XNA here are some of the FAQ’s.

  1. What’s the difference between XNA 3.1 and XNA 4.0? Do I have to upgrade to XNA 4.0 for me to develop games for Windows Phone 7?
  • Yes, You have to upgrade from XNA 3.1 to XNA 4.0 in order to create games for Windows Phone 7, but if your target is just for Xbox 360/Windows then XNA 3.1 is fine, but IMO I would update it to 4.0 since later on, you could see how easy it is to deploy my existing game to other platforms with just few lines of code.
  1. I only have DirectX 9.1c? Is it okay?
  • As far as I know, the minimum requirement for debugging  games for WP7 is DirectX 10, but you are still able to develop games using DirectX 9.1c.
  1. I only have Visual Studio 2008, is there a difference between using Visual Studio 2010?
  • There’s of course a difference between using Visual Studio 2010 and Visual Studio 2008, for more information please check this site. Here. If you’re using Visual Studio 2008 and you have XNA 4.0 installed and WP7 SDK then there is no difference when developing in VS2008 or VS2010 as long as the SDK are updated with VS2008.

    Let’s start developing our very first 2D game.

    To start our project, we go to File -> New -> Project and this window will show up. On the left side of our installed templates you can see that XNA Game Studio 4.0 is there, choose it and you will see different kind of project templates that we could use for WP7, Windows and Xbox360. If you’re using XNA Game Studio 3.1 you won’t be able to see Windows Phone Game and Windows Phone Game Library.

    By default, your solution explorer should look like this.

    Properties:  This is generated for you by Visual Studio and it’ basically a general information about your assembly.

    References: This is where your libraries are called. Just like in your Turbo C class, “#include<stdio.h>”.

    Content References: This is your content pipeline, this is where you add your existing files like images,  sounds, etc.

    Game.ico: This is your game icon in Windows when executed.

    Game1.cs: This is your game engine or the main source code for our game.

    GameThumbnail.png: This is your game’s thumbnail image.

    Program.cs: Main entry for your application which initializes the game1.cs.

    I have mentioned about Content Pipeline, what’s Content Pipeline anyway?

    • Content Pipeline’s objective is to manage our game assets (graphics, sounds, 3D models, etc) from the importation up to the execution with less code.

    Now for the supported file formats, here’s the list:

    2D graphics: .bmp, .png, .jpg;

    3D models: .x, .fbx;

    Shaders: .fx;

    Audio: .mp3, .wav, .wma;

    5

    Video: .wmv;

    Font: TrueType;

    Any XML, text or binary files.

    Next, let’s try opening our game1.cs. If you have notice our game1.cs inherits the XNA game class. Your game1.cs will be your game engine, you could probably create your own game class but you would end up similar to the XNA game class. The game class is composed of five methods:

    Initialize:  The objective of this method is to initialize all the class members similar to a Winforms/WPF Application.

    Load Content: The objective of this method is to load all our game assets from the content pipeline to be used in our game.

    Unload Content: This method ensures that all of our assets that we loaded are disposed correctly and that our memory allocation are handled properly.

    Update:  Always called before the Draw method and is used to update our game engine. This method handles our logic (collision, user inputs, level update, etc.)

    Draw: This method is called in an infinite loop (game loop). It is used to draw the game assets that we used in our content pipeline into runtime.

    Our game1.cs by default have two fields initialized:

    GraphicsDeviceManager: This class provides us useful methods, properties, etc. that allows us to know the screen resolution, screen bounds, etc.

    SpriteBatch: This class provides us methods for 2D drawings. This is likely the class that communicates with our Graphics Processor Unit.

    Let’s first try adding our game assets to our solution. Right click on our content pipeline

    I’m going to import a simple texture in order for us to learn the basics of loading game assets and drawing it to our game runtime.

    Now in our game1.cs, let’s initialize a Texture2D class, this is will be the variable to handle the image that we are going to load.

    Texture2D spriteSheet;

    After declaring spriteSheet, we go to Load method (this is where we load the game assets as I’ve mentioned earlier).

    spriteSheet = Content.Load<Texture2D>(@”xna”);

    Content is a default Game class member representing our Content Project. In order for us to link our game assets to our project we need to access it through Content member. Using Content’s method “Load” it would be easy for the developer to easily load our supported file by specifying its type Load<DataType>, then after specifying its type we have to specify the asset location.

    We have successfully linked our game asset to our variable spriteSheet, now let’s try drawing it in our game. We go to draw method.

    protected override void Draw(GameTime gameTime)

    {

    GraphicsDevice.Clear(Color.CornflowerBlue);

    // TODO: Add your drawing code here

    base.Draw(gameTime);

    }

    The first line basically just clears out the entire screen and sets the background to Cornflowerblue color. The last line calls Draw method and should always be the last instruction of our Draw method.

    To draw simple 2D graphics, the only class we need to use is SpriteBatch (which is initialized by default).

    If we try to load our screen in Windows base the screen should look like this.

    If you are familiar with Cartesian plane, at first glance you would probably say you do and it’s easy to understand its definition and apply it on the screen. The problem is that, it is just similar to Cartesian plane but its Y value is not the same as the definition we know. If our Y axis goes up the value of Y will be negative not positive, and if our Y axis is going down then its Y value is positive.

    In our SpriteBatch class, we can start drawing by calling its function SpriteBatch.Draw(); We could overload this method in 7 different types of arguments to be passed.

    spriteBatch.Draw(Texture2D, Rectangle, Rectangle, Color);

    Where Texture2D (the texture to be passed), Rectangle (destination rectangle), Rectangle (source rectangle), Color (Color to be used).

    Considering our game asset that we load earlier, let’s try to put this code in our Draw method.

    spriteBatch.Begin();

    spriteBatch.Draw(spriteSheet, new Rectangle(50, 50, 100, 100), new Rectangle(0,0, 70, 48), Color.White);

    spriteBatch.End();

    As you notice, spriteBatch.Begin is called first and spriteBatch.End the last, this is a must everytime we are going to draw our game assets into our game. The begin method is simply like “GPU, these are the game assets you are going to draw and how you are going to draw them”. The end method tells that the GPU can start drawing the game assets that it must draw and how it should be drawn in the game.

    That’s the basic for drawing 2D game. Now let’s start developing our own ping pong game in Windows Phone 7.

    As I have said earlier, XNA lets you focus on the game not on the platform. So first we have to think what assets do we need in order to create a simple pong game?

    • Two rectangle bars
    • Ball
    • Background
    • Score display
    • Sounds

    In our content pipeline, I’m going to use my defined game assets. You can download the files here. After downloading the files you should find the following files:

    • spriteSheet.png: A sheet that contains two rectangles and a ball.
    • Background.png: An image that we will use as a background for the game.
    • Bounce.wav: A sound file when a ball bounces.
    • Supporters.wav: A sound file when a player scores.

    After adding them to our game assets, next thing we need to do is declare variables that will link the game assets to our variables so that we could manipulate them.

    // our pong entities

    Rectangle blueBar;

    Rectangle redBar;

    Rectangle ball; // since there’s no “circle” class in XNA, we’ll simulate it

    with a bounding rectangle box

    // our pong clone textures

    Texture2D grass;

    Texture2D spriteSheet;

    // our sound effects

    SoundEffect ballBounce;

    SoundEffect playerScored;

    Next, we go to our Initialize method and initialize the destination of our game assets.

    protected override void Initialize()

    {

    // initializing our entities

    blueBar = new Rectangle(

    32, // x coordinate of the upper left corner of our rectangle

    10

    GraphicsDevice.Viewport.Bounds.Height / 2 – 64, // y coordinate of the

    upper left corner

    32, // its width

    128); // and its height

    redBar = new Rectangle(

    GraphicsDevice.Viewport.Bounds.Width – 64, // x coordinate of the

    upper left corner of our rectangle

    GraphicsDevice.Viewport.Bounds.Height / 2 – 64, // y coordinate of the

    upper left corner

    32, // its width

    128); // and its height

    ball = new Rectangle(

    GraphicsDevice.Viewport.Bounds.Width / 2 – 16, // x coordinate of the

    upper left corner of our rectangle

    GraphicsDevice.Viewport.Bounds.Height / 2 – 16, // y coordinate of the

    upper left corner

    32, // its width

    32); // and its height

    base.Initialize();

    }

    Our bars are 32×128 pixels and must be placed to the left and right of the screen and perfectly place on the center of the corner. If we define a Rectangle it consists of four parameters: the x coordinate of the upper left corner, the y coordinate of the upper left corner, the width of the rectangle, and its height.

    Next, the common part where my audience gets shocked after seeing this line of code

    GraphicsDevice.Viewport.Bounds.Height / 2 – 64;

    Basically, this is just a simple formula on how we vertically center our bars. Notice that I used the GraphicsDevice class to determine the Bounds of the height which I mentioned earlier the use of GraphicsDevice. With this class it would be easy for us to determine the screen size.

    Next, let’s go load our game assets just like we did earlier before starting our pong game.

    protected override void LoadContent()

    {

    // Create a new SpriteBatch, which can be used to draw textures.

    spriteBatch = new SpriteBatch(GraphicsDevice);

    // load our textures from the Content Pipeline

    grass = Content.Load<Texture2D>(@”Textures/Grass”);

    spriteSheet = Content.Load<Texture2D>(@”Textures/Objects”);

    11

    // load our sound effects from the Content Pipeline

    ballBounce = Content.Load<SoundEffect>(@”Sounds/Bounce”);

    playerScored = Content.Load<SoundEffect>(@”Sounds/Supporters”);

    }

    Next, we will have to go to Draw method and start drawing these game assets. But before we go to our Draw method, we have one basic problem that we already have encountered in our real life if we have tried painting in our Arts class.

    It’s similarly called as the Painter’s problem. Normally, if you’re going to paint something and you already painted the subject the next problem you would encounter is how you would perfectly paint the background without touching the subject or accidentally painted the subject by the background’s colour. Graphics API is similar the way it draw game assets. Everything that is drawn will recover what’s already drawn if it overlaps. So you

    have to draw graphics according to their distance from the camera.

    Currently, according to handcraft

    “It is not completely true since there’s some hardware magic called the Z-buffer

    which sorts everything out even if you draw everything in a random order. But the Z-buffer has been

    designed for 3D purposes and when dealing with 2D graphics, we’re no more working with Z

    coordinate so we have to sort this ourselves.”

    XNA provides a method in order to sort 2D graphics via the SpriteSortMode argument of the Draw method but it is still cleaner to draw things in the right order (background first then subject).

    Let’s start drawing our background first.

    protected override void Draw(GameTime gameTime)

    {

    GraphicsDevice.Clear(Color.CornflowerBlue); // clear all the screen with a

    blue color

    // draw the grass background

    spriteBatch.Begin();

    spriteBatch.Draw(

    grass, // use the grass texture

    GraphicsDevice.Viewport.Bounds, // stretch the texture to the whole

    screen

    // GraphicsDevice.Viewport.Bounds is Rectangle corresponding to the

    actual viewport (meaning the entire screen no matter the resolution), only available

    as of XNA 4.0 CTP

    Color.White);

    spriteBatch.End();

    Similar to the code that we’ve put earlier it just simply draw the background, but notice that I used GraphicsDvice.Viewport.Bounds in order to stretch the texture to the whole screen. If you notice I used the bounds as my destination rectangle because remember that the whole screen is represented in Rectangle.

    If we try to run and debug this we should be able to display a screen similar to this

    [Picture]

    After drawing the background, let’s try adding the subjects (bars and rectangle). If you are familiar with Sprite Sheet then we are going to use the same technique. Sprite Sheet allows us to draw all our game assets in one file so that we would only load the file once in our Load method.

    Let’s define the three source rectangle for our game assets. Notice I said three source rectangles and you might be asking that our ball is not a rectangle it is a circle shape. The answer is that, the .NET framework does not provide a Circle class yet but you can probably write your own Circle class.

    // source rectangles of our graphics

    Rectangle blueSrcRect = new Rectangle( // blue bar src rectangle

    0, // upper left corner x-coordinate of the blue bar inside the

    spriteSheet

    0, // upper left corner y-coordinate

    32, // width

    128); // height

    Rectangle redSrcRect = new Rectangle( // red bar src rectangle

    32, // upper left corner x-coordinate of the red bar inside the

    spriteSheet

    0,

    13

    32,

    128);

    Rectangle ballSrcRect = new Rectangle( // ball src rectangle

    64, // upper left corner x-coordinate of the ball inside the spriteSheet

    0,

    32,

    32);

    After declaring the source location of our game assets in Sprite Sheet, let’s start drawing them. In our existing draw method, we add this code after drawing our background

    // draw the entities (bars and ball)

    spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend); //

    setup alpha blend to support transparency

    // draw the red bar

    spriteBatch.Draw(

    spriteSheet, // use the sprites texture

    redBar, // the rectangle where to draw the bar on the screen

    redSrcRect, // the source rectangle of the bar inside the sprite sheet

    Color.White);

    // draw the blue bar

    spriteBatch.Draw(

    spriteSheet,

    blueBar,

    blueSrcRect,

    Color.White);

    // draw the ball

    spriteBatch.Draw(

    spriteSheet,

    ball,

    ballSrcRect,

    Color.White);

    spriteBatch.End();

    Press F5 and you should be able to see a screen similar to this

    We’re done drawing our background and positioning our game assets. If you notice how easy it is to load and draw our game using XNA. Just a few lines of code and there you have it, we have how we want our game to look like. Let’s start coding our gameplay.

    The next thing you would probably ask is the common question that a student would ask “How would I move those images? Objects or whatever you call them?” with XNA, it’s also easy to handle inputs just like how we load our game assets. In our update method you would notice that there is a default content which is

    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) // if the

    Back gamepad button is pressed

    this.Exit(); // exit our game

    Now this GamePad class just allows us to determine the current state of the user input.  Since Windows Phone 7 is not using gamepad nor Keyboard state to play our pong game, we have to import a class in our .NET which is touch location.

I shall return!

After becoming a guest speaker to many different schools here in Metro Manila about Microsoft Technology, it’s time to go to my own school and talk! Will be at FEU – East Asia College, Main Bldg. AVR tomorrow from 9 am to 5 pm! Straight session with no break! Get to learn how to develop and use the SDK/API of Microsoft Multipoint, Silverlight, XNA and Windows Phone 7!

I’ll get back with my blog on Day 2 and Day 3 of 7 days of Windows Phone 7 post. Been busy doing talks and seminars with Windows Phone 7.

Don’t forget to visit these useful links in order for you to get started developing your own applications with Windows Phone 7.

 

http://channel9.msdn.com/Blogs/coolstuff/Windows-Phone-7-development-for-absolute-beginners

http://create.msdn.com/en-US/home/news/new_education_nov_2010

http://channel9.msdn.com/Series/Windows-Phone-7-Development-for-Absolute-Beginners/Writing-your-First-Windows-Phone-7-Application

http://gizmodo.com/5687626/windows-phone-7-essential-apps-reviewed

http://channel9.msdn.com/Blogs/LauraFoy/PDC-10-Student-Apps-for-Windows-Phone-7