1
2
3
4
5
6

Creating a Windows Phone 7 XNA Game in Landscape Orientation

Update 07/14/2010: With the latest Beta release of the Windows Phone 7 Tools there is now built in support for landscape games in XNA Game Studio 4.0. I just put it into my landscape game and it works great - it even automatically supports both landscape directions. Check out this article for details.

I've been working on a game in Silverlight for Windows Phone 7 (WP7), but I have started thinking I should have gone the XNA route. I am now trying to recreate the game in XNA so that once I can get my hands on a device I can figure out for certain if the Silverlight version can perform as well as the XNA version for what I'm trying to accomplish.

In getting started in XNA it took me a bit to figure out how to draw my sprites and game in the landscape orientation on the phone. I also thought it was a bit tough to add a frame per second counter, something I heavily rely on when developing for Silverlight - this blog entry will show how to accomplish both.

How to create a landscape game in XNA for WP7
Keep in mind that according to this article by Shawn Hargreaves there will eventually be built in support in WP7 for handling the landscape orientation - this solution is just a temporary solution until then. Also, keep in mind that things like the X and Y positions for mouse and touch events will need to be inverted as well to support landscape.

First, we are going to create a RenderTarget2D - this is basically a buffer we are going to render everything to before rendering this buffer to the screen at a 90 degree rotation. We also want to define variables for the width and height of the game window instead of relying on GraphicsDevice.Viewport since we are flipping the X and Y coordinates to make the game landscape.

private RenderTarget2D renderTarget; // what game world is rendered on before being rotated
private int GameWindowWidth; // the width of the game window we are rendering to 
private int GameWindowHeight; // the height of the game window we are rendering to

Setup the GameWindow variables in the Initialize() method:

GameWindowWidth = graphics.GraphicsDevice.Viewport.Height;
GameWindowHeight = graphics.GraphicsDevice.Viewport.Width;

Initialize our RenderTarget variable in the LoadContent() method:

renderTarget = new RenderTarget2D(GraphicsDevice, GameWindowWidth, GameWindowHeight, false, 
    SurfaceFormat.Color, DepthFormat.Depth16);

(click 'read more' to keep reading..)

The only other major change is to the Draw() method, there will now be two draw passes. The first draw pass is your normal drawing, except now you are targeting the RenderTarget buffer. The second draw pass is drawing the RenderTarget buffer to the real screen, but with a 90 degree rotation - this is what makes the screen render in landscape.

protected override void Draw(GameTime gameTime)
{
    // -------------------------------------
    // -- render to the render target buffer
    // -------------------------------------
    GraphicsDevice.SetRenderTarget(renderTarget); // set our target to buffer
    graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

    spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);

    // TODO:: do all your normal drawing here

    spriteBatch.End();

    // -------------------------------------
    // call the base Draw() method 
    // -------------------------------------
    base.Draw(gameTime);

    // -------------------------------------
    // -- draw the render target buffer to the screen with 90 degree rotation
    // -------------------------------------
    GraphicsDevice.SetRenderTarget(null); // set our target to screen
    spriteBatch.Begin();

    spriteBatch.Draw(renderTarget, new Vector2(240, 400), 
        null, Color.White, MathHelper.PiOver2,
        new Vector2(400, 240), 1f, SpriteEffects.None, 0);

    spriteBatch.End();
}

Adding a frame rate counter to a WP7 XNA game
Unfortunately, unlike Silverlight, there are no built in frame rate counters in XNA. In order to display a frame rate you must keep track of the total elapsed time of the game, how many times the Update() method has been called, and calculate your own frames per second (FPS).

Luckily this has been written about in a couple of places. The attached code sample includes a FPS component based on the link above that has had the few necessary tweaks to make it work on WP7. The basic jist is that there is a component named FPSComponent based on DrawableGameComponent which you can add to your game in the Initialize() method like so:

FPSComponent fps = new FPSComponent(this, GameWindowWidth, GameWindowHeight);
this.Components.Add(fps);

The code sample attached to this post is a modified version of the "Hello XNA Framework Sample" project on the Code Samples for Windows Phone page - it was modified to support drawing a few hundred images to test out performance.

Hopefully this blog article will be a good reference for someone else dabbling in XNA for WP7 - I'm guessing it won't be a bad idea to know a bit about the strengths of each.

AttachmentSize
HorizontalGameWithFPS.zip270.74 KB

Comments

i'm an absolute xna/wp7 beginner, so excuse me if i'm wrong, but i found that the frame rate calculation code had to be moved from update() to draw() in FPSComponent.cs in order to show the real frame rate (in terms of screen redraws)