This morning, at 8:11 a.m., I downloaded and installed the Windows Phone 7 developer tools from here:
http://developer.windowsphone.com/
Less than 12 hours later, I am writing a tutorial on it. AND, I fit in a 5 mile run, a haircut and shower, a trip to the library and grocery shopping in there too. That’s gotta say something about how easy it is to get up and running with this stuff. Either that or I’m just freaking brilliant, and my wife insists that’s not the case.
One of the best ways I know to learn something is to teach it. That’s the REAL reason I write books and blog. Secret is out. Back in 1999 or 2000 I did my first “gravity tutorial” for Flash 5. It got downloaded a gazillion times and translated into at least 3-4 languages. I’ve repeated it a few times when I’m learning a new language, most recently with the iPhone stuff almost 2 years ago. So here we go.
Basics
OK, so what is Windows Phone 7, how do you get it, how do you start coding for it, etc.
WP7 is a new OS that will soon be out on a number of phones from different manufacturers and available on multiple carriers. It’s a pretty radical departure from anything else that’s out there. If you’ve seen a Zune HD, it’s kind of like that. In general, at first, I was like, “meh”. But I kept hearing about it and each report was glowing, raving. Most reviewers said things along the lines of how they were actually surpised or shocked at just how good it was. Another common thread was that it seemed ok at first and they kept waiting for that moment when they realized it really sucked, but that moment never came. I have not had my hands on a real WP7 device yet, but I’ve been getting more and more intrigued.
Rumor has it that WP7 will launch in October. Stay tuned for some announcements in the next few weeks. Jus the other day, Microsoft released the WP7 developer tools. This is a new, free version of Visual Studio 2010 Express just for making WP7 apps and games. Download it at the above link and install it and you are ready to go. There is also a developer program just like Apple has. For $99 a year, you can submit your apps for approval and get them distributed in the WP7 app store. But you can start developing now for free. The tools include a WP7 simulator just like Android and iOS tools, which is good since hardly anyone has a real device in their hands yet.
WP7 tools allow you to make two types of programs for the phone: apps and games. Apps are generally created with a XAML based UI (Silverlight) and C# code. Games are created with the XNA Game Framework. I think it’s very great that they separated out the two major types of programs that people will be making and gave them two different frameworks, each suited to the task. Both Apple and Google cater toward the app side of things, leaving game developers to come up with their own game framework, or use a 3rd party one. This tutorial will be using the XNA game framework.
START!
OK, what the hell are you waiting for? Start up VS 2010 Express and let’s code! When you get it open, hit File/New Project to open up the new project dialog.
(some of these images are shrunk down, click to see full version.)
You want to choose an XNA Game Studio 4.0 project type, then the Windows Phone Game (4.0) template. Give it a name like GravityTutorial, save it wherever you want, and hit OK. This should create and open up your project, with the main class file ready to go.
But before we even look at code, let’s look at the Solution Explorer panel. Open it if you don’t see it. Dig around the menus. You’re a smart kid, you’ll find it. The Solution Explorer is like Groups and Files in XCode, or Project Navigator or whatever it’s called in Flash Builder. You can view all your files and assets, etc. Here’s what it should look like:
Notice that this solution has two projects: GravityTutorial and GravityTutorialContent. The first one is where your actual game will be coded up. The content project is just that – you dump any asset in there that you want to use at run time. They are delivered with the app, and then loaded in when the program starts up, or later, depending on your needs.
We’ll need something to move around, so I created a ball. It is my gift to you:
Save this anywhere on your computer, then right-click on the GravityTutorialContent project and choose “Add/Existing Item…”. Browse to the ball.png image and select it. Note that it is now listed in that project. Then select the ball.png item in the Solution Explorer and open the Properties panel. You should see a field named “Asset Name” with the value “ball” in it. This is very important, because it is what you will use to load the image and display it in your code. Think of it as the linkage ID in Flash.
OK, we have our asset imported, now let’s code.
What’s in a Game?
Your project should have opened up with the Game1.cs file ready for editing. This is the main class file that starts and runs your game. Let’s take a look at what’s in it.
First, we have the constructor.
[csharp]public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = “Content”;
// Frame rate is 30 fps by default for Windows Phone.
TargetElapsedTime = TimeSpan.FromTicks(333333);
}[/csharp]
This just sets up the graphics device, tells the game where to load its content from and sets the frame rate. Generally, you probably want to leave this as is.
Next is the Initialize method.
[csharp]///
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
///
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}[/csharp]
Pretty self-explanatory. Here’s were you set stuff up for the class, rather than the constructor. Note that in many of these overriden methods, the base (super) method is called at the end of the method.
After the constructor is called, the Initialize method is called, and then the LoadContent method. Here it is:
[csharp]///
/// all of your content.
///
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
}[/csharp]
This is where we will create the instance of the ball itself. Hold your horses though, we’re still looking this beast over…
UnloadContent. Not much to say here.
[csharp]///
/// all content.
///
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}[/csharp]
And finally, the two important ones, Update and Draw. If you’ve ever done any game programming with a game loop, you know what these are. Update runs every “frame” and executes any logic, physics, user input, etc. and updates the model. The Draw method is where rendering occurs. These two can often be in sync, with one running right after the other, but having them separate allows them to run at different rates if need be. Read up on game loops to see why that might be a desirable thing. Anyway here they are:
[csharp]///
/// checking for collisions, gathering input, and playing audio.
///
/// Provides a snapshot of timing values.
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);
}
///
///
/// Provides a snapshot of timing values.
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
base.Draw(gameTime);
}[/csharp]
Update checks if the back button has been pushed, and Draw clears the screen. Everything else is up to you. OK, now we are ready to write some code.
By the way, you can build and run the game right now by pressing F5. It should launch the simulator and show you a blank, blue screen. You can play around a bit with the simulator too, to see how Windows Phone 7 will look.
Loading and Drawing a Texture
OK, we need to load in the ball image and display it somewhere on the device’s screen. The image will be stored in an object of type Texture2D. The place where we will draw it will be a Vector2, which is like a Point in Flash, or a CGPoint in Objective-C. Let’s make class variables for these two things. Right after the definition of the class you’ll see a couple of variables declared. Add our two right after:
[csharp]public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D ball;
Vector2 position;
[/csharp]
Now we need to load the image into the texture. Where do we do that? Yup, in the LoadContent method. We can initialize the position here as well.
[csharp]protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
ball = Content.Load
position.X = 100;
position.Y = 100;
}
[/csharp]
The default has already created something called a SpriteBatch for us. This “enables a group of sprites to be drawn using the same settings,” per the documentation. That’s all you have to know for now. After that we load our image with the Content.Load method. This method can be used to load all kinds of assets, so you tell it what type to load using the angle brackets. This will look familiar to you if you’ve used the Vector class in AS3, or generics in any other language. You pass it the Asset Name you saw in the property inspector earlier, “ball”. Since Vector2 is a simple struct, it is initialized to a 0, 0 point when declared. We can just set its x and y to whatever we want here.
Now we have our graphic loaded. Time to render it. As you may guess, we do that in the Draw method. Here’s the code for that:
[csharp]protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(ball, position, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}[/csharp]
We do the drawing via the spriteBatch object we created in the LoadContent method. The pattern is Begin, Draw, End. SpriteBatch’s Draw method has 7 different implementations. The simplest one takes a texture, a position and a color. The color is used to tint the object being drawn. Passing in Color.White results in no tint. Other than that, it’s pretty clear: we’re drawing the ball at such and such position.
At this point you should be able to hit F5 and run the game in the simulator. By default, games will run in landscape mode. There are buttons on the sim that allow you to rotate the device. You should see something like this:
OK, that’s about enough for one post. We have a graphical asset loading in and being displayed on the screen at a specific location. Not bad. In Part II we’ll get it moving.