How can I move the player over the tiles?

Topics: User Forum
May 9, 2013 at 10:00 PM
Hi. I'm a beginner and it's the first time that I use Farseer in XNA.
I created 4 tiles and I want to move the player over these tiles. But collision is not working. The player can move thru the tiles. I don't want that the player moves thru the tiles. What did I wrong?
I just want to do a little platformer, like the old Mario games.
public class Game1 : Microsoft.Xna.Framework.Game
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        World world;
        Body rectangle, rectangle2, rectangle3, rectangle4, playerrect;
        Texture2D rectangleSprite, playerSprite;
        float PosX, PosY;

        private static float _displayUnitsToSimUnitsRatio = 100f;

        public static Vector2 ToDisplayUnits(Vector2 simUnits)
            return simUnits * _displayUnitsToSimUnitsRatio;

        public Game1()
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

        protected override void Initialize()

        protected override void LoadContent()
            spriteBatch = new SpriteBatch(GraphicsDevice);
            playerSprite = Content.Load<Texture2D>("retromario");
            rectangleSprite = Content.Load<Texture2D>("retrotile");

            if (world == null)
                world = new World(new Vector2(0, 1));

            playerrect = BodyFactory.CreateRectangle(world, 0.64f, 0.64f, 1.0f);
            playerrect.BodyType = BodyType.Dynamic;
            playerrect.Position = new Vector2(0.96f, 4.16f);

            rectangle = BodyFactory.CreateRectangle(world, 0.64f, 0.64f, 1.0f);
            rectangle.BodyType = BodyType.Static;
            rectangle.Position = new Vector2(0.96f, 4.16f);

            rectangle2 = BodyFactory.CreateRectangle(world, 0.64f, 0.64f, 1.0f);
            rectangle2.BodyType = BodyType.Static;
            rectangle2.Position = new Vector2(0.32f, 4.80f);

            rectangle3 = BodyFactory.CreateRectangle(world, 0.64f, 0.64f, 1.0f);
            rectangle3.BodyType = BodyType.Static;
            rectangle3.Position = new Vector2(0.96f, 4.80f);

            rectangle4 = BodyFactory.CreateRectangle(world, 0.64f, 0.64f, 1.0f);
            rectangle4.BodyType = BodyType.Static;
            rectangle4.Position = new Vector2(1.60f, 4.80f);          
        protected override void Update(GameTime gameTime)
            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
            world.Step(Math.Min(elapsed, (1f / 60f)));
            KeyboardState kbState = Keyboard.GetState();

            // Move the player
            if (kbState.IsKeyDown(Keys.Left))
                PosX -= 0.5f * elapsed;
            if (kbState.IsKeyDown(Keys.Right))
                PosX += 0.5f * elapsed;
            if (kbState.IsKeyDown(Keys.Up))
                PosY -= 0.5f * elapsed;
            if (kbState.IsKeyDown(Keys.Down))
                PosY += 0.5f * elapsed;
            playerrect.Position = new Vector2(PosX, PosY);


        protected override void Draw(GameTime gameTime)
            spriteBatch.Draw(playerSprite, ConvertUnits.ToDisplayUnits(playerrect.Position),
                                           Color.White, playerrect.Rotation, new Vector2(playerSprite.Width / 2.0f, playerSprite.Height / 2.0f), 1f,
                                           SpriteEffects.None, 0f);

            spriteBatch.Draw(rectangleSprite, ConvertUnits.ToDisplayUnits(rectangle.Position),
                                            Color.White, rectangle.Rotation, new Vector2(rectangleSprite.Width / 2.0f, rectangleSprite.Height / 2.0f), 1f,
                                            SpriteEffects.None, 0f);

            spriteBatch.Draw(rectangleSprite, ConvertUnits.ToDisplayUnits(rectangle2.Position),
                                            Color.White, rectangle2.Rotation, new Vector2(rectangleSprite.Width / 2.0f, rectangleSprite.Height / 2.0f), 1f,
                                            SpriteEffects.None, 0f);

            spriteBatch.Draw(rectangleSprite, ConvertUnits.ToDisplayUnits(rectangle3.Position),
                                            Color.White, rectangle3.Rotation, new Vector2(rectangleSprite.Width / 2.0f, rectangleSprite.Height / 2.0f), 1f,
                                            SpriteEffects.None, 0f);

            spriteBatch.Draw(rectangleSprite, ConvertUnits.ToDisplayUnits(rectangle4.Position),
                                            Color.White, rectangle4.Rotation, new Vector2(rectangleSprite.Width / 2.0f, rectangleSprite.Height / 2.0f), 1f,
                                            SpriteEffects.None, 0f);

May 10, 2013 at 6:26 PM
My guess is that your bodies are not actually colliding, it just "looks" like they are colliding. Keep in mind that the physics world and drawing world are completely separate. I'm guessing you're drawing your platforms larger than they are in the physics world (since you're just scaling a rectangle sprite). One way to confirm this would be to, instead of using the Position version of the Draw call, use the Destination Rectangle version where the rectangle is a ToDisplayUnits version of the actual rectangle body you created.

Hopefully that makes sense. In short, check your drawing code and scale. If your bodies do not react to a collision, then they're not colliding -- it just might look they are colliding because of the way you're drawing them.

May 10, 2013 at 9:15 PM
Edited May 13, 2013 at 3:42 PM
I guess it's a problem with collision detection. I found this code in another topic but I don't know how to apply it in my code.
How can I use OnCollision in my code?
var body = BodyFactory.CreateRectangle(world, width, height, 1f, position);
body.OnCollision += body_OnCollision;

// ...

bool body_OnCollision (Fixture fixtureA, Fixture fixtureB, FarseerPhysics.Dynamics.Contacts.Contact contact) {
    // will be called whenever some other body collides with 'body'
How can I use this code to detect for collision? I just want that the player can not move thru the rectangles.

I solved the problem.