Note: This tutorial is still a WIP, but I decided to release it just in case anyone needs it. Enjoy!

In this tutorial we are going through the process of creating a simple game from A to Z using Visual Studio 2010 and the Windows Phone 7.1 SDK – Targeting Windows Phone 7.5.

This game was created during a presentation and took about 45 minutes, and patched as the session went on by feedback from the audience. I just documented the process and shared it on this blog.

First of all, if you haven’t done so yet – you will need to download the Windows Phone SDK.

1. Designing the game

The first thing you should do when creating a game is to come up with an idea, story and how you should go through that story. It’s important to be able to explain the game in one sentence – if you can’t, the players/gamers/consumers will have trouble understanding the game. If you can, it will be much easier to market and sell the game!

This game will be quite simple: I want a player to move around on a field and avoid the enemies as long as possible. If hit, it’s game over and you have to restart. The longer you stay alive, the higher will the score be.

The settingYou are inside and lost in a hostile ghost house.

One-Sentence Marketing Description”Run around on the playfield without getting caught by evil ghosts and survive as long as possible.”

2. Creating the graphics

Most games require some graphics. In this game I want to have a playfield that represents the floor in a ghost house, a ghost, a player, some text that display high scores and some dot’s that show where I just walked (path).

Note: The textures and the source for the game can be downloaded here:

(added shadow as the image is white, just so you can see it’s a round thing)

Texture: Main menu screen

3. Game logic

Next we should think how we should play the game, what’s the logic, how is the enemies moving, how should the player move and so on.

Player movmentTap position

The player should move towards a point on the screen. The point is set each time the player taps on the screen. This enables the player to both move by tapping on spots, or hold the finger on the screen to move.

Enemy movment

All the enemies active in the game should move towards the players location. If the player moves, the target to where the enemies are moving should be updated. This will make the enemies follow the player.

FlowEvery second:- Add new enemy to the game- Increase the score with the number of active enemies

If the player is hit by an enemy- Initiate Game Over process- Set high score if better than previous- Reset and restart the game

I don’t want the player to be able to get a resting-pause when game over (thus, not going back to the main menu or “tap to restart” or anything), but instead just let the player continue from where he died, just reset the score and remove “living” ghosts. I also want to motivate the player by showing him/her that he got a new record, or that “Almost there, just X points away from high score, you can do it!!”

PlayerThe player will have a class that contains a target-positions. In the update loop, the player will move towards this target. Target is set by tapping on the screen.

EnemyThe enemy is the same as the player, but the target will be set to the players location instead of a tap on the screen.

Enemy HandlerThere will be many enemies, so we create a List that will contain all the enemies and place it in a Enemy Handler. The handler will loop through each enemy, update and draw then, and also check for collisions with the player.

Offline and Online High scoreThere will be both an offline local high score and a online high score. The local high score is stored to the App’s Isolated Storage. The online high score is stored to a free service that hosts online high scores for both free and commercial games; Mogade. You can read more about Modage here, and sign up for a free account.

The highscores will show when you start the game and when it’s game over. After playing a few seconds, the high score will not be visible.

Walking stepsA path of steps will follow the player, showing the walked path. Each step should slowly fade out after a while. This is done by adding steps to a list with the players position, and in the update, fade them out and remove them from the list.

The game screenThis is how the game will look in the end:

Game icons for the phone app-menusThe games need a logo and app tile image. They will have alpha as background, making the tile for the app use the same background color as the phones theme. The red below is the color of the Theme.

Little icon:

Large icon:

4. Implementing the game

The games classes we will implement

Be sure do download the source for the applications so you can follow the implementations. Or you can follow the steps below and create the game as we go, but not all details will be covered.

Next, we need to create a new project. Make sure you select XNA Game Studio 4.0 and Windows Phone Game (4.0)

Now you should have a empty game project. Don’t add anything yet, I will explain some logic first. We will add the Game1 logic last, so just read until we start adding the Player class.

Main Menu State

When starting the app, the player should see the main menu. All it will do is to wait for some input and start the game. When the player taps the screen, the game should ask for a name and start the game.

In this case the scenes will be very simple. It’s either in-game or main menu. So to handle the scene state we simply use a boolean variable. We also create a boolean variable to check if the player has typed in his/her name yet.

bool inMainMenu = true;
bool nameTyped = false;

In the Draw() function of the game we check if these indicate if we should show the game or draw the main menu, and in Update() we use these to update the game accordingly.

We check for a touch on the screen. If we touch, we set the first boolean to false making the game only wait for the player to have completely set the name. We do this by using the built in function Guide.BeginShowKeybaordInput(..). This will call the function GetText when the player clicks OK/Cancel.

This function gets the written name and stores it both in memory, and in the IsolatedStorage for later use. Once the name is set, we set the final boolean that the name is typed. The next time we visit update and draw, it will execute the code that represent “in-game” – you start playing the game.

In-Game

This is where all the fun is happening. Let’s just take a look at the logic from section 3.

Every second:- Add new enemy to the game- Increase the score with the number of active enemies

The Update() function will now bypass the main menu and instead start updating the game logic. It will increase the total score each second by using a scoreTimer. If the scoreTimer is above 1000 (ms), it should be set to 0 (restarting the timer) and also increase the score and add a new ghost (logic soon to be implemented).

Let’s move out from the main Update() for a while and instead create the Player Game Component class, Enemy Game Component, the Enemy Handler and the rest of the classes we want to have in the game.

In other words, it’s time to start writing some code. For each of the classes below, add a new class to your game. I created a folder named GameClasses (just to show the audience that it’s possible) and added the classes into it. Feel free to make a better architecture once you are comfortable with the logic and the implementation, refactor and revisit the code where needed.

So, go ahead an add a new folder named GameClasses to your project, and then we will add the classes one-by-one as we follow the tutorial. in the end, the project might look something similar to below.

PlayerThe player class is a small and simple class. Add a new class to your project by rightclicking the GameClasses foler and select Add new item, make sure it’s a GameComponent and name it Player.

An empty Game Component class named Player is generated and added to your project. Now, go to the class and change the inheritance from being GameComponent to DrawableGameComponent. This should be done for each class except the FotStep (more on this later) as it will be a GameComponent since the player-class will draw them directly.

So change this:

to this:

The code can be seen below, but let me first explain how the Player class works.

The player class contains the current score for the player, the previous score if any, a position and a target. It also contains a texture that represents the player, a footstep texture and a footstep list.

The constructor just sets the target to 0,0 and the position to 0,0. The player will then start in the upper corner of the screen.

LoadContent will load both the player texture and the footStepTexture.

We have a foot step timer that will add a new footstep to the footstep list once it hit the timer. Each footstep will be added at the center of the player. Also, for each Update() we remove each footstep that is inactive.

The key part of Update() is that the position of the player must move towards the target position. We simply do this by checking the position of the player and the target, and it they don’t match with an offset of 5 pixels, we should move the player. This can be done in a smarter way but hey, I only had 45 minutes to create what the audience wanted

The Draw() will take a spriteBatch as an input (so I don’t have to create a new one for the player and each enemy, and also use the same spriteBatch only once for each frame), and render all the footsteps – using the alpha channel as the fadeout for a footstep, and also draw the player.

If contains a texture that represents the enemy, a position and a target.

The constructor generates a initial position to the player somewhere outside the play area (so he won’t spawn on the player if unlucky). Using random numbers, we place the enemies between the coordinates –1000,-1000 and 1000,1000. If the player is within 0,0 and 800,480 (the playfield), we place the enemy outside to –32, –32.

In other words, if the player is spawned in the green area below, proceed. If it’s in the red area, put the enemy at –32,-32. This will make a more flow of enemies come from the top-left corner, implementing possibilities for strategies when the player is playing the game

The Update() will only move the player to the Target-position and Draw() simply draws the ghost-texture at it’s position.

Enemy HandlerThe enemy handler will handle all the enemies that are active in the game.

It contains a list over the active enemies, if it’s game over or not and a function for Adding new enemies to the list, Clearing the list and checking how many active enemies we have.

The AddEnemy() function adds a new enemy to the list. The Enemy’s constructor randomly places the enemy on the screen, making it easy for us to just add a new enemy to the list, and it will magically get a correct position, start getting updated and drawn.

The Clear() function will remove all enemies in the list, and also set gameOver to false as the Clear() function is called when it’s game over.

The Update()-loop will check if one enemy hits the player. This is done by creating a rectangle around each enemy, and around the player and then checking if any of the enemy-rectangles intersects with the players rectangle. If they do, it’s game over.

The Draw()-loop will simply just iterate through all enemies and draw them.

It contains a position, the alpha channel and if it’s active or not. The alpha value starts at 255 and is slowly reduced to 0. If it hit’s 0, it’s isActive flag is set to false and will be removed the next time the player.Update() function is called.

The Update()-function handles the alpha calculations.

The FotStep does not have a Draw()-function. This is because I didn’t want to load a texture for each foot step. Instead, the texture is loaded at the players class, and just rendered multiple times during the players Draw()-loop.

MogadeHelperThe MogadeHelper-class is a class that is used to simplify the implementation of Mogade for online highscore.

It contains an Enum that is used to select what highscore-list will be used by Mogade. You can have more than one, but in this game, we simply just use one: Main.

It contains a gameKey and a secret key that is received when you add a new game on your account at the Mogade website. It also creates an instance of the MogadeClient and contains a list of our ScoardboardEntry. Each leaderboard got a unique key, so when creating a new game at Mogade, make sure to add a new leaderboard to the game, name it (follow the enum), in this case Main, and copy-paste the generated Leaderboard key.

Making it all work together, revisiting the main-game classLet’s go back to the main-class of the game and look at the logic.

The game starts by Initialize() – the enemy handler and the player is initialized, three new enemies are added(so the game starts with 3 active enemies) and Loads the Loaderboards.

The Update()-loop constantly checks it the player is pressing the backbutton – if so, return to the main menu if in-game, or exit if you are in the main-menu.

It also keeps track of the highscore timer, reducing it every Update(). If it’s above 0, show the highscore, else, hide it.

Then it checks for input, if yes, update the players position.

It also checks if it’s game over by checking the enemy handlers game over property. If it’s game over, save the score, set the highscore timer to 6000 (the high scores will then be visible for 6 seconds). It then clears the enemy list in the enemy hanlder (and setting the game over variable to false), adds 3 new starter enemies and updates the local highscore and saves it to the disc if it’s a new high score… aaand resets the players score to 0.

Mogade got an async function SaveScore. It tries to save the score and calls the ScoreResponseHandler when done.

Hi, very nice tutorial you have im glad I´ve found out your site.
however this tutorial for beginners could be better if you add the mogade instrauctions.

I´m having a problem running your solution. the grafics in emulator are all fuzzy and I can only see some distorted lines. probably something with graphic card or some confifuration. Do you know how to fix this ?
thanks and keep this good tutorials rollin :)

It’s the best time to make a few plans for the future and it’s time to be
happy. I have read this put up and if I could I
want to counsel you some attention-grabbing issues or
advice. Maybe you can write subsequent articles regarding this article.