Click here to Skip to main content
15,867,686 members
Articles / Mobile Apps / Windows Phone 7

BounceBall - XNA Farseer Magic

Rate me:
Please Sign up or sign in to vote.
4.97/5 (72 votes)
12 Apr 2011CPOL62 min read 191.9K   19K   119   52
In this article we are going to develop a game using Farseer Physics Engine and XNA for Windows Phone 7. This article provides you base for your games to make game development easy and fast.

From childhood I want to build games, and today technology has become so easy to utilize that we can create simple games very easily. This article is one of the attempts to build a reusable component based game framework which reduce the time required to build games based on physics and XNA. 

Figure1.png
DOWNLOAD SOURCE CODE

Contents

WHO, WHAT, WHERE AND WHY? 

You can skip this section if you are very eager to see things in action.

Who this Article for? This article, written to accommodate developers new to building mobile games, as well as those who have built mobile applications using XNA. In order to get the most out of this Article, it is recommended that you have at least a good understanding of C# and the.NET Framework & some knowledge of Microsoft XNA Game studio. If you are new to Farseer Physics Engine, don’t be afraid, I started learning Farseer alongside this game.

What the hell I’m reading? Games for Windows Phone have a unique set of requirements and challenges that need to be addressed. Through the course of this Article, you will learn how to structure your application so as to provide a consistent and reliable experience to user. And for developer this article gives many reusable but very required components which a Game must have. 

Why this Article? I have many game Ideas for Windows Phone 7 and want to make them happen but when I started with the XNA and Farseer Physics Engine, I could not figure out optimum and productive way to build games fast and easily. Like there is no clear framework or reusable code available under one roof. So I started collecting/building the basic building block of any game. And after assembling everything in one project it seems very easy to work with the XNA and Farseer Physics Engine. So this article will give you power to build games within few days or even hours.

What you will need? (Prerequisites) All the tools which we used are free to use.
Microsoft Visual Studio 2010 Express for Windows Phone
GIMP, The GNU Image Manipulation Program
Farseer Physics Engine

What that means? (Conventions)
//REMEMBER// Do not forget this.
//NOTE// General information apart form the article.

Where is Source Code? Below are the download links, for main game source, 3 demos, FarseerPhysicsXNA dll and code snippets.

GAME OVERVIEW 

I think we should be clear with what we are going to build and then we will build the actual codebase and discuss the problems of choosing one option over other. So we will be building very simple but quite addictive type of game, in which player just have to control the left and right movement of the subject which jumps every time it hits the ground. For forward movement, we will be using constant scrolling method in which player can’t control the movement or speed of the game. This kind of movement puts extra bit of difficulty in game play and after all game should attract every level of gamer (novice, average and experienced), so we will be building different levels with different set of difficulties. About the goal of the game, it is survival and not only survival, player need to score more by taking risk of collecting rewards point (we need to think how we implement it) So that’s it, this is our idea. From the above thoughts you can think of the basic stuffs which needs to be there like some level selection and game play area (hence screen system), physics (Farseer Physics objects), buttons to get the player input for left and right movement, scoring system (after all it is a game, they requires some goal and our game’s goal is to score as much as player can).

Farseer Physics Engine 3.2 & XNA 4

What is Physics Engine and why we need one?

Physics engines makes objects move in believable ways and make them obey real world like physics rules. From the game's point of view a physics engine is just a system for procedural animation. 

We can build one by our own, at the end in our game we don’t need too much control over object’s physics properties, but we are aiming at fast and reliable way of building game, so rather than building, we will use existing, ready to use and tested code as physics engine. Hence Farseer Physics Engine (v3.2). 

Background of Farseer Physics Engine 

Farseer Physics Engine is a C# port of Box2d. Box2D is a 2D rigid body simulation library for games. Farseer Physics Engine is a collision detection system with realistic physics responses. Let’s go through its fundamentals first.
To work with Farseer Physics engine you need to know 4 things as described below:

1. World: This is the object which contains everything; you can compare it with real world. It has gravity, bodies, contacts, fixtures etc. Its Step method moves objects and make sure everything is consistent and stable.

C#
//Creates a new World with Gravity of 10 in downward direction.
World MyWorld = new World(-Vector2.UnitY * 10);

2. Body: Just like real world, forces get applied to body. But unlike real world they don’t have any structure or shapes by default. Body tracks position in world, and affected by the impulse from collision or gravity. Below are the details about the body types.
StaticBody: This kind of body doesn’t move under simulation, they don’t collide with other static or kinematic bodies. If user (developer) wants to move them then it is possible to do so.
KinematicBody: It moves under velocity applied to it when simulating. Kinematic bodies do not respond to forces. User can move them manually but mostly moved using setting its velocity. They don’t collide with other static or kinematic bodies.
DynamicBody: A dynamic body is fully simulated body. It always has non-zero finite mass. It can collide with any type of bodies.

C#
/* Creates a new Static Body and add to Current World object so that it can be updated by engine. We will see a better and easy approach of doing the same using Facotries. */
Body MyBody = new Body(World);
MyBody.IsStatic = true;

//REMEMBER//
If we pass world as parameter to body creation then body will be added to world automatically and we no need to add it manually.

3. Shape: It is 2D structure of Body, like how much space object occupies in world, ex: Polygon, Square, Circle etc. It requires to calculate the inertia, mass, centroid and related stuffs. Shapes can be used independently without Body. In short body has position and velocity and can experience force, impulse, and torque.

C#
/* Creates a new Circle Shape with Radius 10 and Density 25. We will see a better and easy approach of doing the same using Facotries. */
CircleShape MyCircle = new CircleShape(10, 25);

4. Fixture: It is the glue between Body and Shape. Fixture binds Shape to Body, also provides properties like friction, restitution (bounce-ability, I guess), density etc. This binding is such that Centroid of shape becomes Body’s position. It is the fixture which provides collision related functionality, like when shapes collide; it passes force to body and hence move the shape alongside.

C#
/* Creates a new Fixture which binds provided Body and Shape. We will see a better and easy approach of doing the same using Facotries. */
Fixture MyFixture = new Fixture(MyBody, MyShape);

Other than above 4 main part of Farseer Physics engine we have Joints, Factories and PolygonTools to help us do things easily, as described below.

Joints: This is a constraint to hold two or more bodies together. Typical examples in games include ragdolls, teeters, and pulleys. Joints can be combined in many different ways to create interesting motions. There are many types of joints, like Angle Joint, Distance Joint, Friction Joint, Revolute Joint, Gear Joint, Line Joint, Prismatic Joint, Pulley Joint, Revolute Joint, Slider Joint and Weld Joint.

C#
/* Creates a new Fixture which binds provided Body and Shape. We will see a better and easy approach of doing the same using Facotries. */
AngleJoint MyJoint = new AngleJoint(BodyA, BodyB);

Factories: Factories makes our life easy by providing way to create common type of objects. There is factory for Body, Shapes, Fixture, Joints and Paths. Each object type has its own static Factory, with many overloads to provide full flexibility while creating them. We mainly used BodyFactory and FixtureFactory in our Game. Below are some of the samples for Factories.

C#
//Create Body which gets places at Origin.
Body MyBody = BodyFactory.CreateBody(MyWorld, Vector2.Zero);

//Create Circle Fixture with 10 Radius and 25 Density.
FixtureFactory.CreateCircle(MyWorld, 10, 25);

PolygonTools: This class helps us create all sorts of Polygons. Using this class we can create Rectangle, Rounded Rectangle, Edge, Circle, Ellipse, Capsule and Gear. Sample usage is shown below:

C#
//Generate Vertices for Rectangle of 10x5 dimensions. We can use the same approach for more complex objects.
Vertices vert = PolygonTools.CreateRectangle(10, 5);

//Create Fixture for Vertices collected in last step and binds the shape generated from Vertices to some Body.
FixtureFactory.CreatePolygon(vert, 10, MyBody);

Up to now we have created World, added body to it, created shapes using different ways, connected bodies by Joints and added fixture to bodies too. This is all Farseer Physics engine at heart; no doubt we need to have more understanding than this to build complex object and large game but this is more than enough to start playing around with it.

Rendering Farseer Physics object in XNA (RenderXNA)

In this section we actually see some working code and fundamental behind the positioning of objects on world. First we need to understand how object’s measurements are considered in Farseer Physics Engine.

Understanding Farseer Physics Engine’s Measurements
Farseer is port of Box2D Engine, in Box2D, if we want to create rectangle then we tell system half width, half height and centre point of the shape. Same measurement system ported to Farseer Physics Engine too. In Silverlight or other .net application we try to create rectangle by specifying its top-left corner position and then providing information about the Height and Width. But that is not the case with the Farseer Physics Engine, so remember always the Position of a Physics object always tells us the centre point not the top-left corner, but Height and Width should be supplied full not half as we have with the Box2D, that is one exception.
Now if you want to create rectangle of 10x10 units and specify the same in the Farseer Physics object then you will end up with very large object, because Farseer Physics uses meters as its units. So we need to always use very low sizes or need a converter which converts our pixel value to meters. I like to go with converts, because it will allow me to think in pixels only throughout the application, hence remove the hassle to remember what goes in pixels and what needs to be in meters. So we need to choose a conversion ratio, like 1 meter = 15 pixels or something like that. This ratio will be used throughout the application to convert Display units (pixels) to Simulation units (meters).
Lastly rotation in Farseer Physics Engine takes radian units, so be sure to convert your Rotation amount (Degree) to Radian before assigning to Physics objects.

Usage Demo for Farseer Physics Engine
So far, we have physics objects, we know what measurements we need to follow, but there is no UI related stuff, because Farseer is physics engine not UI generator. Hence if we go ahead and create a body in world we can’t see anything on screen even if the body is there. To make Farseer physics objects to appear on screen we need to draw them using XNA. We can use Draw and DrawText methods from SpriteBatch class to render texture and text on screen. Below is sample to draw Rectangle (Square) of 10x10 size and fill it with MyTexture texture.

C#
SpriteBatch.Draw(MyTexture, new Rectangle(0, 0, 10, 10), Color.White);

So let’s build one sample to make a rectangle fall, because of gravity, on floor.
Fire up Visual Studio 2010 Express for Windows Phone, create new project, and select XNA Game Studio 4.0 from templates and Windows Phone Game (4.0) from project template and name it FarseerXNADemo1. It will give you 2 projects, first one is XNA project and another one is content project to manage resources (like Images, Sound, Fonts etc).
- First we need to reference to the Farseer Physics Engine for WP7 dll (can be found on http://farseerphysics.codeplex.com at Download tab). Now we need to get some texture (by texture we are referring to images) which will be rendered, but we are ok with the simple colors too so I’m going to add blank png Image (blank.png) to Content project. After following above step our solution explorer will look like below.
Figure2.png
- Now go to Game1.cs file and set screen’s Height and Width using flowing code,

C#
public Game1()
{
	Window.Title = "DEMO 1";

	_graphics = new GraphicsDeviceManager(this);
	_graphics.PreferredBackBufferWidth = 480;
	_graphics.PreferredBackBufferHeight = 800;
	_graphics.IsFullScreen = true;

	Content.RootDirectory = "Content";
}
- We first set the title for the window then we create a new object of GraphicsDeviceManager using current Game class’s instance. Now we assign width with 480 and height with 800, because we want our phone to be in portrait mode. Also we are developing game so we don’t want to show battery or connection related stuff on upper part of the phone, hence Full screen flag is turned on. (Note that sometimes it is good practice to show battery details, otherwise player might exhaust full battery while playing and phone suddenly gets switched off, which can be annoying).
- In same file Declare one Texture2D object named MyTexture, one World object named MyWorld and 2 Body objects named BoxBody and FloorBody.
- In the Initialize method, initialize all 4 objects declared in previous step by assigning physics related properties to them. Like,
C#
Texture2D MyTexture;
World MyWorld;
Body BoxBody, FloorBody;

protected override void LoadContent()
{
	// Create a new SpriteBatch, which can be used to draw textures.
	spriteBatch = new SpriteBatch(GraphicsDevice);
	
	base.LoadContent();
	
	//Load Blank Texture so that we can render colors over it.
	MyTexture = Content.Load<Texture2D>("blank");
	
	//Create New World with gravity of 10 units, downward.
	MyWorld = new World(Vector2.UnitY * 10);
	
	//Create Floor
	Fixture floorFixture = FixtureFactory.CreateRectangle(MyWorld, ConvertUnits.ToSimUnits(480), ConvertUnits.ToSimUnits(10), 10);
	floorFixture.Restitution = 0.5f;        //Bounceability
	floorFixture.Friction = 0.5f;           //Friction
	FloorBody = floorFixture.Body;          //Get Body from Fixture
	FloorBody.IsStatic = true;              //Floor must be stationary object
	
	//Create Box, (Note:Different way from above code, just to show it otherwise there is no difference)
	BoxBody = BodyFactory.CreateBody(MyWorld);
	FixtureFactory.CreateRectangle(ConvertUnits.ToSimUnits(50), ConvertUnits.ToSimUnits(50), 10, Vector2.Zero, BoxBody);
	foreach (Fixture fixture in BoxBody.FixtureList)
	{
	    fixture.Restitution = 0.5f;
	    fixture.Friction = 0.5f;
	}
	BoxBody.BodyType = BodyType.Dynamic;
	
	//Place floor object to bottom of the screen.
	FloorBody.Position = ConvertUnits.ToSimUnits(new Vector2(240, 700));
	
	//Place Box on screen, somewhere
	BoxBody.Position = ConvertUnits.ToSimUnits(new Vector2(240, 25));
}
- Let’s explore each line at once (for more information about the ConvertUnits class, see section “ConvertUnits”). The very first line in Initialize method loads texture and save it in object for later use. Then we create a new World with downward gravity of 10 units. After, we creates floor Body, by creating its shape and fixture using FixtureFactory.CreateRectangle method. It creates rectangle of viewport width and 20 unit height. It also creates correct shape and body for it to. Then we set the Restitution and Friction property of floor and finally save the body object for later use.
- We can use the same approach to create physics object as we used with the floor creation but I want to show you other ways too, so we will create Box with little different code. We first create a body and if we pass world’s object into constructor then we are adding that body to world at the same time. Then we create fixture, hence it will create shape and bind it to body (note that we passed BoxBody as parameter this time in CreateRectangle method). Then we provide restitution and friction values to fixtures of body. Last line in Box creation is to set correct body type. We want to move Box under gravity so we make this object as Dynamic type.
- Uptill now we have created Floor and Box, now we need to position them on screen, floor needs to be placed just by the bottom screen and Box can be placed somewhere at top.
- ConvertUnits: This class is used to convert units (measurements) from Farseer Physics Units (meters) to Display Specific Units (Pixels). We have used ratio of 16 units, so for us 1 meter = 16 pixels. Good Enough ratio to work with screen of 800x480 pixels. There are 3 static methods and many overloads in this class, methods are described below:
ToSimUnits – This method convert supplied values to Simulation units, means Display Units (Pixel) to Simulation Units (Meter).
ToDisplayUnits – This method convert supplied values to Display units, means Simulation Units (Meter) to Display Units (Pixel).
SetDisplayUnitToSimUnitRatio – This method allows application to set any conversion ratio for Display Units to Simulation Units. Use it wisely because setting the ratio may result in unexpected behavior of physics objects, like very heavy massed objects with relatively small dimension, or something similar irregularity.
//REMEMBER//
In Farseer Physics measurements are in meters not in pixels. And position signifies centre point of object not the top-left corner.
- After doing the physics related stuff we need to draw these objects using XNA. For that we add following code in Draw Method.
C#
protected override void Draw(GameTime gameTime)
{            
	GraphicsDevice.Clear(Color.CornflowerBlue);
	
	spriteBatch.Begin();
	
	//Draw Box, its Height is 50 and Width is 50.
	spriteBatch.Draw(MyTexture, new Rectangle((int)(ConvertUnits.ToDisplayUnits(BoxBody.Position.X) - 25), (int)(ConvertUnits.ToDisplayUnits(BoxBody.Position.Y) - 25), 50, 50), Color.Green);
	
	//Draw Floor, its Height is 10 and Width is 480.
	spriteBatch.Draw(MyTexture, new Rectangle((int)ConvertUnits.ToDisplayUnits(FloorBody.Position).X - 240, (int)ConvertUnits.ToDisplayUnits(FloorBody.Position).Y - 5, 480, 10), null, Color.Gray, FloorBody.Rotation, new Vector2(0, 0), SpriteEffects.None, 0);
	
	spriteBatch.End();
	
	base.Draw(gameTime);
}
- We use Draw method of SpriteBatch class. While drawing Box, we provide texture, and the destination rectangle in which we want to render the box (in short the dimension of the Box). First and second argument to the Rectangle is the top left corner coordinate (recall that Farseer stores centre point as position, so we need to subtract half width and half height from the position to get the top left corner). Next 2 arguments for rectangle are the width and height respectively. The same approach is used with the Floor object.
- If you run the project now you will see the box and floor, but box doesn’t fall in impression of gravity. This is because we are not updating the World, means we are not moving world to next step. For that add code to Update method, and it will look like below,
C#
protected override void Update(GameTime gameTime)
{
	// Allows the game to exit
	if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
	this.Exit();
	
	// variable time step but never less then 30 Hz
	MyWorld.Step(Math.Min((float)gameTime.ElapsedGameTime.TotalMilliseconds * 0.001f, (1f / 30f)));
	
	base.Update(gameTime);
}
- In above code note the Step method, it will move world forward with 30 or more updates per second. Now if you run the project you will get the box falling under the impression of gravity.
Figure3.png
- Now you might be thinking that it is so easy to integrate Physics objects with XNA, and I thought the same but if you try to rotate, transform and combine more Shapes in one Body you will have to figure out how exactly that body should be drawn on screen, And believe me that is not as easy as it seems, also it will consume a lot of time to figure out exactly how to draw objects in a generic way. So where should we go….? Answer is DebugDraw.

DebugDraw (RenderXNA) 

- DebugDraw is the facility provided by Farseer Physics Engine to draw object data on screen while we are in development stage, this will help you visualize bodies, joints, fixtures and more. I thought why we can’t use the same in real applications. And could not find any good enough reason to stop myself by doing so. Hence we have a project named “RenderXNA”.
- This project contains three classes, RenderMaterial, Materials and RenderXNAHelper. RenderMaterial class is the data structure we need at the time of rendering the object. Materials class is the helper class to manage the loaded textures, so that don’t load textures again and again. And finally the RenderXNAHelper class, this is the main class which derives from FarseerPhysiscs.DebugView class and IDisposable interface. We use this class to render objects instead of writing our own code to draw objects. If you look into code you will find many methods like DrawJoint, DrawShape, DrawPolygon, DrawCircle, DrawTexturedLine etc, and these methods actually draw our objects. RenderXNAHelper uses World.BodyList to get all the available Bodies for rendering.
- RenderXNAHelper originated from the DebugViewXNA.cs file from DebugView source code of Farseer Physics Engine. I changed it to use materials outside of the project. Simple enough to get it working in considerable less time than building our own code to do so.
- Ok, time for a sample code to use the RenderXNA project. You can find the RenderXNA.dll in the source code provided; add reference of it to our first demo project FarseerXNADemo1.
- We also need Camera2D class, which I have found in one of the sample. It works just like the real camera, we no need to look into the code to use it (even I don’t know much of the stuff). Useful methods in Camera2D class are ConvertScreenToWorld and ConvertWorldToScreen methods, these methods convert Screen Points (actual points) to World Points (system points) and vice versa respectively. We also have Projection and View as properties of type Matrix; they are used to represent Current Camera Projection and Current View frustum of the Camera respectively. This class also contains Update method which needs to be called in the Update method of XNA Game class. That is all we need to remember about the Camera2D class.
- After having Camera2D class in place we can go further with the sample implementation. Go ahead and add a new class named Game2 and derive it from Microsoft.Xna.Framework.Game class. Its constructor will look just like the Game1 class which we already have in project. Also declare same class level variables (as we have in Game1) in Game2 class. Apart from that we need to have 2 more variables for Camera2D class and RenderXNAHelper class. We need three methods namely LoadContent, Update and Draw, so override them first. Initialize both Camera2D and RenderXNAHelper object in LoadContent method, shown below. First copy the whole LoadContent method from Game1 class and add following code in LoadContent method just after the creation of World object.
C#
//Create DebugView and switch on the Flags to render shapes.
RenderHelper = new RenderXNAHelper(MyWorld);
RenderHelper.AppendFlags(DebugViewFlags.TexturedShape);
RenderHelper.RemoveFlags(DebugViewFlags.Shape);

RenderHelper.DefaultShapeColor = Color.White;
RenderHelper.SleepingShapeColor = Color.LightGray;
RenderHelper.LoadContent(GraphicsDevice, Content);

Camera = new Camera2D(GraphicsDevice);
- We also need to add texture details to the Physics object itself, because now they are going to be rendered by RenderXNAHelper. Fortunately we have an argument of type object in CreateRectangle method of FixtureFactory (almost all Factory method have this provision and argument is named as UserData), that can be used just like TAG property which we have in most of the .net controls. So we can assign texture, color etc details in it, for that we use RenderMaterial’s object. Sample of that look like below,
C#
new RenderMaterial(MyTexture, "Blank") { Color = Color.White }
- Above code will render MyTexture’s Image with color White (White color means the texture gets rendered with its original image colors, other than White means that Image will have Mask over it of the same color).
- So add new RenderMaterial object as last parameter to FixtureFactory.CreateRectangle method for both Floor and Box Fixtures.
- After adding above code we need to add code to Update and Draw methods, and they will look like below,
C#
protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();

    if (MyWorld != null)
    {
        // Update the camera
        Camera.Update();

        // variable time step but never less then 30 Hz
        MyWorld.Step(Math.Min((float)gameTime.ElapsedGameTime.TotalMilliseconds * 0.001f, (1f / 30f)));
        RenderHelper.Update(gameTime);
    }

    base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    if (MyWorld != null)
    {
    //Render the Data
        RenderHelper.RenderDebugData(ref Camera2D.Projection, ref Camera2D.View);
    }

    base.Draw(gameTime);
}
- To run this new Game class we need to set it as startup type from Project Properties.
Figure4.png
- Also we need to add one font and line material for default rendering. So now our content project will look like below,
Figure5.png
- Run the project now and you will be treated with the same screen as we have with the Game1. That’s all we need to have the same experience as with the manual Draw of objects. Note that we are not rendering any object in Draw method instead that responsibility have been shifted to RenderXNAHelper class. This will remove most of the problem which we have with the rendering objects on screen.

On closing note to this section we have our Physics objects; we can draw them and can provide textures, color and other details. Full sample code for the FarseerXNADemo1.

LET’s DIG & PUT A BASE (WINDOWS PHONE 7 XNA GAME BASE)

Uptill now we only concentrated on Physics, but a game needs much more than just physics engine, it requires panels (normal and scrollable), buttons, labels and Image controls which can be placed inside panels so that making them scrollable, background control (like Parallax background), Border control, Input handler, font and texture manager, frame-rate counter and on all a base screen model on which we can create new screens of game as easily as possible with minimal of code. We will create each of these things one by one starting from FameRate counter. (Note that I have employed different way of creating and using these reusable components just to show you what are the ways we can have while creating reusable controls.)
For this section we are referring to the FarseerXNABase project.

ScreenSystem 

Screen System, a question might arise in your mind that why screen system, we have classes and each class will draw or do its related work, like instruction class will draw instructions on display. Good enough but using screen system we can have more control over when, how and which screen (class) gets the control of the display. So our first task is to have a way to add, remove screen, but before that we need to have a class for screen. 

GameScreen
A screen is a single layer that has update and draw logic and which can be combined with other layers to build up a complex menu system. For instance the main menu, the options menu, the “are you sure you want to quit” message box and the main game itself, are all implemented as screen. We have one base class called GameScreen in FarseerXNABase/Components/ScreenSystem folder. It is an abstract class which will be used in every screen as base. Let’s explore its properties and methods.
Figure6.png
ControllingPlayer: Gets the index of the player who is currently controlling this screen or null if it is accepting input from any player. This is used to lock the game to a specific player profile. The main menu responds to input from any connected gamepad, but whichever player makes a selection from this menu is given control over all subsequent screens, so other gamepads are inactive until the controlling player returns to the main menu.
EnabledGestures: Gets the gestures the screen is interested in. Screens should be as specific as possible with gestures to increase the accuracy of the gesture engine. For example, most menus only need Tap or VerticalDrag to operate. These gestures are handled by the ScreenManager when screens change and all gestures are placed in the InputState passed to the HandleInput method.
IsActive: This property shows whether the current screen is the top most or not. If current screen is in top then it will be true and all the inputs are handled by this screen only.
IsExiting: Tells that current screen is exiting or not. There are two possible reasons why a screen might be transitioning off. It could be temporarily going away to make room for another screen that is on top of it, or it could be going away for good: This property indicated whether the screen is exiting for real: if set, the screen will automatically remove itself as soon as the transition finishes.
IsPopup: Normally when one screen is brought up over the top of another, the first screen will transition off to make room for the new one. This property indicated whether the screen is only a small popup, in which case screens underneath it do not need to bother transitioning off.
ScreenManager: Will talk about it later in its own section. It will return the ScreenManager attached to current screen.
ScreenState: Screen can be in one of the 4 states, TransitionOn, Active, TransitionOff and Hidden. This property returns one of them according to the current conditions of the screen.
TransitionAlpha: It stores screen’s opacity value. Range from zero to one.
TransitionOffTime: Time-span required to transition off current screen completely.
TransitionOnTime: Time-span required to transition on current screen completely.
TransitionPosition: Tells the position of the current screen, ranges from zero (fully active, no transitioning) to one (transitioned fully off to nothing).

Draw: This is called when screen should draw itself.
ExitScreen: Makes the screen exit and start off transitions. This will not kill screen immediately, rather it will wait for the transition off time-span to complete first.
Update: Allows the screen to run logic, such as updating the transition position. This method gets called irrespective of the screen is Active, hidden or in middle of transition.
HandleGamePadInput, HandleInput and HandleKeyboardInput: Allows the screen to handle user input. Unlike Update, this method is only called when the screen is active, and not when some other screen taken the focus.
LoadContent, UnloadContent: Load and Unload graphics content for the screen.
UpdateTransition: It is a helper method to update the screen transition position. 

ScreenManager
This class manages the Adding, removing and all screen related task, like rendering screen, updating screen etc. In short it manages one or more instance of GameScreen class, call update, draw methods at appropriate time and routes the input to the topmost screen. Let’s see its properties and methods.
Figure7.png
SpriteBatch: A default spritebatch shared by all the screens. This saves each screen having to bother creating their own local instance.

AddScreen: It will add new screen to screenmanager instance.
Draw: Tells each screen to draw itself.
Update: Allows each screen to run logic.
FadeBackBufferToBlack: Helps draw a translucent black fullsccreen sprite, used for fading screens in and out, and for darkening the background behind popup.
GetScreens: Exposes an array holding all screens. We return a copy rather than the real master list, because screens should only be added or removed using AddScreen or RemoveScreen methods.
LoadContent, UnloadContent: Load and Unload graphics content.
RemoveScree: Remove screen from screen manager. You should use GameScreen.ExitScreen instead of calling this directly, so that screen can gradually transition off rather than just being instantly removed.
TranceScreen: Used in debugging, it prints list of all screens. 

Camera2D
We already discussed the usage of Camera2D class in previous sections. Now let’s explore its properties and methods in more detail.
Figure8.png
CurrentSize: A vector representing the current size of camera view. Expressed as Size * (1 / Zoom).
MaxPosition and MinPosition: The furthermost left and right a camera can go. If both the values are same then no clipping will be applied unless until you have override that method.
MaxRotation and MinRotation: It represents the maximum and minimum a camera can be rotated.
MaxZoom and MinZoom: Property represents the limitations of the zoom of a camera.
MoveRate: Represents the rate at which tracking camera moves.
Position: Current camera position.
Rotation: Current Rotation of the camera.
RotationRate: Represets how much camera can be rotated in one update.
ScreenCenter: Represents center of the screen.
ScreenHeight and ScreenWidth: Represents the Height and the Width of the current screen.
TargetPosition, TargetRotation and TargetZoom: Represents the target value of the camera to be reached. These values are checked against current values and if required makes the necessary updates every forward move.
TrackingBody: Represents a FarseerPhysics body which needs to be tracked. This body will always be in the middle of the screen.
Zoom and ZoomRate: Zoom represents the current zoom level and ZoomRate tells how much zooming can be achieved in one step forward.

ConvertScreenToWorld: It will convert the Screen position to the camera (world) position.
ConvertWorldToScreen: It will convert the world position to the screen position.
CreateProjection: It will create the Projection matrix for the camera; we need to call this method every time the screen resolution or more specifically aspect ratio changes.
MoveCamera: Move camera by specified amount.
ResetCamera: Reset the camera to its default values.
Resize: Applyupdated rotation, position and zoom value to camera.
SmoothResetCamera: Reset the camera position to default value, gradually fading from current position, rotation and zoom values.
Update: Moves the camera one step forward timestep.
ZoomIn and ZoomOut: Makes the camera zoom in and out respectively. 

InputHelper
Purpose of this class is to help in capturing the input from the User. Followings are the properties and methods available in InputHelper class. This class can also be used with Xbox.
Figure9.png
(You might be thinking why we have GamePad, Keyboard and Mouse related function in this class, while we only working with the Phone. Answer to that question is that, we will be using mouse while debugging and the same class can be used with the Xbox games too.)
CurrentGamePadState: Gets the current players Game Pad state.
CurrentKeyboardState: Gets the current players Keyboard state.
LastGamePadState and LastKeyboardState: Gets the Last gamepad or keyboard state for the current player.
MousePosition: Gives the current position of the mouse.
MouseScollWheelPosition and MouseScrollWheelVelocity: Represents the current mouse wheel’s scroll position and its velocity.
MouseVelocity: Gives us the mouse move velocity, can be expressed as current mouse position – last mouse position.

IsKeyDown and IsKeyUp: Checked whether controlling player has pressed or released a specified key or not.
IsNewButtonPress and IsNewKeyPress: Helper for checking if a button was newly pressed during this update. The controlling player parameter tells from which player to read input. And if it is null then it will accept input from any player. When the button press is detected, the output player index represents which player pressed it.
IsOldButtonPress: A Boolean indicating whether the selected mouse button is not being pressed in the current state and is being pressed in the old state.
IsPauseGame: Checks for the “Pause the Game” input action. The controlling Player parameter specifies which player to read input for. If this is null, it will accept input from any player.
Update: Reads the latest state of the keyboard and gamepad. 

PhysicsGameScreen
So far we have GameScreen which will be base class for all screens, but we also need to develop a base class for physics related screens. This base will encapsulate most of the task for us, like creating border, setting and initializing RenderXNAHelper, mouse to physics object handler etc. Below are the available methods, let’s explore them.
Figure10.png
CreateBorder: Most of the times while debugging we need to restrict the physics object from falling outside of screen, that’s why we have the CreatBorder method to create a border on the edges of the screen. There are four overloads which will further simplifies the work and allows us to customize it as per our need.
Draw: This method will draw the physics objects using the RenderXNAHelper and world object.
Update: This method just calls the world’s step method and update of RenderXNAHelper object.
EnableOrDisableFlag: It will enable or disable the debugging flags in RenderXNAHelper object.
HandleInput: Often, while debugging we need to move objects using mouse even though we are in the Windows Phone development, this method will help us doing so. Also the same method can be used to enable or disable any flag while in Xbox or Windows Game.
LoadContent: Load and initialize objects like World, RenderXNAHelper etc.
Mouse, MouseDown and MouseUp: Mouse related methods to help manipulate the physics objects using Mouse.
UpdateScreen: This method gets called when camera projection changes. We need to write all the code which needs to be updated when camera moves or changes its position. Like moving border according to the camera position. 

SpriteFont
We use this class to help with the fonts. We load all the required fonts for the game in this class, and use it throughout the application. We use this class to catch all the fonts and use it whenever we need them.

FrameRate Counter

It is the most required feature while developing a game, because if FPS (Frame rate per second) drops on certain action or after playing game for prolong time, then we can say that there must be something processing intensive work going on or we are drawing too much of data on screen. That gives us starting point to debug your performance problem. So without boring you much we will look into the code details.
FrameRateCounter class has two methods, Update and Draw and it is derived from DrawableGameComponent.
Update method checks for the elapsed time and if the timespan is more or equal to one second then updates the FPS to display and resent the counter to zero, otherwise does nothing.
Draw method always increment the frame rate counter and renders the currently stored FrameRate on screen.

Parallax Background

This component helps you scroll background for any 2D game. Parallax scrolling means scrolling different layers of images one over another any different speed, making effect of depth and distance. It can be easily understood by imagining that you are looking through a moving car towards mountains, so nears objects like trees move faster compared to the mountains situated far away. More information about parallax scrolling can be found over Wikipedia.
Now time to see some code, and then we build a demo showing the use of the same. Jump to the FarseerXNABase/Components/ParallaxBackground.cs class file.
As soon as you open file you will see many properties, let’s see usage of them first.
SpeedX and SpeedY: When we move background images, these properties determine the speed at which background is going to be moved in either direction. Default value is one for both and set to zero or one depending on the direction of the scrolling set by developer.
Height and Width: Get or set the Height and Width of the viewport in which we want to show the scrolling Images.
ScrollingTextures: It is a list of Texture2D type. We can give more than one image to scroll one after another, at the same depth level. If all images are scrolled then it will start scrolling from first image again, and repeat the process again and again.
Position: Gives the current position of the moving background. At first this property seems waste, but believe me you need this. Consider you are in a game with moving background, suddenly phone call arrives and your game tombstoned, at that time you need to know at which position background is to store it in memory for later retrieval while we resume from tombstoned state.

//REMEMBER//
ParallaxBackground component won’t work perfectly with the images of Height/Width less than the ViewPort’s Height/Width respectively. Say want to scroll image in horizontal direction in landscape phone mode, with full screen occupancy then you must have images greater than or equal to the width of the phone’s width (i.e. 800) otherwise it might fail in moving background perfectly.
We are using TextureDetails named struct to store information about the textures we want to scroll. For scrolling background we need to know how much space any image/texture is going to occupy and whether we need to render more than one texture at a time or not, all these questions required information like height, width, image/texture’s position in the belt (by belt we mean whole background with multiple images and their position by order).
The only method which requires some explanation is Draw method. Below is the code snippet of the method,
C#
public void Draw(SpriteBatch spriteBatch)
{
	//Iterate through all texture
	//If Current position fall into current texture then render it and
	//Increment the current location by width (min(texturewidth and windowWidth)
	
	float positionX = _currentPosition.X;
	float positionY = _currentPosition.Y;
	for (int i = 0; i < _textures.Count; i++)
	{
		if (this._direction == ParallaxDirection.Horizontal)
			if (positionX >= _textures[i].BeltPositionX && positionX <= (_textures[i].BeltPositionX + _textures[i].Width))
			{
				positionX += Math.Min(_textures[i].Width, this.Width);
				spriteBatch.Draw(_textures[i].Texture, new Vector2(_textures[i].BeltPositionX - _currentPosition.X, 0), Color.White);
			}
		
		if (this._direction == ParallaxDirection.Vertical)
			if (positionY >= _textures[i].BeltPositionY && positionY <= (_textures[i].BeltPositionY + _textures[i].Height))
			{
				positionY += Math.Min(_textures[i].Height, this.Height);
				spriteBatch.Draw(_textures[i].Texture, new Vector2(0, _textures[i].BeltPositionY - _currentPosition.Y), Color.White);
			}
	}
	
	//Means last texture reached and we can't reset Position to zero unless untill we completely render last texture,
	//So render first texture just by the last texture
	// |-------------|--------------------------|
	// | Last        | First                    |
	// | Texture     | Texture                  |
	// |-------------|--------------------------|
	if (this._direction == ParallaxDirection.Horizontal)
		if (_currentPosition.X >= (_textures[_textures.Count - 1].BeltPositionX + _textures[_textures.Count - 1].Width - this.Width))
		{
		spriteBatch.Draw(_textures[0].Texture, new Vector2((_textures[_textures.Count - 1].BeltPositionX + _textures[_textures.Count - 1].Width - _currentPosition.X), 0), Color.White);
		}
	
	if (this._direction == ParallaxDirection.Vertical)
		if (_currentPosition.Y >= (_textures[_textures.Count - 1].BeltPositionY + _textures[_textures.Count - 1].Height - this.Height))
		{
		spriteBatch.Draw(_textures[0].Texture, new Vector2(0, (_textures[_textures.Count - 1].BeltPositionY + _textures[_textures.Count - 1].Height - _currentPosition.Y)), Color.White);
		}
}
This method is the heart of the component. To understand this method let’s suppose we are using three different textures of 1000px width and we want to scroll in horizontal direction. So at first what should happen? Component should draw the first texture from current position which is (0,0) to (800,480) (width and height) position and rest of the texture should be clipped. Then there will be Move method call which will update the current position by the speed, this will cause the clipping region to move by speed (say SpeedX=1 and SpeedY=0) so we have current postion (1,0) and we still have height and width 480 and 800 respectively, so we draw the first texture region from (1,0) to (801,480). This thing continues until we reach position where entire screen cannot filled by first texture fully and that would be on (201,0) position, when current position reached X by 201 we have to draw second texture from (799,0) to (800,480). Rendering of first and second texture is handled by the for loop and code inside it.
Now suppose you are rendering the last texture and you know that at some point in time it will be moved so that it can’t fill the whole screen, at that time we need to start rendering the first texture just after the last point of the last texture. You can see this happening in the second part of the method. Last four if statement helps us do so.
Let’s see the parallax by example in which we will use the images from the Wikipedia and make them scroll using our game component. So first create a new project named FarseerXNADemo2 and add the images to content from folder Demos\FarseerXNADemo2\FarseerXNADemo2\FarseerXNADemo2Content. There will be 4 images for each layer. Our layers will look something like below when looked from side angle.
Figure11.png
Now add reference to the FarseerXNABase library to this project. So now our solution looks something like below,
Figure12.png
Open the Game1.cs file and remove unnecessary methods like Initialize, Unload and keep only LoadContent, Update and Draw methods.
Now define four ParallaxBackground object namely layer0, layer1, layer2 and layer3. We need to initialize these objects with images they need to scroll, scrolling direction, viewport’s height and width and speed at which we want to scroll them. Below is the snippet from the LoadContent method from the Game1.cs class.
C#
List<Texture2D> lst = new List<Texture2D>();
lst.Add(Content.Load<Texture2D>("layer-0"));
layer0 = new ParallaxBackground(lst, ParallaxDirection.Horizontal)
{
	Height = graphics.GraphicsDevice.Viewport.Height,
	Width = graphics.GraphicsDevice.Viewport.Width,
	SpeedX = 0
};

Same way we initialize all remaining 3 layers and increasing the speed in each of them gradually. Now the only code left is to call Move method of ParallaxBackground in the Update method and call to Draw method in the Draw method of Game1.cs. Run the project and switch to Landscape mode and you will see different backgrounds moving at different speed making quite realistic view on screen.

Button, Textblock, ScrollPanel, PanelControl, Border and Image Control

Almost in every game you need to have button, menu, Image, textblock etc. So I started looking over web for some startups and by my fortune found some very good controls and very nicely structured code over App Hub. I like this project because it provides me some base code to start with, like the Control class which can be extended to do much more and build almost every required component of a game’s UI. Using this project, I have created and extended controls which we need in a game. So let’s explore the Controls folder of FarseerXNABase project which contains code from the App Hub and extended controls too. 

Control Class
Control is the base class for a simple UI control’s framework. Controls are grouped into a hierarchy; each control has a parent and an optional list of children. They draw themselves too.
Call HandleInput() once per update on the root control of the hierarchy; it will then call HandleInput on its children. Controls can override HandlInput to check for touch events and the like. If you override this method then you need to call base.HandleInput to let your child controls see input.

//REMEMBER//
Controls do not have any special system for setting TouchPanel.EnabledGestures; if you’re using gesture-sensitive controls, you need to set EnabledGestures as appropriate in each GameScreen.

Override Control.Draw method to render your control. Control.Draw takes a ‘DrawContext’ struct, which contains the GraphicsDevice and other objects useful for drawing. It also contains a SpriteBatch, which will have had Begin() called before Control.Draw() is called. This allows batching of sprites across multiple controls to improve rendering speed.
Controls have a Position and Size, which defines a rectangle. By default, Size is computed automatically by a internal call to ComputeSize method, which each child control can implement as appropriate. For example, TextControl uses the size of the rendered text.
There is no dynamic layout system. Instead, container controls (PanelControl in particular) contain method for positioning their child controls into rows, columns, or other arrangements. Client code should create the controls needed for a screen, then call one or more of these layout functions to position them. 

DrawContext Class
It is a collection of rendering data to pass into Control.Draw() method. By Passing this data into each draw call, our controls can access necessary data when they need it, without introducing dependencies on top-level object like ScreenManager.
It has following fields,
Device: XNA GraphicsDevice object.
GameTime: GameTime passed into Game.Draw() method.
SpriteBatch: Shared SpriteBatch for use by any control that wants to draw with it. Being is called on this batch before drawing controls, and end is called after drawing controls, so that multiple controls can have their rendering batched together.
DraeOffset (Vector2): Positional offset to draw at. Note that this is a simple positional offset rather than a fill transform, so this API doesn’t easily support full hierarchical transform. A control’s position will already be added to this vector when Control.Draw is called.
BlankTexture (Texture2D): A single-pixel white texture, useful for drawing boxes and outlines within a SpriteBatch. 

TextControl Class
This class is used to render single line of text on screen. It is derived from the Control base class and overrides two methods, Draw and ComputeSize. This class can be easily extended to allow different text manipulation features like text wrapping, alignment, font size etc. 

ImageControl Class
ImageControl is a control that displays a single sprite. By Default it displays an entire texture. If a null texture is given, this control will use DrawContext.BlankTexture. This allows it to be used to draw solid-colored rectangles. Some of its properties are described below,
Origin: Position within the source texture, in pixels. Default is (0,0) for the upper-left corner.
SourceSize: Size in pixels of source rectangle. If null (the default), size will be the same as the size of the control. You only need to set this property if you want pixels scaled at some other size than 1-to-1; normally you can just set the size of both the source and destination rectangles with the Size property.
Color: Color to modulate the texture with. The default is white, which displays the original unmodified texture.
In Draw override method it will compute the source and destination rectangles and draw the provided texture with the color specified. 

PanelControl Class
This class arrange objects of type Controls in a row wise or column wise fashion, with the given spacing between components. It has only two methods namely LayoutColumn and LayoutRow with three parametes Margin both X and Y and Spacing of type float. This is mostly used with many child controls in it; it might or might not have any UI attached to it. 

ScrollTracker Class
ScrollTracker watched the touchPanel for drag and flick gestures, and computes the appropriate position and scale for a viewpoer within a larger canvas to emulate the behavior of the Silverlight scrolling controls. This class only handles computation of the view rectangle; how that rectangle is used for rendering is up to the client code.
This class watched for HorizontalDrag, DragComplete, and Flick gestures. However, it cannot just set TouchPanel.EnabledGestures, because that would most likely interfere with gestures needed elsewhere in the application. So it just exposes a const ‘HandledGestures’ field and relies on the client code to set TouchPanel.EnabledGestures appropriately. It’s some of the properties and methods are as described below,
CanvasRect: A rectangle (set by the client code) given the area of the canvas we want to scroll around in. Normally taller or wider than the viewport.
ViewRect: A rectangle describing the currently visible view area. Normally the caller will set this once to set the viewport size and initial position, and from then on let ScrollTracker move it around; however, you can set it at any time to change the position or size of the viewport.
FullCanvasRect: FullCanvasRect is the same as CanvasRect, except it’s extended to be at least as large as ViewRext. This is the true canvas area that we scroll around in.
Update method will check for whether we need to move the viewport (are we tracking a drag gesture) using the velocity or both X and Y direction. Also it will handle the soft clamp, means at the end of the scrolling it will stop gradually rather than a sudden jerk and used to get the partial-overdrag effect at the edges of the scroller.
HandleInput method takes one argument of type InputHelper and processes the gestures for us. We use this method to notify Update method about the gestures; we set a flag as soon as we find any touch. We can’t use gestures for this because no gesture data is returned on the initial touch. We have to be careful to pick out only ‘Pressed’ locations, because TouchState can return other events a fram after we’ve seen GestureType.Flick or GestureType.DragComplete. 

ScrollingPanelControl Class
This class is extended form of PanelControl and adds ScrollTracker to it. It overrides three methods Update, Draw and handleInput. In Update we compute the ScrollTracker’s scrollable area. HandleInput will allow ScrollTracker to take control of the inputs and respond to them if required. And last Draw method which will just adjust the offset before rendering the child controls using the ScrollTracker’s ViewRect data. 

Button Class
This class is used as button and it is derived from the Control class hence it can have child and can be added to PanelControl and ScrollablePanelControl. We used this class mostly in the menu like context. Let’s dig some code now, properties first.
Font: Font sprite to be used when drawing Display Text of a button. It is required if TextVisible is true otherwise control will throw error.
TextVisible: Boolean property to notify draw method whether to draw text on button or not.
DisplayText: String property, which holds the text to be rendered on button surface.
TextRotation: Amount of rotation should be added to display text while rendering it.
TextSize: Size of the text to be rendered. We have three sizes, Small, Medium and Large. Actually we are scaling the rendered text by 75% of its original size if Small, 100% when Medium (Default) and 125% when large.
TextAlignment: Align the text in the view area of button. It can be Left, Right or Centre (Default).
ClickAreaSpecific: We can use different display area and different sized clickable area. If this property is true then we only check the Tap gesture in the Clickable area.
ClickArea: A rectangle defining the clickable area of the button, if not specified then it will be same size as display area.
NormalButtonTexture and ClickedButtonTexture: Stores the textures for the Normal button state and clicked button state respectively. NormalTexture is required otherwise control will throw error. But you can change it to your usage way easily.
State: It is the state of the button currently. It can be Normal or clicked depending on the Tap gesture position we have.
Height and Width: Specify the Height and Width of the display area. It will be used for rendering textures as well as finding the click in case of no ClickAreaSpecific mode. Height and Width are 50pixel by default.
Foregound and ClickedForeground: Color of the font when in normal state and when in clicked state respectively. Both are Black by default.
TextWidth and TextHeight: Gets the display text width and height respectively.
TapPosition: Gives the last Tap postion.
Tag: It is used to store extra information with the Button control like in dynamically created buttons we need to know which button raised the click event so in this case we can store some meaningful information which can identify each button uniquely. It is of type object so can store anything.

We override four methods, ComputeSize, Update, Draw and HandleInput.
ComputeSize will return Width and Height values.
HandleInput: In this method we check for Tap gesture, and if found one then we need to process that Tap gesture. While processing if the Tap position is inside current Button then we remove that gesture after processing it otherwise we neglect it and do nothing. While processing we note the position of the Tap and store to be used in Update method. Then we check for the ClickAreaSpecific flag and if found then check the current Tap position against the clickable area otherwise we Display area as clickable area and check the position against it. If the Tap is outside the clickable area then we leave the method and return false so that gesture remains in the gesture list and other buttons can process it. And if Tap is inside clickable area then we change the button’s state to Clicked, rest of the things like rendering correct texture and font according to button’s state will be handled by the Update and Draw methods.
Update: If we have TapPosition set then we need to record the current ElapsedTime which will be used later for raising clicked event after displaying the clicked texture. If we don’t do this, button won’t look like button as, when user Tap on a button, clicked event will be raised and clicked texture won’t be shown for enough amount of time to be visible.
Draw: This method stores the last drawn position of the Button which will be used in the checking of Tap inside the button or not. Also it actually renders the correct texture and foreground based on the Button’s State.

Ok, enough now, it is time for Demo. We will have demo showing usage of ScreenSystem and Controls we have just explored. We will create 3 screens; out of one will be of type popup, means it will allow screens underneath it to render. Also we will use buttons, TextBlock, scrollable panel and normal panel. So go ahead and explore the code from FarseerXNADemo3 folder. Below are the screenshots from the same project. You can use back navigation button of phone to dismiss the screen.

Figure13.png

LET’S DEVELOP A GAME. READY!!!

We have most of the parts needed to create a game so let’s think of an Idea first. Simplest game concept can be a subject jumping by its own when hit the ground, player only need to control the left and right movement of the subject. We can put obstacles and reward for the subject. Aim of the game is to complete a level with the maximum points. Also we will scroll the screen at constant speed which puts more challenge in game play. About the obstacle, we will have two types of obstacle, jump through and hit-dead. Jump through obstacle allows us to make subject move in particular fashion, and these obstacle work similar to the ground and makes the subject jump. While the hit-dead obstacle serves the same purpose but makes the player to avoid them as when subject hit them level gets over. About the reward, so we can put some object which when collected by jumping subject, will increase the score by large amount hence making the player to collect them and we will put more danger with these rewards, so player have to choose whether to collect or just survive. Also we can make the hollow ground and if subject falls in it then game level gets over. Hmmmmm….. Ok, that’s all we needed.

Now the concept is ready so let’s turn on the programmer brain, we need to think how we achieve the above concept. Obviously we need some screens, like start screen from which we can collection information about game, like how to play, highscore, and navigation link to level selector screen. Next we need a level selector screen through which player can select different levels. Then the actual game screen which renders level, based on the data provided to it. Other than the screens we need some helper classes, like Assets class which will hold all the constant values for graphics, sound, and physics related constants. Also currently assume that we have game data, which includes level Name, its description and also the obstacle and other objects position in the level. And this game data is in form of XML (we will come to this and how to create levels in the Level Editor section), so first thing is to deserialize this data and keep it into memory, for that we use the same Assets class (you can find LEVEL DATA section at the bottom of the class just above the Highscore functionality). Other than Assets class we also have Serialization helper class which deserialize XML data for us and if required can read a text file too. We also have other simple classes like Entity, EntityData, Level and GameObjectData which will be used mostly as Data Structure to store level data for actual game screen. Also some enums like EntityType and GameObjectType to help us overcome the string typing errors.
Let’s explore the game screens one by one.

Start Screen 

This will be the first screen which comes up when we run the game. So it should be the root of the navigation, hence we need three menu items, Start Game which will navigate us to Level Selector screen, Instructions which will show Instruction screen popup and Highscore which will navigate to HighscoreScreen. To make things more interesting we will put some moving background and some graphics from the Game itself. So our screen will look something like below,
Figure1.png
Components used on this screen are Buttons (for menu creation), PanelControl (to hold menu items) and ParallaxBackground (obviously for moving background). We also have one Event called ExitGame which we use to notify the main Game class (FarseerXNAWP7Game.cs) that we need to shut the game down.

Instruction Screen

We need to provide details about the controls and how to play the game, so we have Instruction screen. It is not of full display size rather a popup screen. Here is the look of the instructions screen placed/opened over start screen,
Figure14.png
In this screen, we only used Buttons and PanelControl to hold it. Everything else is just rendered using normal XNA Draw and DrawString methods.

//NOTE//
Any popup in your game or in any Windows Phone 7 application should be closed when user hit the back hardware button, otherwise your application won’t pass the review process for marketplace.

Level Selector Screen

We want to create many different levels so we need to allow user to play any one of them at any time, so we need to show all the levels in one screen, hence LevelSelectorScreen. So our first task is to get levels which we already have in the Assets class, and show a Name and description of the level on a button. So we have screen something like below,
Figure15.png
Here we have used only a background image, buttons and ScrollablePanelControl (because this list can grow very large and user might need to scroll it).

//NOTE//
Before using scrollable panel control make sure you have enabled all the gestures required for the ScrollTracker (Flick, VerticalDrag  and DragComplete) while buttons required Tap gesture.

Game Level, Physics Screen

So far we have not used Farseer in any screens; it’s time to do so. This screen will be the actual playground where our subject is going to bounce and camera is going to move towards right at steady speed. While moving the subject, players have to face the obstacles and make the way out with keeping in mind to score as high as possible.
To make things simpler for rendering and designing we are going to divide the screen in grid or square blocks each of size 32 pixel, making the screen of 800x480 in 25x15 blocks.
One more thing which we haven’t talked about much is “how the level gets designed”? I thought of using xml data to store level information, like obstacle node with position at point x and y. But then to design a whole level this way will take a lot of time. So I decided to build a level editor, specific to my game (not generic this time). Through this level editor we can design our own levels and this level editor will give the XML (sample at FarseerXNAWP7/Levels/Game.xml) needed to render the level in game. Good enough so now we need to think that we have already designed some levels and passed through level selector screen to GameLevelPhysicsScreen. Its task of this screen to read the data and render them correctly with correct physics applied to it.
//NOTE//
If you are using physics in a game then don’t be too realistic with the numbers, because most of the games are 50% non-real physical conditions, like you may need to set the gravity to more than 9.8 to make it more real. In short, do trial and errors with the numbers until you get the simulation to work similar to what is in your mind and don’t bother about the real world value.

From now onwards we will be using following terminology, level data = collection of entities, entity = everything which will be rendered on screen and have meaning with respect to subject, subject = moving entity which can be controlled by player, obstacle = entities which makes the subject jump when hit on top side, spikes = hit-dead obstacles placed at different position and stationary all the time, spike strip = to understand why we need this object first consider one scenario, suppose we are moving the camera at steady speed towards right, now if player doesn’t move the subject then it will be soon out of the screen so we need one spike strip on the whole left wall of the screen which will be scrolled alongside the camera, front wall = player can move the subject faster than the camera speed, so it is possible that player move the subject off the boundary by right wall, to prevent this we need to have a front wall, it is not visible but it is there, solid floor = same as obstacle but generated automatically at the bottom of the screen which makes the subject jump when hit, Diamond = when player hit them, diamonds gets invisible and player gets large score boost, hollow floor = it is actually nothing in context of physics, it is a hole in the floor if subject drops in it, then game over.
So now we assume that LevelSelectorScreen has passed levels data in constructor. Let’s explore the code in the FarseerXNAWP7/Screens/GameLevelPhysicsScreen.cs.
We will start with the LoadContent method, and very first line of code in it resets the World (remember the Farseer Physics Engine’s World class) with downward gravity of 65 magnitude (recall the last NOTE section, games are 50% unreal). Very important method call in LoadContent is the CreateEntities, this method is responsible for creating background, scoreboard, level entities, front wall and spike strip. We are mostly interested in the Level Entities creation, so let’s have a look into PlotLevelData method. Ok I admit it is bit difficult to understand at first sight but believe me it is way too simple. In this PlotLevelData method, we iterate through all the Entities and according to their type (obstacle, spike, hollow floor etc) we need to create the related physics object, easy enough, right! So if you take a close look at the method we are creating physics object using the same FixtureFactory and BodyFactory we explained in FarseeXNADemo1. But there are little tweaks we need to do in order to make the game playable. Below is the explanation about each entity creation.
Obstacle (from 1 to 6): Obstacle is solid block of 1 cell size (32x32 pixels) and only allows the subject to bounce from its top surface. To make subject jump we apply impulse to it when we have collision with specific type of objects (like Obstacle’s front side). But there is no way to identify whether we hit the front wall side wall or bottom wall, so we create 2 physics object, one will be the actual Obstacle with correct texture on it and another will be the thin line placed at the top of the obstacle (first object), which when collided with the subject makes it jump. This second object’s width will be little less than the obstacle width because we are going to use the same obstacle in wall creation and if we keep the second object of same width then wall can also makes the subject jump which we don’t want to do, so little less width, below diagram shows this problem.
Figure16.png
Spikes (Up, Down, Left and Right): Spikes are created using the vertices and they are after all triangle which fits in 32x32 pixels square.
Floor (Left, Right and Middle): By floor we mean hollow floor entity. Left and Right side of the hollow floor texture is different than the middle and middle floor texture can be repeated to make things easy to create. So we need different objects for each type of floor entity. Actually it is hollow floor so it should not have anything but how game will decide that the subject has fallen into it, so we use the same technique we used with the obstacle, we create two object, one with full texture and of floor object size (width 32 and height 64 pixels) and second object of thin line, placed at the bottom of the floor (at the screen bottom). Our first object don’t collide with the subject while second do, hence we will have nice looking effect of subject falling into the floor hole and when it hit the ground of the hole we will be notified about the same.
Subject and Diamond: We can go with the geometry of the diamond exactly using the vertices, but our game doesn’t require that much precision so we can use rectangle/circle for these objects easily. And I don’t think now we need to know how to create rectangle and circles, Do we!!!
Solid Floor: You might have noticed that we are keeping track of the placement of the object in the grid using a two dimensional array. When we have any object at the column x row position then we put 1 in the matrix. This will be used in the calculation for where we need to put the floor, and we can do that by just comparing the last row value, simple huh….
If you have noticed that we are passing rendering information with the GameObjectType, now you ask why? Let me tell you a story, a long time ago there was a king, When we have collision we can’t find whether it is a floor, obstacle, spike or diamond by looking at the fixture of the collided bodies, so we saved some more information with each body which can be easily retrieved at the time of collision. So let’s see the collision methods.
OnCollision: Ok so think of how many objects can collide and what should we do when that happens? Answer to said question will be our method body. Only subject can collide with other object, so collision can be between Subject and obstacle, spikes, hollow floor, solid floor, diamonds and Spike strip. We don’t even bother about the front wall because we don’t need to do anything at the time of collision, physics engine will take care of that. So let’s explore what should be do when the subject collides with the said objects. Collision with
- Obstacle and Solid Floor: Apply impulse to the subject so that it looks like jump.
- Spike, Spike Strip and Hollow Floor: Game over buddy. Start the process of showing the game over screen (LevelOverScreen).
- Diamond: Now this is problematic. If you wait for the OnCollision event to fire then your subject will be bounced from the collision with the diamond and we definitely don’t want this to happen. We want the subject to pass through the diamond and still want to remove that diamond from the screen, but how???? BeforeCollision, we can check whether the Subject is going to collide with the diamond and if yes then we remove the diamond from the world hence no collision and bounce but we know that collision will be there so increase the score, cool huh.
One more thing left and that is how game will be notified that level is complete? And we again use the invisible completion wall and collision detection to determine it. We will create an invisible wall at the end of the level data and check for the collision of Subject with it, if we found one then we can say that player has finished the level and need to be presented with the Level Completed screen.
One last thing about this screen is that, we are storing the textures in dictionary, now you say why, why can’t we use variables as we use with other screens? My answer to that question is ‘CACHING’. Suppose player hit spike and game is over, then we need to allow player to retry the level, for that we don’t want to load all the textures again, they are already there, already loaded. So we store them in memory for later use.

Level Over Screen

This screen is similar to the Instructions screen; in fact they both share the same background image too. This screen is used to show the total score when player completes the game level or game gets over. From the same screen player can choose to go for level selector menu or retry level/next level depending on the screen type (which can be level completed screen or game over screen). Below is the screenshot of the same screen when player hits the spike and game gets over.
Figure17.png

HighScore Screen

Last screen we need is the Highscore screen. We will be using isolated storage to store the scores of the player. We can have multiple levels so we need to store the highscores with respect to the level. Also we are only interested in top 5 highscore for each level. Below is the Highscore screen’s screenshot.
Figure18.png
Here we have utilized the scrollable panel control because this list might get off the screen; Background is the same parallax background.

TOMBSTONING

One of the things we need to consider in phone applications are the interrupts which can occur at any point of time. By interrupts we mean, getting a phone call or user hitting hardware button etc. Because WP7 is not a multitasking phone (not at least now) we can’t have more than one application running. So suppose your application is running and user hit the hardware search button, so now your application gets deactivated and search screen gets activated, but if you are using Visual Studio and have already attached debugging you will see that debugging is not stopped, so that means your application is not killed totally instead it is not in the foreground, now if you hit the back button your application gets resumed. You might be thinking that WP7 will store states for you and it will resume from where you left it, but that is not the case, resume means WP7 knows that it is reactivated and no new instance was launched. Hence we can use this knowledge to save and load the states if application gets deactivated and activated.
In our game we only care about the main game screen (GameLevelPhysicsScreen). If this screen is active then we save the current state of the objects in memory for later retrieval. Ok, so what information we need to save to load the screen again? Answer will be the subject’s position, camera position, background position, Current Level index being played, Diamonds collected and distance travelled. We use a class named ResumeState to store these data and then we put object of that class in phone’s memory state.
Now we need to know when to save data in memory and when to load from memory, and for that we can listen to the current PhoneApplicationService’s Deactivated and Activated events respectively. When we have Deactivated event we get the ResumeState object from the StartScreen, which will request the same from the LevelSelector Screen which in turn gets data from actual GameLevelPhysicsScreen if it is the active screen. This ResumeState object will be saved in phone’s memory state. When we have Activated event we check for the phone’s memory state for the Resume state key, if we found one then we get the ResumeState object and pass it to the StartScreen, now StartScreen checks for the local ResumeState object and if it is set then it will load the LevelSelectorScreen which does the same process and load the GameLevelPhysicsScreen with the ResumeState object. In the ContentLoad method if we have the ResumeState object set then we initializes the Camera, Subject, Background, and Score with the values from the ResumeState object. And that’s all we need to do to make the application rise from the Tombstate.
One last thing left with the tombstoning is get ready screen, think like you are in middle of the game and suddenly a call comes and games goes to tombstoned state, after the call you hit the back button and game resumes from the middle, but it might happen that player is not ready to hit the correct controls when he comes back, at that time we need to show him a get ready screen. We are using 5 seconds counter to tell player that we will be ready in 5 seconds so you better be ready.

LEVEL EDITOR AND SERIALIZATION WITH XNA

For our game we need to have some levels with different difficulty level. So rather building levels with note and paper I decided to go with the Level Editor application. This application will simplify the process of creating the level and also provide the actual runtime feel of the level. Through this application we can create new set of levels, edit them, place different kind of entities on it and design the level with just Drag and Drop. So let’s quickly explore the forms.

Level Editor Main Form

This form is main form of the application, you can create level, edit level, recorder them in the display list, save levels to be used in game or can loan existing levels to edit. Below is the screenshot of the same,
Figure19.png

New/Edit Level Form

This form is used to edit the attributes of level, like Name, Description, total width (which can be edited later from level builder form) and parallax background images.
Figure20.png

Actual Level Builder

Below form is the main design canvas of the level. We can build any complex level from this form using simple drag and drop. To build level, select any entity from the side bar and then left click on the canvas to place entity over it. Right click on any entity to remove it from the surface. One thing to note here is that, the editor is not so smart, if you try to place 2 cell sized entity on the last row of the grid then it is possible. So you must act smart in order to build playable levels. Come on I also have social life.
Figure21.png
When we hit the save and close, entities data (Position, type of entity, image, height and width) in Memory. And when we save from the main window we get the xml format which can be read from the XNA game using XML serialization and de-serialization, hence making things easy to extend.

YOUR TAKE AWAY

- Game Framework
- Code Snippet for rapid screen creation
- Graphics
- Reusable components (Button, Image, Text, Panel and ScrollBar)
- Screen System
- Farseer Physics Engine Basics and redering helper

CLOSING NOTE 

At the end, I just want to ask for suggestion to improve or if you find any bug in the code, just let me know. Also I have not tested things on real phone. It’s been my dream to build Games and make the Game development task as simple as LOB applications. If even a single developer gets inspired by this article and start developing Games then my task is fulfilled.  

One last thing, if you like things then please vote if anything wrong then please let me know.  

UPDATE HISTORY

28 Mar '11 - Original Article.
11 Apr '11 - Minor change to Closing note.
12 Apr '11 - Added FarseerPhysicsXNA.dll as download because with new version source is not getting compiled.  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO Veloxcore
India India
Love Programming... and games. You can find latest about me over http://www.veloxcore.com/

Comments and Discussions

 
QuestionUnable to Run or View the Project. Pin
pardeep sharma917-Apr-13 21:14
pardeep sharma917-Apr-13 21:14 
GeneralMy vote of 5 Pin
Charalampos114-Apr-13 9:41
Charalampos114-Apr-13 9:41 
GeneralFull Marks Pin
CrystalB26-Mar-13 8:51
CrystalB26-Mar-13 8:51 
GeneralMy vote of 5 Pin
mruva19-Jan-13 3:22
mruva19-Jan-13 3:22 
GeneralMy vote of 5 Pin
Kanasz Robert21-Sep-12 1:27
professionalKanasz Robert21-Sep-12 1:27 
GeneralMy vote of 5 Pin
Jαved30-Apr-12 1:19
professionalJαved30-Apr-12 1:19 
BugBug found!! Pin
Deepak NW29-Dec-11 18:28
Deepak NW29-Dec-11 18:28 
GeneralRe: Bug found!! Pin
Vinit Yadav24-Feb-13 3:21
professionalVinit Yadav24-Feb-13 3:21 
QuestionWindows Phone 7 Toggle Pin
Deepak NW25-Dec-11 17:39
Deepak NW25-Dec-11 17:39 
GeneralMy vote of 5 Pin
Anoop Pillai13-May-11 2:08
Anoop Pillai13-May-11 2:08 
GeneralMy vote of 5 Pin
ratruong12-May-11 3:38
ratruong12-May-11 3:38 
GeneralMy vote of 5 Pin
jfriedman27-Apr-11 17:41
jfriedman27-Apr-11 17:41 
GeneralExcellent Pin
Member 456543324-Apr-11 4:59
Member 456543324-Apr-11 4:59 
Have 5
GeneralMy vote of 5 Pin
linuxjr12-Apr-11 7:07
professionallinuxjr12-Apr-11 7:07 
GeneralMy vote of 5 Pin
hoernchenmeister12-Apr-11 5:45
hoernchenmeister12-Apr-11 5:45 
GeneralExcellent stuff Pin
Sacha Barber12-Apr-11 4:43
Sacha Barber12-Apr-11 4:43 
GeneralHelp me compile please. Pin
Member 127158312-Apr-11 2:09
Member 127158312-Apr-11 2:09 
GeneralRe: Help me compile please. Pin
Vinit Yadav12-Apr-11 5:47
professionalVinit Yadav12-Apr-11 5:47 
GeneralMy vote of 5 Pin
Slacker00712-Apr-11 1:02
professionalSlacker00712-Apr-11 1:02 
GeneralMy vote of 5 Pin
Prashanth K B11-Apr-11 23:40
Prashanth K B11-Apr-11 23:40 
GeneralMy vote of 5 Pin
User 246299111-Apr-11 21:19
professionalUser 246299111-Apr-11 21:19 
GeneralMy vote of 5 Pin
Luc Pattyn11-Apr-11 11:56
sitebuilderLuc Pattyn11-Apr-11 11:56 
GeneralI am so disappointed... Pin
Pete O'Hanlon11-Apr-11 9:41
subeditorPete O'Hanlon11-Apr-11 9:41 
GeneralRe: I am so disappointed... Pin
Vinit Yadav11-Apr-11 18:18
professionalVinit Yadav11-Apr-11 18:18 
Generalsprite image control Pin
sandrogrillo7-Apr-11 21:50
sandrogrillo7-Apr-11 21:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.