This project has moved and is read-only. For the latest updates, please go here.

Having problems with simple collision

Topics: Developer Forum, User Forum
Apr 2, 2008 at 5:23 AM
Hi all. I am trying to write a very simple program to understand how Farseer works. Based on the sample I donwloaded here, I draw a square in the screen (player) and a black rectangle (platform) that should act as a floor. I positioned the player on the top of the screen, the floor somewhere in the middle, and ran waiting for the player to collide and stop falling. But the player for some reason always falls a little bit more than expected.

I will paste the source code below, but the only thing I noticed that is different from the sample is that the body and geometry created for the boxes have a width and height of 190 while the box texture is 210x210. Why is this? For a collision right on the edges, shouldn't these values be equal?

Here is my source code, I put all on LoadContent() for simplicity. I appreciate any help and thanks in advance for your time:

protected override void LoadContent()
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

IsFixedTimeStep = true;
TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 10); //10 ms --> 100 fps for physics update

psim = new PhysicsSimulator(new Vector2(0, 200));

platformTexture = Content.Load<Texture2D>("Stage1_Floor");
platformBody = BodyFactory.Instance.CreateRectangleBody(psim,platformTexture.Width, platformTexture.Height, 1.0f);
platformBody.Position = new Vector2(0, 370);
platformBody.IsStatic = true;

platformGeom = GeomFactory.Instance.CreateRectangleGeom(psim,platformBody, platformTexture.Width, platformTexture.Height);
platformGeom.CollisionEnabled = true;

playerTexture = Content.Load<Texture2D>("test");
playerBody = BodyFactory.Instance.CreateRectangleBody(psim, playerTexture.Width, playerTexture.Height, 1.0f);
playerBody.IsStatic = false;
playerBody.Position = new Vector2(20, 101);

playerGeom = GeomFactory.Instance.CreateRectangleGeom(psim, playerBody, playerTexture.Width, playerTexture.Height);
playerGeom.CollisionEnabled = true;


On the update method:
psim.Update(gameTime.ElapsedGameTime.Milliseconds * .001f);

And on Draw:

spriteBatch.Draw(platformTexture, platformBody.Position, Color.White);
spriteBatch.Draw(playerTexture, playerBody.Position, Color.White);

Apr 2, 2008 at 12:26 PM
You are going to have to hook up some sort of debug view to really see what is happening. You can find an example debug view in the samples.
Apr 2, 2008 at 5:50 PM
You are right, I will incorporate the debug methods from the samples into my project, I will need many times over. But can you please just briefly explain to me why the geometry and body width and heights are not the same as the texture? Thank you.
Apr 2, 2008 at 6:55 PM
So, I incorporated the debug methods from the samples into my project and here is the problem:

So, the Position attribute of a body is not the upper left corner, but in the center of the body. That makes a lot of sense when you think of physics but it is very easy to make this mistake because XNA default position is the upper left, or 0,0.

May I suggest that the name of Body.Position changes to Body.Origin ? And maybe put some intellisense information (summary tag) to make this clear to the user.

I know, I should have noticed the Origin parameter in the draw method, but I was so concerned about getting the physics right that I didn't pay too much attention to the texture drawing part.

Thanks !
Apr 3, 2008 at 5:45 PM
I probably won't rename the property but adding some code comments that call this out is a good idea.

Thanks, and glad you found the problem. A debug view is pretty much mandatory from the start. It saves a lot of time and frustration.