2
\$\begingroup\$

So I'm using Farseer to create an immovable object:

[...]
private Body body;
public Immovable(World world, ContentManager c, String s, int posx, int posy, int w, int h, String user_data)
{
    texture = c.Load<Texture2D>(s);
    float converted_width = ConvertUnits.ToSimUnits(w);
    float converted_height = ConvertUnits.ToSimUnits(h);
    float converted_posx = ConvertUnits.ToSimUnits(posx);
    float converted_posy = ConvertUnits.ToSimUnits(posy);
    body = BodyFactory.CreateRectangle(world, converted_width, converted_height, 1.0f, new Vector2(converted_posx, converted_posy), user_data);
    body.BodyType = BodyType.Static;
    width = w;
    height = h;
    x = posx;
    y = posy;
}

What I'm trying to do is keep separate my values for screen units (here, width, height, x, and y) and my values for simulated units (here, stored in body). This way, later, when I draw the object to the screen, I can:

public virtual void Draw(SpriteBatch sb)
{
    sb.Draw(texture, new Rectangle(x, y, width, height), Color.White);
}

This way, when I instantiate things, I can visualize them as screen coordinates, which should hopefully keep me sane during all this! Theoretically (especially as these objects don't move), these two coordinate pairs should be in the same spot (or off by a maximum of one pixel if I'm truncating floats to an int somewhere).

However, for some reason, my rectangles are being offset by ~25 pixels up and to the left. Here's a screenshot:

You can see that he has "landed" just above where the rectangle is being drawn. I can float around the box to explore where the physics engine believes it is, and I find that it's up and left about 25 pixels.

Any ideas on what could be causing this?

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I think when you create a physics body, the body's position is considered to be at its center of mass - which in this case since it's a rectangle, the center of mass is exactly in the middle of the rectangle. But you're drawing the sprite using the physics body position as if it were the top left corner of the sprite, instead of its center. For starters you should use another overload of Draw, the one that takes a Vector2 position and a Vector2 origin, and set the origin to be new Vector2(width/2, height/2). The one you're using is only really useful when you want to specify a sprite size. \$\endgroup\$ Commented May 1, 2012 at 21:15
  • 2
    \$\begingroup\$ @DavidGouveia you should put than in an answer since it's the solution to his problem. \$\endgroup\$ Commented May 1, 2012 at 21:30
  • \$\begingroup\$ @ClassicThunder Waiting for confirmation, I find it a bit strange because if that were the only problem, the character would not be floating, but rather digging into the ground. But I guess I'll place it in an answer and take it from there. \$\endgroup\$ Commented May 1, 2012 at 22:11

1 Answer 1

2
\$\begingroup\$

I think when you create a physics body, the body's position is considered to be at its center of mass - which in this case since it's a rectangle, the center of mass is exactly in the middle of the rectangle. But you're drawing the sprite using the physics body position as if it were the top left corner of the sprite, instead of its center.

For starters you should use another overload of Draw, the one that takes a Vector2 position and a Vector2 origin, and set the origin to be new Vector2(width/2, height/2). The one you're using is only really useful when you want to directly specify a sprite size.

\$\endgroup\$
3
  • \$\begingroup\$ Interesting. The only method I found that took a Vector2 position and origin was this: Draw(texture, Vector2 position, Rectangle source, Color, float rotation, Vector2 origin, float scale, SpriteEffect, float layerDepth). Is this the one you mean? I tried it (with an origin of height/2 and width/2, and a source rectangle of (0, 0, width, height), and I got a similar effect where they're still offset. \$\endgroup\$
    – Dan
    Commented May 1, 2012 at 22:25
  • \$\begingroup\$ That's the overload yes. By the way you can use null as the source rectangle, it defaults to the entire texture. I'm a bit busy at the moment though. Look at the character position in the debugger, and see if it makes sense compared to how it's being rendered. \$\endgroup\$ Commented May 1, 2012 at 22:28
  • \$\begingroup\$ Hey man, no worries. In this case, I need the custom width/height because I'm using variable sizes of the same texture -- but that's a non-issue. Your fix worked just fine -- I'd forgotten to do it for the player's sprite as well. :-) Cheers! \$\endgroup\$
    – Dan
    Commented May 1, 2012 at 22:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .