David Rousset - HTML5 & Gaming Technical Evangelist

HTML5 & Gaming Technical Evangelist

Windows Phone 7 Platformer Starter Kit for XNA Studio 4.0

Windows Phone 7 Platformer Starter Kit for XNA Studio 4.0

Rate This
  • Comments 6

As you maybe already know, you can easily develop games on the Windows Phone 7 Series mobiles thanks to the XNA framework. During a single afternoon, I’ve then managed to update the little platform game provided with the “Platformer Starter Kit” shipped with XNA Studio 3.1. I’ve updated it to support XNA 4.0 and the different features available on a Windows Phone 7 like the accelerometer and the touch screen. You’ll find below some brief explanations on the modifications I’ve done to the code and resources. You’ll finally find the source code to download at the end of this article. Loading and running the code will then display something like that in your emulator:

portagexna4

Pour les lecteurs Français, vous pouvez retrouver une version française ici.

First of all, what is XNA in a few words ?

XNA is framework developed by Microsoft to help you building video games in an easy manner. It’s a managed wrapper on top of DirectX. It’s also a multiplatform framework. XNA Studio 3.1 was targeting for instance PC, Xbox 360 and the Zune (HD) device. XNA Studio 4.0 is targeting PC, Xbox 360 and Windows Phone 7 Series devices. The main advantage is that you’ll be able to reuse around 90% of the same code on the 3 platforms. The remaining 10% will be linked to each platform’s specifics: native resolution, type of devices available, sensors available or not, gameplay optimization, etc.

Moreover with XNA, you can build 2D and 3D games in the same easy way. In conclusion, you’ll be able to concentrate your development effort once and you’ll targeting a huge amount of devices capable of running your games but above all… having a huge amount of customers that will potentially buy your games ! ;-)

First time I’ve heard about XNA was during an internal Microsoft conference in the US few years ago. During one session on XNA, the development team was pointing us to the fact that few developers had the set of skills needed to build games on top of DirectX. For me, there are 2 obvious main reasons to that: DirectX is a COM model only accessible through C++ and there are a lot of concepts to master before starting seeing the first pixels moving on the screen. The idea was then to simplify the concepts through a higher level framework to provide young students and passionate people a first mean to discover how to build games without handling all the plumbing. Once this step done, they will be potentially detected by video games editors that will train them on DirectX for more complex games. The XNA framework is then providing solid bases to build a video game.

Note : XNA Studio 3.1 as well as XNA Studio 4.0 are free and work with the free versions of Visual C# Express. All resources linked to XNA can be downloaded from here.

Step 1: retrieve the game’s source code from XNA Studio 3.1 – Visual C# 2008

In this first step, you simply need to have access to the source code of the game by creating the “Platformer Starter Kit (3.1)” project with Visual C# 2008 Express or Visual Studio 2008 like shown in this screenshot:

wp7platformer001

Once done, we will then have in the target directory all the needed source code and resources (sprites, levels, songs, sounds, etc.) to work on.

Let’s use the Zune project as a base. Indeed, this version is displaying the game’s levels using the height rather than the Xbox 360/PC versions that display the blocks in a widely manner.

Ok, this first step was pretty easy! :-)

Step 2: update the code and the solution for XNA Studio 4.0 and Windows Phone

There is no migration wizard available to update a XNA Studio 3.1/VS 2008 solution to XNA Studio 4.0/VS 2010. However, hopefully, this is not a very complicated task to achieve. It’s mainly a brutal copy/paste operation.

Let’s start by creating the base solution for a Windows Phone 7 game:

wp7platformer002

You then need to import the various source files from the XNA 3.1 project (Player.cs, Level.cs, Tile.cs, etc.) into the main XNA 4.0 project. Then, you need to import the game’s resources in the content project. Indeed, first difference between XNA 3.1 & XNA 4.0, the resources (handled by the Content Pipeline) are now shared between each platform (Xbox 360, PC & mobile phone) whereas there were copied in each project before.

Once imported, you’ll notice that the solution won’t compile yet. Indeed, some parts have changed between XNA 3.1 & XNA 4.0. In our case, the only parts of the code that need to be updated to allow compilation are linked to the files accesses. There is 2 parts of the code you’ll need to modify.

The first one is inside the “PlatformerGame.cs” file in the LoadNextLevel() method. You have to change this piece of code:

// Try to find the next level. They are sequentially numbered txt files.
levelPath = String.Format("Levels/{0}.txt", ++levelIndex);
levelPath = Path.Combine(StorageContainer.TitleLocation, "Content/" + levelPath);
if (File.Exists(levelPath))
    break;

by this one:

// Try to find the next level. They are sequentially numbered txt files.
levelPath = String.Format("Levels/{0}.txt", ++levelIndex);
levelPath = "Content/" + levelPath;

try
{
    StreamReader sr = new StreamReader(TitleContainer.OpenStream(levelPath));
    fileFound = true;
}
catch
{
    fileFound = false;
}

if (fileFound)
    break;

Don’t forget to add this namespace:

using System.IO;

The second part is inside the “Level.cs” file in the LoadTiles() method. Change this line:

using (StreamReader reader = new StreamReader(path))

by this one:

using (StreamReader reader = new StreamReader(TitleContainer.OpenStream(path)))

The first method checks if a next level is available. If so, it uses the 2nd method to load it. Each level is described in the “Level” directory inside a classic text file (0.txt, 1.txt, etc.) that looks like this:

........
........
.X......
###.....
........
......G.
.....###
........
.G......
###.....
........
......G.
.....###
........
1.......
########

The ‘1’ character indicates where the player will start the level, the ‘#’ character the blocks on which the player can jump, the ‘G’ the diamonds the player takes to score and the ‘X’ the level’s exit. Each association are described in the LoadTile() method. You can see above the level 0 description for the Zune splitting the screen into 8 columns and 16 lines.

To finish on this part, in order to be able to properly compile, you’ll need to change the properties of each level’s text file to change the “Build Action” property from “Compile” to “None” and the “Copy to Output Directory” from “Do not copy” to “Copy if newer”. You’ll need also to modify some sounds content properties to change the value from “Song – XNA Framework” to “Sound Effect – XNA Framework” (except the music itself of the game of course). These slight modifications are linked to the brutal copy/paste operations we’ve done before. The Content Pipeline has just assumed some wrong default properties.

If you launch the game at this stage, the current output is currently… a bit weird! :-)

wp7platformer003

We’ll then need to modify a bit the code and some design elements in order to make them matched the Windows Phone resolution.

Step 3: updating the game for the Windows Phone resolution

If you have a look at the initial XNA 3.1 code, you’ll notice that there are different conditional compiler directives for each platform:

#if ZUNE
        private const int TargetFrameRate = 30;        
        private const int BackBufferWidth = 240;
        private const int BackBufferHeight = 320;
        private const Buttons ContinueButton = Buttons.B;        
#else
        private const int TargetFrameRate = 60;
        private const int BackBufferWidth = 1280;
        private const int BackBufferHeight = 720;
        private const Buttons ContinueButton = Buttons.A;
#endif

We then need to handle the windows phone case. Let’s first try to understand how the levels are drawn.

On Xbox 360/PC, we have:

- A graphic resolution (width X height) of 1280x720 (720p)
- Levels are described inside text files with 15 lines and 20 columns.
- We then have blocks of 720/15 = 48 pixels height and 1280/20 = 64 pixels width. We named them “Tile” in our game. Their size will then be 64x48 pixels on PC.

On Zune, we have:

- A graphic resolution of 240x320
- Levels are described inside text files with 16 lines and 8 columns.
- We then have blocks of 320/16 = 20 pixels height and 240/8 = 30 pixels width. The size of our tiles will then be 30x20 pixels on Zune.

Indeed, if you go to the “Tiles” subdirectory of the “HighResolutionContent” (for PC/Xbox) and the “LowResolutionContent” (for Zune) directories, you’ll notice that the size of the images used for these tiles are exactly 64x48 and 30x20. In my case, I’ve decided to use the following values for the phone.

On Windows Phone, we will have:

- A graphic resolution of 480x800
- I’d like to reuse the Zune levels described with 16 lines and 8 columns.
- We then have blocks of 800/16 = 50 pixels height and 480/8 = 60 pixels width. The size of our tiles will then be 60x50 pixels on Windows Phone.

Now that we’ve done some decision on the resolution, we now need to update the sprites and the code accordingly. For the sprites, I’ve reused the samples provided inside the “HighResolutionContent” and I’ve resized them thanks to Paint.NET.

In the source code, we then need to replace the previous code of the “PlatformerGamer.cs”  file by this one:

#if WINDOWS_PHONE
        private const int TargetFrameRate = 30;        
        private const int BackBufferWidth = 480;
        private const int BackBufferHeight = 800;
        private const Buttons ContinueButton = Buttons.B;        
#else
        private const int TargetFrameRate = 60;
        private const int BackBufferWidth = 1280;
        private const int BackBufferHeight = 720;
        private const Buttons ContinueButton = Buttons.A;
#endif

In the “Tile.cs”  file, replace these lines:

#if ZUNE
        public const int Width = 30;
        public const int Height = 20;
#else
        public const int Width = 64;
        public const int Height = 48;

by those one:

#if WINDOWS_PHONE
        public const int Width = 60;
        public const int Height = 50;
#else
        public const int Width = 64;
        public const int Height = 48;

With the high resolution sprites and our tiles modified with Paint.NET, we now start to have a game that looks relatively nice:

wp7platformer004

We even can start playing to the game using the PC keyboard of the host inside the emulator. However, you’ll quickly notice 2 issues:

1 – The speed of the game doesn’t seem to be adapted to the phone
2 – On the final device (the real one not the emulator!), we potentially won’t have a keyboard

We’re then going to review the gameplay to match the phone features.

Step 4: review the gameplay to match the Windows Phone features

Let’s start by the simplest task: changing the speed of the characters. There are 2 parts in the code handling the movements. 1 is for the hero inside “Player.cs" and 1 is for the bad guys inside “Enemy.cs”. Go into the “Enemy.cs”  file and replace this code:

#ifZUNE
        private const float MoveSpeed = 64.0f;
#else
        private const float
MoveSpeed = 128.0f;
#endif

By this one:

#if WINDOWS_PHONE
        private const float MoveSpeed = 64.0f;
#else
        private const float MoveSpeed = 128.0f;
#endif

This was simple. We’ve just slowdown the speed of the bad guys to divide their speed by 2. This better fits the width of the phone. The hero has more detailed characteristics on its side. You’ll then find its move acceleration, its maximum move speed, the forces to apply when it’s jumping, etc. This is what we call a physics engine (even if here, it’s a pretty simple one). Locate the last conditional section inside the “Player.cs” file and replace it by this new one:

#if WINDOWS_PHONE
        // Constants for controling horizontal movement
        private const float MoveAcceleration = 7000.0f;
        private const float MaxMoveSpeed = 1000.0f;
        private const float GroundDragFactor = 0.58f;
        private const float AirDragFactor = 0.65f;

        // Constants for controlling vertical movement
        private const float MaxJumpTime = 0.35f;
        private const float JumpLaunchVelocity = -4000.0f;
        private const float GravityAcceleration = 3500.0f;
        private const float MaxFallSpeed = 600.0f;
        private const float JumpControlPower = 0.16f;

        // Input configuration
        private const float MoveStickScale = 1.0f;
        private const Buttons JumpButton = Buttons.A;  

I’ve chosen these values myself based on the few tests I’ve done within the emulator but feel free to change them as you wish!

The very last step is to be able to play the game without a keyboard or a gamepad. For that, we could imagine using the phone’s accelerometer in order to move the main character on the left or on the right when the user will rotate his phone on those directions. When the user will tap the screen, we will make jumping the hero.

To do that, you’ll need to follow the instructions below originally written to update the game for the Zune HD:

- Zune HD XNA Platformer Game : http://www.allaboutcoding.com/tutorials/cs/zunehd.asp

However, the way to handle the accelerometer is slightly different between the Zune HD and the Windows Phone. For instance, we don’t have (yet ?) the AccelerometerState class. To solve that, you can use the suggested code from this article: Windows Phone Accelerometer Support in XNA which provides a wrapper on the AccelerometerSensor class to be able to have a copy of AccelerometerState. Once this wrapper inserted in your project, you should be able to use as-is the previous code initially designed for the Zune HD.

Source code available for download

Here is the source code containing the result of these 4 steps if you don’t want to follow them yourself:

Unfortunately, I haven’t tested the accelerometer and the touch sections of this project as we don’t have any Windows Phone 7 Series devices in France yet… :-( However if you’re one of these lucky guys currently having one of these prototypes in your hand, feel free to tell me how the code behave on your highly desired phone!

Conclusion

Since I’ve started coding, I've always secretly dreamed (as many of you I guess!) to participate into the conception of a video game. Indeed, to my point of view, this has always been one of the most complex and stimulating kind of development. However, up to now, I’ve been constantly thinking that I wasn’t good enough to face the mountain of details implied by this kind of project. XNA makes me feel that I can face them for the first time! I hope that this will give you the same feeling and that we will soon discover your great games and creativity on our phone.

David

  • Wow very cool blog entry and very nice port, do you have complete udates for the new beta yet. noticed some issues with reference assemblies etc. in the latest beta from your live drive latest code update.. Very nice to see all in all..

  • I know you updated this ages ago, but I am getting this error:

    Cannot find importer "TextureImporter"

    I assume I am missing something very simple. I just don't know what it is.

  • Hi,

    The latest version I've published is here : blogs.msdn.com/.../sl4-xna-platformer-level-editor-pour-wp7-le-jeu-xna-4-4.aspx . It's very easy to recompile it with the RTW version of the WP7 SDK.

    Bye,

    David

  • @jsteph1967: I've the same error: Cannot find importer "TextureImporter".

    I'm try to use the last version, linked by davrous.

  • I cant load some levels.

    I fixed the import references bug, but it cant load some levels.

    Actually i am really surprised, how the levels should come to the isolated storage, if they arent written there yet?

    Damn, I really wanted to check it out :(

  • I want to develop a tic tac toe game using the multicast channel, but i only want 2 players to join this multicast channel , how can i do this????

    please help me??

Page 1 of 1 (6 items)
Leave a Comment
  • Please add 3 and 4 and type the answer here:
  • Post