I hope everyone is having a wonderful holiday season. I sure am. Corndog and I wish the best for our viewers and hope for peace in these troubled times. I know we could use some.

You may not believe me, but the project is still alive and moving along. Our posting and working schedule has been terribly afflicted by finals season, but we have recently made incredible progress and should (Finally) be able to post some videos of early gameplay by the end of next month. These videos will hopefully showcase some of the features we hope to include in the final version of the game.

Also starting with the new year we will start writing segments about the game. Such as gameplay, story, weapons, things I'm sure you want to know as opposed to all this programming stuff. There will still be programming stuff, but it will be spaced apart for out more non-technical audiences.

With the recent victory over camera control we have been busy at work implementing the texture tiling and sprite animation controls which will be needed once we get some actual textures. My task is now to implement the Lidgren Networking Library which I have been studying for some time, while Corndog polishes up the character movement.

Anyways more on this game development stuff later, there are cookies that need to be taken care of.
Hello! GM Riscvul here. Normally Corndog would be the one to post on the Farseer Development effort, but he delegated the effort to me. This week's post on Farseer Physics has to do with the debugviewer. For the longest time we could not get our physics world to match up with our pixels world. This made our physics objects be in completely different places than our graphics. This made it almost impossible to debug effectively.

Following the last post we posted the following debugview code

172 //If you want to see debug info on top then place this function before other spritebatch calls

173 debugView.RenderDebugData(ref proj, ref view);


This used an identity matrix for the viewport and a projection matrix that looked like so

147 Matrix proj = Matrix.CreateOrthographic(50 * AspectRatio, 50, 0, 1);


This was all well and good except for... IT WASN'T MATCHING UP!!!
Alot of foul language was heard from Corndog as he tried desperately to match them to no avail. However having taken a few graphics classes I had a better idea of what I was looking at and dug in. The following answer is adapted from some kind soul's code posted on a forum. I cannot find the forum entry again and therefore I am failing to give proper credit. The code was adapted to suit our specific program.

141 Viewport Vport = GraphicsDevice.Viewport;

142 GraphicsDevice.Clear(Color.CornflowerBlue);

143

144 //Creates screen projection for debug mode that sets the height of the physics world to variable

145 // ScreenHeightInPhysicsWorld.

146 // This height is in meters

147 Matrix proj = Matrix.CreateOrthographic(ScreenHeightInPhysicsWorld * graphics.GraphicsDevice.Viewport.AspectRatio, ScreenHeightInPhysicsWorld, 0, 1);

148

149 // Viewport should either be identity matrix or camera transformation

150 Matrix view = _camera.get_transformation(GraphicsDevice);

151

152 // This transform matrix is passed into spritebatch to convert pixel sizes into meters

153 // This means physics world coordinates are the same as spritebatch coordinates

154 // Use locations and sizes of physics bodies for coordinates

155 Matrix transform = view * Matrix.CreateScale(Vport.Height / ScreenHeightInPhysicsWorld)

156 * Matrix.CreateScale(1,-1,1)

157 * Matrix.CreateTranslation(Vport.Width * .5f, Vport.Height * .5f, 0f);

158

159 //Be sure to pass in transform into any spritebatch you want to conform to the physics world!

160 //

161 // One other note! JigLibX which farseer is based off of uses a reversed Y scale. This means you need

162 // to reverse any textures you use or they will be culled by spritebatch! It might be possible to fix

163 // this by changing the scale matrix above, but edit at your own risk.

164 spriteBatch.Begin(SpriteBlendMode.AlphaBlend,SpriteSortMode.BackToFront,SaveStateMode.SaveState,transform);

165

166

167 //map.Draw(spriteBatch, graphics);

168 player.Draw(spriteBatch, graphics);

169

170

171

172 //If you want to see debug info on top then place this function before other spritebatch calls

173 debugView.RenderDebugData(ref proj, ref view);


The Code above contains many comments which should help explain it, but for simplicity I will break it down farther. The view variable represents a viewport matrix. This will be your camera transform. We are using a camera2D class which provides the transform.

Next the proj variable represents a projection matrix. Since we are making a 2D game our projection will be orthographic. The purpose of an orthographic matrix is to make a scene fit on any screen by scaling and transforming the image to fit the current resolution. Our orthographic projection's goal is to make a standard height and width for the physics coordinates and spritebatch coordinates. Since XNA's graphicDevice stores the aspect ratio, or ratio of width to height, we will use this to set standard sizes for our world.

You might have noticed references to a variable called screenHeightInPhysicsWorld. Farseer uses meters to measure coordinates and sizes of its fixtures, so we want to use meters as well. This variable is how tall the portion of the world viewable on the screen is in meters. In this case it is 50. However feel free to change this to whatever you want.

Now our screen size is standardized and our camera is set up... but things still don't match up!! Well that is where the transform matrix comes in. Spritebatch can accept a matrix called a transform. We want to pass it a transform that will convert pixels to meters. This is much more complex. In fact it means little to anyone who doesn't have a background in graphics. In short this matrix converts pixel coordinates used in your spritebatch calls to meter coordinates used by farseer.

One final note, the transform flips coordinates to match Farseer's reversed Y scale. This means textures will by default be applied upside down and culled by the graphicsDevice. You need to flip textures on the Y axis in order to keep them visible. This is accomplished by something similar to the following.

175 Vector2 scale = new Vector2((circleFixture.Shape.Radius * 2) / (squareTexture.Width), -(circleFixture.Shape.Radius * 2) / (squareTexture.Width));


This scale vector is passed into spritebatch when drawing a texture. For spritebatch position information use the fixture position and spritebatch will draw the texture exactly where the physics object is.

Alright You should now have debug mode matching up with your spritebatch calls now. Have fun with physics!