Bill Reiss is a Windows Platform Development MVP and a Senior Consultant for AgileThought

Archive for April, 2012

This is the fifth part of a series where I am taking a presentation I did on using XNA with Windows Phone and stepping through it, elaborating as necessary. Here are the original assets for the presentation, including source code and demo script.

This series is all about demystifying game development and breaking it down into simple steps:

- Draw Stuff
- Handle and act on input
- Play sounds
- Monetize
- Stick with it!

So far we’ve made it through the first two steps and we’re on to playing sounds. This post starts where we left off last time: http://www.billreiss.com/wp-content/uploads/2012/04/MyFirstGame_part4_completed.zip

Step 3: Play Sounds

There are two major types of sounds in XNA, one is for sound effects and the other is for longer sounds that is mainly used for background music and cut scenes. Both are easy to get the basics working in while providing advanced capabilities if needed. Let’s look at sound effects first.

First of all, add the sound effect file to your content project. You can use this file:

http://www.billreiss.com/wp-content/uploads/2012/04/PlayerJump.wma

Call it PlayerJump.wma. When you add it to your content project and then look at the properties window it’ll look something like this:

image

Since this is a WMA file it defaults to the Song content processor. Since we want to use it as a sound effect, you need to change the content processor to Sound Effect:

image

If you were to bring in a WAV file, it would default to Sound Effect since this is the native format for sound effects.

Add a field to the Game class for the sound effect:

SoundEffect playerJumpSound;

Then in the LoadContent method, we do pretty much the same thing as for images but specify the SoundEffect type instead:

playerJumpSound = Content.Load<SoundEffect>("playerJump");

And finally in the Update method, we can play the sound effect when we detect to start a jump:

if (isPressed && !jumping)
{
    jumping = true;
    currentPlayerAnimationDelay = 0;
    velocityY = startVelocityY;
    playerJumpSound.Play();
}

 

Run the app and when the player jumps you should now hear the sound play. Next let’s take a look at background music. For this we can use the Song and the MediaPlayer classes.

Here is our looping music:

http://www.billreiss.com/wp-content/uploads/2012/04/MusLoop.wma

Add it to the content project and this time we can keep the default content type of Song. Now declare a new field in the Game class to hold the Song:

Song musicLoop;

Then in the LoadContent method:

musicLoop = Content.Load<Song>("MusLoop");
MediaPlayer.IsRepeating = true;
MediaPlayer.Play(musicLoop);

Now if you run the game again you should hear looping background music.

One issue with sound is finding good sound effects and music that are licensed for use in mobile applications. One good source I’ve found for inexpensive and royalty free sounds and other assets is http://www.pond5.com

Here is the source code for our current progress:

http://www.billreiss.com/wp-content/uploads/2012/04/MyFirstGame_part5_completed.zip

In the next post we’ll look at adding the Microsoft Advertising control to our game.

The first 3 parts of this series covered the first step of game development, Draw Stuff. Now we move on to the next step, Handle and Act on Input.

This sample starts where the last one left off, here is the source code we’ll build on:

http://www.billreiss.com/wp-content/uploads/2012/04/MyFirstGame_part3_completed

I’ll be following up this series of posts with more information on checking for input, but for now we’ll focus on a simple case where we’re just checking to see if the screen is being touched.

Step 2: Handle and Act on Input

For this demo we’ll handle touch data, but the techniques are similar for the accelerometer and other common inputs on phone, PC, and Xbox. In XNA all of these inputs are done using a polling technique, and generally you’ll call a GetXXXState method in your Update method.

One of the most popular categories of games on phones are “one button” games. These come in a bunch of variations, but basically the input is simplified so that you only detect whether the screen is currently pressed and you don’t care where. It’s surprising how much fun a game can be with such limited input. Some examples of this type of game are Funny Jump, Penguin, and Gravity Guy.

Given the simplicity of input and the popularity of this type of game, we’ll focus on this type of game for this sample. We’ll make the player jump if the screen is touched.

First, let’s add another texture to the content project. Click on the image below and then right click on it to save it to your computer as jump.png.

Jump

Add this image to the Content project.

Then, we need some fields to store the current state of the jump:

Texture2D playerJump;
bool isPressed = false;
bool jumping = false;
float velocityY = 0;
float offsetY = 0;
float accelerationY = 600f;
float startVelocityY = -500f;

Then as we’ve seen a few times already, we load the content in the LoadContent method:

playerJump = Content.Load<Texture2D>("jump"); 

The Update method is where the most changes will happen. Replace the previous Update logic we added with the following:

if (jumping)
{
    offsetY += velocityY * (float)gameTime.ElapsedGameTime.TotalSeconds;
    if (offsetY > 0)
    {
        offsetY = 0;
        jumping = false;
    }
    velocityY += accelerationY * (float)gameTime.ElapsedGameTime.TotalSeconds;
}

TouchCollection touchPoints = TouchPanel.GetState();
isPressed = touchPoints.Count > 0;

if (isPressed && !jumping)
{
    jumping = true;
    currentPlayerAnimationDelay = 0;
    velocityY = startVelocityY;
}

currentPlayerAnimationDelay += gameTime.ElapsedGameTime.TotalSeconds;
if (!jumping)
{
    while (currentPlayerAnimationDelay > playerAnimationDelay)
    {
        playerCurrentFrame++;
        playerCurrentFrame = playerCurrentFrame % 10;
        currentPlayerAnimationDelay -= playerAnimationDelay;
    }
}
else
{
    double totalJumpTime = Math.Abs(startVelocityY * 2) / accelerationY;
    playerCurrentFrame = (int)MathHelper.Lerp(0, 10.999f, (float)(currentPlayerAnimationDelay / totalJumpTime));
    if (playerCurrentFrame > 10) playerCurrentFrame = 10;
}
platformOffset += platformScrollSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
if (platformOffset > platform.Width) platformOffset -= platform.Width;

There are a few things going on in here. First of all it handles gravity if the character is jumping. Remember your high school physics class right now! The change in velocity is equal to acceleration multiplied by time. So when the character is jumping, we modify the Y velocity based on gravity and elapsed time and also check if we’re done jumping (if we’re back to the ground level).

Next we see if any touch points are pressed by getting the state of the TouchPanel. If this wasn’t a one button game you could interrogate how many points were active, and what the state is. These include Moved, Pressed, and Released, so you can tell if the user is pressing, dragging a finger, or letting go.

Finally if we’re jumping, the current frame to display is based on how far we are through the jump. Here comes high school physics again. If I remember correctly the total jump time will be double the start velocity divided by gravity, please let me know if this is incorrect.

One thing that may look a little different in this part is that since the amount of time jumping depends on the initial velocity and we want to spread all of the frames of the jump animation across that time, we need to calculate how far we are through the jump at any given time and show the correct frame. This is a bit more complicated than just changing the frame on an interval but it’s not too bad. One way we could do this is to calculate the total time, divide it by the number of frames we have, and use this interval to handle animation just like we did for running.

In order to show something a little different I’ve decided to use the MathHelper.Lerp method. The MathHelper is a very useful class provided by XNA and I highly recommend you dig through the functionality it provides.

Lerp is shorthand for “Linear intERPolation” and by providing a start value, end value, and percentage from 0 to 1 it will give back the appropriate value in between. So in our case, to calculate the current frame we can use a start value of 0, and end value of 10.999 (close enough to 11 without getting there) and the percentage comes from the time since the start of the jump divided by the total jump time. Feeding this into Lerp gives us the current frame. Also look at SmoothStep which interpolates between two values using a curve that is generally more pleasing to the eye when doing movement.

If we’re not jumping we do the same thing we were doing before to handle the running animation.

And in the Draw method we can replace the spriteBatch.Draw for the player with this:

if (!jumping)
{
    spriteBatch.Draw(player, new Vector2(80, 300 + offsetY), new Rectangle(playerCurrentFrame * player.Height, 0, player.Height, player.Height),
        Color.White, 0, Vector2.Zero, 1, SpriteEffects.FlipHorizontally, 0);
}
else
{
    spriteBatch.Draw(playerJump, new Vector2(80, 300 + offsetY), new Rectangle(playerCurrentFrame * playerJump.Height, 0, playerJump.Height, playerJump.Height),
        Color.White, 0, Vector2.Zero, 1, SpriteEffects.FlipHorizontally, 0);
}

If we’re not jumping we draw exactly as we were drawing before for the running animation, otherwise we need to draw the jumping animation and draw the correct frame.

Now if you tap the screen the player should jump like this:

image

The code as of the end if this step is here:

http://www.billreiss.com/wp-content/uploads/2012/04/MyFirstGame_part4_completed.zip

Next time we’ll look at adding sound effects.

At the end of Part 2 of this series, we had our character running in place. image_thumb5

This was done through the Update method of the XNA Game class processing when the frame should change, and then the Draw method called the appropriate SpriteBatch.Draw method to draw the current frame. Here is the source code that we’ll start with and build upon in this post.

http://www.billreiss.com/wp-content/uploads/2012/04/MyFirstGame_part2_completed.zip

This is a fairly short one, we just need to build upon some of the topics so far to build a platform for our player to run on, and then we’ll be done with Step 1 (“Draw Stuff”) of building an XNA game.

Here is the platform image:

Platform

Click on the image and then select to save it to your computer. Call it platform.png.

Now just like with the player image from Part 1, add an existing item to the content project. This time we’ll use platform.png. Now we want to do exactly the same thing we did before, adding a field to store the texture, and a couple of others to store the animation state:

Texture2D platform;
float platformOffset = 0;
float platformScrollSpeed = 200;

And in LoadContent we’ll load it:

platform = Content.Load<Texture2D>("platform");

And then in the Draw method we’ll draw a row of these under the player:

for (float f = -platformOffset; f < 800; f += platform.Width)
{
    spriteBatch.Draw(platform, new Vector2(f, 300 + runFrameHeight),
        Color.White);
}

Notice that you can use the same texture multiple times when drawing. This is starting to look better:

image

Now to give an illusion of motion we can scroll the platform by changing the platformOffset in the Update method based on the speed and the elapsed time:

platformOffset += platformScrollSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
if (platformOffset > platform.Width) platformOffset -= platform.Width;

Every time we scroll more than the width of a block, we’ll subtract the width of the block from the offset so that the number doesn’t keep getting bigger, but since we shift by exactly the width of one block the motion looks smooth and continuous.

Run it again. You should now see the running man and the scrolling platform. Not bad for less than 40 lines of code.

Here is the source code for the project at this point:

http://www.billreiss.com/wp-content/uploads/2012/04/MyFirstGame_part3_completed.zip

In the next post we’ll start Step 2 and look at how to handle input in XNA.

In the last post we created a new XNA game solution for Windows Phone, added an image to draw to the content project, loaded it, and drew it to the screen. We also explored how to remove the taskbar and taking advantage of hardware scaling for performance. At the end of Part 1 we were somewhere around here:

image

Here is the source code for the starting point for this post:

http://www.billreiss.com/wp-content/uploads/2012/04/MyFirstGame_part1_completed.zip

Now let’s take it a step further and only draw a part of the image so that we only see one frame at a time.

This image that we’re drawing (called a texture in XNA) is known as a sprite sheet and it’s copied from the Platformer sample that ships with XNA. A sprite sheet is an image that contains multiple frames of motion for a sprite or sprites.

When using the graphics processor (GPU) to draw like XNA does, it’s more efficient to use a single texture and draw only what you need from it instead of loading a texture for each frame and swapping them. It’s even more efficient to pack all of your textures into a single texture and with each draw call draw only what you need. This is because there is significant overhead in telling the graphics processor to use a different texture.

The sprite sheet that we’re using is the texture used when the character is running. There is one part of the texture for each frame in the running animation and by drawing these in sequence we can get the illusion that the character is running.

TIP: If creating your own character, you can draw over an existing sprite sheet, it’s easy to find these on the internet. By drawing over an existing one it’s easier to draw the character in the correct positions. Instead of figuring out what positions you need to give the illusion of running you can just focus on the artwork.

To draw only a single frame, let’s add fields to store the current frame and the frame height and width:

int playerCurrentFrame = 0;
int runFrameWidth = 0;
int runFrameHeight = 0;

In the LoadContent method we’ll take the loaded player texture and calculate the frame width and height from it:

player = Content.Load<Texture2D>("run");
runFrameWidth = player.Width / 10;
runFrameHeight = player.Height;

Then in the Draw method, we’ll change the Draw call as follows:

spriteBatch.Draw(player, new Vector2(80, 300),
    new Rectangle(playerCurrentFrame * runFrameWidth, 0,
    runFrameWidth, runFrameHeight), Color.White);

This is a different overload of the Draw method, there are a lot of them. Take some time to look at all of the different SpriteBatch Draw calls since the right overload can save you a lot of effort.

Run the app again. Now you should only see one frame.

image

Now if we want to animate the character, we can do this with the Update method.

playerCurrentFrame++;
playerCurrentFrame = playerCurrentFrame % 10;

Since there are 10 frames in this animation, the frame count is incremented every time the Update method is called, and when it gets to 10 it starts over. Run the app again.

Looks like he’s running a little fast, so let’s slow him down a bit. Instead of updating the current frame every time Update is called, it’s do it based on a time value. Add the following fields to the Game class:

double playerAnimationDelay = .05;
double currentPlayerAnimationDelay = 0;

And in the Update method, the code changes as follows:

currentPlayerAnimationDelay += gameTime.ElapsedGameTime.TotalSeconds;
while (currentPlayerAnimationDelay > playerAnimationDelay)
{
    playerCurrentFrame++;
    playerCurrentFrame = playerCurrentFrame % 10;
    currentPlayerAnimationDelay -= playerAnimationDelay;
}

Now by changing the playerAnimationDelay value you can control exactly how fast your character animates. He’s also facing the wrong way for our needs, so change the spriteBatch Draw call as follows:

spriteBatch.Draw(player, new Vector2(80, 300),
    new Rectangle(playerCurrentFrame * runFrameWidth, 0,
    runFrameWidth, runFrameHeight),
    Color.White, 0, Vector2.Zero, 1, SpriteEffects.FlipHorizontally, 0);

Cool now he should be facing the right way and running at a slower speed.

image

http://www.billreiss.com/wp-content/uploads/2012/04/MyFirstGame_part2_completed.zip

In the next post we’ll look at giving our character something to run on.

To get started developing games for Windows Phone you need to have the Windows Phone 7.1 SDK installed. You can get it here. Once you’ve installed this you’ll also want the 7.1.1 update, which you can get here. The update requires the 7.1 SDK to be installed first.

If you’re installing on Windows 8, check out my post about installing the Windows Phone development environment on Windows 8.

In this post we’ll start creating a new XNA game, and begin with the most visible step, and the one people thing of first when they think of game development. We’ll draw something to the screen.

Step 1: Draw Stuff

Let’s start by creating a new XNA game project. Run Visual Studio 2010 with Windows Phone SDK 7.1.1 installed. Select File -> New -> Project and select XNA Game Studio 4.0 and choose Windows Phone Game. We’ll call our game MyFirstGame.

image

Choose to target Windows Phone 7.1, there’s no real reason to target 7.0 anymore.

image

With 7.1 there are many new capabilities with the most important for games being fast app switching, or the ability to resume your game via the back button without reloading everything.

This creates two projects, one for your XNA game and one for your game’s content. Content projects contain any assets for your game, including images, sound effects, 3D meshes, shaders, and level data. Assets that are added to the content project are compiled to a proprietary XNB format that XNA understands so that XNA doesn’t need to know how to deal with the various asset types when the game is running, the heavy lifting is done at compile time.

image

The solution that is generated is a fully functioning game. It doesn’t do a whole lot yet, but helps you to know where your code needs to be added. Run the game in the emulator and you will see the “blue screen of life”, by default you get a Cornflower Blue background and not much else, but at least the back button works.

Run the game and show what it looks like so far.

image

Now one thing you may notice is that the game doesn’t fill the entire screen. It’s kind of hard to see in the emulator, but by default the system tray is displayed, and your game is scaled (letterboxed and preserving aspect ratio) in the remaining space.

To remove the system tray, in the game project, go to Game1.cs. and add the following to the Game1 constructor:

graphics.IsFullScreen = true;

Run the app again and you should see that it fills the entire area.

image

Now it’s time to draw something.

Save this image to your computer. You can do this by clicking on it and then right clicking and save the image. Call it run.png.

Run

In the content project, select Add Existing Item and go to the Assets folder and pick run.png from wherever you saved it to.

Add a field to the Game1 class:

Texture2D player;

and in the LoadContent method after the TODO comment add the following:

player = Content.Load<Texture2D>("run");

The text “run” is the asset name of the content we want to load. By default this is the filename without the extension, but you can change this in the properties pane for the content item.

In the Draw method, add the following to draw the texture:

spriteBatch.Begin();
spriteBatch.Draw(player, new Vector2(80, 300), Color.White);
spriteBatch.End();

When drawing using SpriteBatch, you need to make sure that for every Begin of the SpriteBatch that you have a corresponding End. You should also limit the number of Begin and End calls that you do, but you can do as many Draw calls as you want between a single Begin and End. It’s not a big deal to have a few Begins and Ends but don’t have one per draw call, since most of the overhead when drawing is in the End call because this is where the graphics are actually rendered.

Run the game. It should look like this:

image

One thing you’ll notice is that the texture is being drawn sideways.

By default XNA apps are in landscape mode on the phone. You can change this by adding the following to the Game constructor:

graphics.PreferredBackBufferWidth = 480;
graphics.PreferredBackBufferHeight = 800;

 

By specifying a height that is larger than the width, XNA automatically determines that it should be in portrait mode.

image

There’s another neat trick when it comes to the back buffer width and height and XNA on the phone. The phone resolution of 800×480 is almost 400,000 pixels. Drawing this many pixels can potentially impact the performance of your game, especially if drawing a lot of big textures. You can automatically scale the game using hardware scaling by specifying smaller values for the preferred width and height. By specifying values of half the native size you end up drawing one quarter of the pixels that you do in full resolution. Of course, all of your textures will be scaled up too, so you’re sacrificing level of detail for performance, but if you need it, it’s good to have it available. Change the constructor code as follows:

graphics.PreferredBackBufferWidth = 240;
graphics.PreferredBackBufferHeight = 400;

 

Run the app and it should look like this:

image

Everything is now double size. Now that we’ve had fun with orientation and scaling, let’s remove the code to set the width and height and go back to displaying it in landscape mode. We can also rotate the emulator so that it’s displaying in landscape mode on the screen.

image

Here is the source code for everything up to this point: http://www.billreiss.com/wp-content/uploads/2012/04/MyFirstGame_part1_completed.zip

In the next post we’ll look at drawing a single frame of this image and how to draw different frames over a period of time.

I recently revamped my Intro to XNA presentation so that I could present something fresh at the Orlando Code Camp. I have this problem where I don’t like to take the easy path and keep presenting the same thing.

When I’ve presented about game development recently I’ve had the impression that most of the attendees thought it was cool but it was something that they couldn’t actually do.

Because of this, I decided to try to make it more approachable and break down game development into its core parts and if you take them one at a time it’s not that scary.

So these are the steps I broke it down to:

  • Draw stuff
  • Handle and act on input
  • Play sounds
  • Monetize
  • Stick with it!

You can find my presentation slides and demos here: http://www.billreiss.com/wp-content/uploads/2012/04/XnaWp7GameDev.zip

I’ve decided to turn this presentation into a series of blog posts, so stay tuned and I hope you enjoy the posts as much as I enjoyed putting it together. When we get to the end it will look something like this:

image

This morning I received word that I have been renewed as a Microsoft MVP (what’s an MVP?) for another year in the Silverlight competency. I thank Microsoft for this honor and especially with some other high profile people not getting renewed I’m humbled to be recognized for the 6th year in a row. This award is based only on what contributions the individual had over the past year, definitely a what have you done for me lately thing.

I was more concerned about this year than any other since the first because of the uncertainty about the future of Silverlight, significant changes in the people involved in the MVP program for Microsoft, and because some individuals involved in deciding who will be a Silverlight MVP are no longer with the company. I also had not been blogging as much about Silverlight (or in general) because I love digging into less traveled territory and much of Silverlight had already been covered so it was unclear where I could provide value. So I spent more time promoting Windows Phone to developers, and found other ways to contribute to the community.

With all that being said, this is very likely the last year I will be a Silverlight MVP. Before I was a Silverlight MVP I started out as an XNA MVP when it was very new, then jumped on Silverlight when it was first announced. Following that pattern, my current interests revolve around Windows 8 and Windows Phone, with more interest on the Windows 8 side since it’s so new and there is more of an opportunity to provide valuable (at least I hope it’s valuable) information to the community.

I think that combining C++ with XAML is very interesting, and will be digging into this a lot, along with C# and XAML for WinRT. And of course I still have a strong love for indie game development so I’m very interested to hear what’s on the roadmap for writing games in managed code for the Windows 8 Store. When this becomes clearer I’m sure I’ll be covering this as well.

I think the next couple of years will be a very exciting time for software developers with incredible opportunities and I’m looking forward to see where we end up.

I’ve done a bunch of sessions over the years on beginning XNA game development but for the Orlando Code Camp I did a major revamp of the presentation and created a new set of demos which build upon each other to make a great start to a game, at least as much as can be covered in an hour.

I have packaged up the powerpoint presentation, very detailed demo script, and source code and made it available here:

http://www.billreiss.com/wp-content/uploads/2012/04/XnaWp7GameDev.zip

The topics include drawing 2D sprites, frame based animation, handling input, playing sounds, and using the Microsoft ad control.

Feel free to reuse all or part of the presentation and demos, my only request is that if you re-present or publish anything that you provide proper attribution and a link to http://www.billreiss.com