On Time, On Point, On Budget!

Splash! Game Development For Windows Phone 7

Introduction

How quickly can you create a fully-featured game for modern phone working under Windows Phone 7? What do you need for this? What difficulties can you face?

We will try to answer these questions during small game creation. To create a real world environment it will be a fully featured application that will be submitted to Windows Phone Marketplace.

We will review the full cycle of a game creation process beginning from the idea and ending with publishing the game to Marketplace, without omitting any detail of this process.

Game idea

We won't clone other games. We will think of something new, interesting and colorful – designed specifically for phones with accelerometer and touch screen. You can maneuver the ball with the help of accelerometer by tilting phone to different sides as if it is rolling in a square box.

There are colored balls on the field. They try to reach the white balls to color it in their color.

User can break colored balls by taping on it with a fingertip. When you tap the ball turn into colored splashes and then disappear new balls then appear. For each broken ball you achieve a higher score. The number of levels that a user can play is unlimited.

The player should attempt to achieve the highest score possible.

To make a player use accelerometer (but not only break the balls), one more balls (black) is added to the game. Black balls can't be broken till they get a color.

2D-graphics is enough for this game. Besides, it is needed to play sounds and interact with accelerometer and touch screen.

Development environment

To create applications for Windows Phone 7, we needed: Visual C# 2010 Express and Windows Phone Developer Tools. Both free products.

Then go to the Microsoft website, download and install the following tools:
http://www.microsoft.com/express/Downloads/

Windows Phone Developer Tools can't be installed on Windows XP, however you can do this way:
http://www.brucebarrera.com/how-to-install-windows-phone-7-developer-tools-on-windows-xp. However, it is likely that the phone emulator won't run on Windows XP, thus it's better to install Windows 7.

If you already have Visual Studio 2010, it is better to install Windows Phone Developer Tools on it, as Visual C# 2010 Express is much less comfortable.

Technology selection: XNA vs Silverlight


 

After Windows Phone Developer Tools installation there is an option to create new project types in Studio: Windows Phone Application and Windows Phone Game.

Which one suits us more?

The first project is the Silverlight application for Windows Phone 7. Accordingly, it has access to almost all classes, which are presented in usual Silverlight. It has XAML and controls, designer in Studio, etc.

The second project is the XNA 4.0. application. It doesn't have any controls; however it has game cycle and access to the quick features of hardware graphics.

Judging by the name and technology description what we need is XNA. Maybe Silverlight is also suitable for game creation? The simple test with Silverlight for Windows Phone relieves limitations of this technology: hundreds of simultaneously moving small images lead the phone to slide-show mode. If we try the same on XNA, everything works quickly (with a larger number of images).

That is why we will create the game on XNA. It's unfortunate that there are no controls, but it seems they are useless now.

Getting acquainted with XNA

Let's create the Windows Phone Game project in Studio. It appears together with the game class:

public class Game1 : Microsoft.Xna.Framework.Game

Let's define how user will hold a phone during the game. Suppose, it is more comfortable to keep the phone in one hand (tilting it to maneuver a white ball) and tap on the colored balls with another hand. This means we need a portrait game mode. We put this mode to the game constructor.

public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";

    graphics.SupportedOrientations = DisplayOrientation.Portrait;
    graphics.PreferredBackBufferWidth = 480;
    graphics.PreferredBackBufferHeight = 800;
    graphics.IsFullScreen = true;
}

Then in this class we are mostly interested in two features: Update и Draw.

protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();
 
    // TODO: Add your update logic here
 
    base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);
 
    // TODO: Add your drawing code here
 
    base.Draw(gameTime);
}

The first feature is dedicated to game logic processing. We will get data on user actions (from accelerometer to touch-screen) and calculate new positions of all the game objects.

The second feature is for drawing game objects on the screen only.

It's necessary to say that the total time of two features execution shouldn't be more than one iteration of the game cycle. It's about 33 milliseconds on the phone, as the frequency of the game cycle is 30 frames per second. If time of the features execution is bigger than this value: the game will be too slow, some frames will be omitted, or, what is even worse, the game will omit user actions.

That is game is actually a real-time application. How will it react on Garbage Collector actions? It is better to avoid its unexpected intervention, so we will neatly work with objects and won't create thousands on the each iteration. Generally speaking, we won't need to create them often as all the objects of the game world will be relatively long-living. We will use structures or links to already existing objects as feature parameters. This way Garbage Collector won't prevent us from doing of what we need.

Let's try to compile and launch the application. On several computers, you may see the message that XNA can't be launch on emulator. This way you may create the Windows Game project and attach files (Add As Link) from our Windows Phone Game project. That is the same XNA-code will work on phone and on Windows (as well as on XBOX 360).

Finally, there is a window filled with purple color. This is the result of the GraphicsDevice.Clear(Color.CornflowerBlue) feature execution.

There is the SpriteBatch object class in the game class. This object is everything we need when drawing. It contains all the necessary methods for work with 2D-graphics and text.

But still we lack the most important aspect which is game content.

Content

Game content is different resources necessary for game, such as textures (images used for drawing), fonts (as we need to output text) and sounds.

Together with the Windows Phone Game project, we create another project in which name is the word "Content".We should add files with images and sounds to this project.

Besides, we should set all fonts to be used for text output in this project.

It's very simple to load content in the program with the help of the Content.Load(assetName) function. The Content attribute is available in the game class. The resource name (which we added to the project with content) should be put as assetName. As a rule this is just a file name without extension. Content type to be used (Texture2D, SpriteFont or SoundEffect) should be set as T.

Content load isn't a quick operation, that is why we will load all the content when the game starts and will use it when needed.

Now everything is prepared and we can start the game development.

Game logic

All game logic can be in put in a separate class "GameController". Now the Update feature in the game class looks like this:

protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();
 
    GameController.Update(gameTime);
 
    base.Update(gameTime);
}

Note that we send object of the GameTime class to GameController.Update. It has the ElapsedGameTime attribute which shows how much time has passed since the previous call of the Update feature. As a rule this time is fixed and equals 33 milliseconds on the phone. However it's better not to rely on it but use the sent value in all the calculations.

We will use ElapsedGameTime when we need to calculate movements of the game world objects. For example, if we need to calculate a new position of the white ball (under the influence of the phone tilt), it will look this way:

position += (float)(acceleration * gameTime.ElapsedGameTime.TotalSeconds);

Radius of balls and splashes (at the moment they appear) is calculated this way:

radius += (float)(GrowSpeed * gameTime.ElapsedGameTime.TotalSeconds);

All the calculations will be done in separate classes. Each class will have its own analogical the Update(gameTime) feature. GameController.Update will just call them. 

Drawing graphics

Drawing graphics is sent to the GameController class. The Draw feature in the class of the game now looks the following way:

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.Black);
   
    spriteBatch.Begin();
    GameController.Draw(spriteBatch);
    spriteBatch.End();

    base.Draw(gameTime);
}

Note, we send only the SpriteBatch object class to GameController.Draw. It is used for only for drawing. We do not need GameTime here as all the necessary calculations are already in the Update feature.

Then, GameController.Draw will call the analogical Draw(spriteBatch) features from the classes which realize game world logic.

Drawing itself looks quite simple:

spriteBatch.Draw(texture, position, color);

That is we can display only ready textures. Drawing of 2D primitives drawing (lines, rectangles, ellipses, etc.) isn't provided in XNA.

You can get texture by loading it from the content:

Texture2D texture = Content.Load<Texture2D>(assetName);

Textures have been loaded already; all the positions have been calculated. However we can "play" with color! If we need original texture color, we need to have Color.White.

If we need to have another color, texture should be drawn with this color layout. If we need to set a color with alpha-channel, then texture will be drawn transparently. So, we can manage smooth appearance and disappearance of the objects and their color change (these is exactly what we need in our game).

To mix two colors we use the Color.Lerp function. To add alpha-channel we should use the Color.FromNonPremultiplied function.

There are also other variants of the spriteBatch.Draw function that allow textile changing and scaling. Which will also need.

Text output

Text display is as simple as graphics output:

spriteBatch.DrawString(spriteFont, text, position, color);

You can get Object of the SpriteFont class by loading it from the content:

SpriteFont spriteFont = Content.Load<SpriteFont>(assetName);

You can also set font colors in the same way here. If you set a color with alpha-channel, the text will be transparent.

If you set coordinates for text output with float-position then text may be displayed a little bit distorted. That is why we will round coordinates to integer number when smooth text movements are not necessary.

There are other variants of the spriteBatch.DrawString function which allow turning and scaling the text. It is necessary to remember that such movements cause text misrepresentation. This happens as XNA doesn't work with original vector font, but with its raster presentation, which is created at the moment of project compilation and is added to content. 

Touch screen

To define where user has taped the screen, we should get data from the Microsoft.Xna.Framework.Input.Touch.TouchPanel class:

foreach (var item in TouchPanel.GetState())
{
    if (item.State == TouchLocationState.Pressed
        || item.State == TouchLocationState.Moved)
    {
        // Get item.Position
    }
}

Thereby, we get all the screen dots which user has touched. However we will need data on one-time action of screen touching (when you tap and take finger from the screen). This is necessary for tracking touches of the screen buttons, for example, the Pause button. To get this data we should use gesture support.

At the game beginning we should indicate that we need support of the gestures (taps):

TouchPanel.EnabledGestures = GestureType.Tap;

Then we can get gestures in each iteration of the game cycle:

while (TouchPanel.IsGestureAvailable)
{
    GestureSample gesture = TouchPanel.ReadGesture();
 
    if (gesture.GestureType == GestureType.Tap)
    {
        // Get guesture.Position
    }
}

Accelerometer

To get data on the phone tilt we will use the Microsoft.Devices.Sensors.Accelerometer class. Unfortunately, we can't get data directly from accelerometer (the way we did it with TouchPanel) as it supports event model only. That is why we should use subsidiary class which creates object and subscribes on its event:

accelerometer = new Microsoft.Devices.Sensors.Accelerometer();
accelerometer.ReadingChanged += AccelerometerChanged;
accelerometer.Start();

In the event handler we will remember acceleration value and save it for further usage:

private void AccelerometerChanged(object sender, AccelerometerReadingEventArgs e)
{
    vector = new Vector3((float)e.X, (float)e.Y, (float)e.Z);
}

Acceleration vector contains information about all three axes (X, Y and Z), but we need first two only (for portrait orientation of the phone). That is why attribute which returns acceleration in our system of coordinates will look this way:

public Vector2 Acceleration
{
    get
    {
        return new Vector2(vector.X, -vector.Y);
    }
}

Right this acceleration will be given to the white ball.

More obvious presentation of accelerometer axes is here.

Playing sounds

You can play sounds in XNA with the help of the Play function in the object of the SoundEffect class. Object of this class can be loaded from content:

SoundEffect sound = Content.Load<SoundEffect>(assetName);

That is all we should do with sounds.

Windows

A lot of things are ready: the white ball is moving by accelerometer, the rest balls chase it and are turned into splashes when touched, score is calculated, sounds are playing. It seems like everything is ready? No, it's not that simple.

Now we need to create windows: start windows (main menu), pause dialogue and windows of game end (with display of gained score and records).

There are no windows XNA for Windows Phone, that is why we will have to do them on our own. It isn't as difficult as it may seem at first sight.

It is enough to create a basic control with main features: Parent, Children, Bounds, Visible, Enabled and with functions "Update" and "Draw". Then we should create several child classes: Window, Button, Label, etc.

After that we can easily display elements in windows.  

Saving game state

The game on the phone can be put on hold at any moment either by clicking on the "Home" button or by any other external event. That is why we need to take attention to saving game state at any moment of time and further resume of this state when game launched.

Let's use the System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings class for saving states (and settings). This class implements the IDictionary interface, that's why it's quick easy to work with it. Let's summarize the current state of all the game world objects (hopefully there are no many of them) to this dictionary and call the IsolatedStorageSettings.ApplicationSettings.Save() function.

Game will be saved at the moment when you exit it. To do so, let's override the OnExiting function in the game class:

protected override void OnExiting(object sender, EventArgs args)
{
    GameController.SaveState();

    base.OnExiting(sender, args);
}

Game resume is done analogically. When the app is launched we receive the data from IsolatedStorageSettings.ApplicationSettings and resume all the game world objects.

Application activation and deactivation

Our application won't always be in an active state. Sometimes it may be deactivated (i.e. in case of incoming call) and activated again.

To track these events let's override the OnActivated and OnDeactivated functions in the game class.

During application deactivation we will put the game in pause mode so the dialogue message about resuming the game will appear when user returns to it.

Besides, not to waste calculating resources of the phone in deactivated state, let's add the following code to the beginning of the Update function in the game class:

if (!IsActive)
{
    SuppressDraw();
    return;
}

Splash Screen

Our game (to be precise, game content) is loaded within several seconds and displays only black screen during this time period. We should show users that the application is working. To do so we should draw a nice splash-screen to show it at the game launch:



It will be shown automatically if you just to add the SplashScreenImage.jpg file for Windows Phone in Silverlight application.

However it doesn't work for XNA projects.

We'll have to re-make content load. At first we do texture for splash-screen and draw it during the first call of the Draw function. Then we load the rest content and launch the game. Till the rest content is loading, splash-screen is displayed.

Now the game start looks much nicer.

Game location in the phone

To make our game appear in the phone in the Games section (you can reach it by clicking the XBOX LIVE button on the start screen of the phone) you need to edit the WMAppManifest.xml file in the project. In this file instead of the Genre="Apps.Normal" line you should write Genre="Apps.Games".

Plus let's put game name and description in the same file (in the Title and Description attributes). Let's remove the unnecessary requirements (section ). In this section we will leave only for accelerometer support. We don't need the rest parts in this version of the game.

The project should have two pictures: GameThumbnail.png and Background.png.

The first picture is needed for game display in the Games section and the second one is needed for start screen of the phone. Size of the both pictures should 173×173 pixels.

Trial-mode

As our game will be for money, we need to add trial mode support. Trial check is already built to the platform and is done with the help of the Microsoft.Phone.Marketplace.LicenseInformation class:

var license = new Microsoft.Phone.Marketplace.LicenseInformation();
return license.IsTrial();

As the function is rather slow, we won't call it each game cycle iteration. Instead of this we will call it only when the application is activated (in the OnActivated function of the game class and the result will be saved in variable).

If the application is launched in the trial mode, then after several minutes, the window offering game purchase (or starting a new game) appears.

When clicking the Buy button, we call display of our application in Windows Phone Marketplace:

var market = new Microsoft.Phone.Tasks.MarketplaceDetailTask();
market.Show();

After purchase user can return to the application and continue the game.

The Back button

Everything is almost ready and we send the application to Windows Phone Marketplace. Before publication it is carefully tested by Microsoft and after several days it gives the verdict: declined. What is the reason?

The problem is in code we left in the Update function.

protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();
 
    ...
}

Hardware button "Back" should work must work in a certain manner, that is return users to the previous screen. You can exit the application using the button if user is on the start screen of the application (main game menu) only. If you are in the pause mode then the button must return you back to the game.

In our case, the button always called application exit. Let's remove this code and apply the correct work of the button and send it to Microsoft review again. Repeated review will take less time.

Results

Yes, the application is accepted! Now the game is in Windows Phone Marketplace.
All in all we spent about two weeks on the game development (and two weeks on publishing to the marketplace). At the end we got a nice and attractive game:


 

Editorial Staff of the Best WP7 Games website reviewed this game: http://www.bestwp7games.com/splash-fun-accelerometer-game-for-wp7-review.html


In a week after submission, the game appeared in Top 100 paid games in Windows Phone Marketplace.

What can we conclude from our experience in this game development? The answer is: creation games for Windows Phone 7 is really very simple!

You can download game here

Want to benefit by our experience in mobile application development for Windows Phone? Start with your project estimation right now!

This entry was posted on Wednesday, February 16th, 2011 at 8:11 am and is filed under Windows Phone 7, XNA.