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

'Sliding' behaving oddly.

Mar 21, 2012 at 1:23 AM
Edited Mar 21, 2012 at 1:24 AM

Hi, guys. I'm trying to make a platformer using Farseer. I realize there are a number of obstacles with this, but after struggling to get collisions to work properly on my own, and not wanting to resort to a tile-based layout, I've set up Farseer and have been playing around with it. So far I just have a box you can control, which falls onto a platform.

The problem is that I notice some very odd behaviour. When moving the box left or right on the platform, it sometimes gets 'stuck' (the platform is perfectly flat and composed of many 32x32 blocks). It will suddenly act as though it is caught on something. Further, when it doesn't, moving it right or left sometimes generates lift rather than just sliding across the ground which is what I am looking for. I am not sure what causes these behaviours. It is possible I have set some weird parameters for the world. The player has a mass of 10, is set not to rotate, gravity is set at 50, and movement is done by applying force in the appropriate direction.

Any insight is appreciated.

Player's HandleInput function:

        protected void HandleInput(GameTime gameTime)
            KeyboardState keyState = Keyboard.GetState();
            float forcePower = 100000;

            //Apply force in the arrow key direction
            Vector2 force = Vector2.Zero;

            if (keyState.IsKeyDown(Keys.Left))
                force.X -= forcePower * (float)gameTime.ElapsedGameTime.TotalSeconds;
            if (keyState.IsKeyDown(Keys.Right))
                force.X += forcePower * (float)gameTime.ElapsedGameTime.TotalSeconds;
            if (keyState.IsKeyDown(Keys.Up))
                force.Y -= forcePower * (float)gameTime.ElapsedGameTime.TotalSeconds;
            if (keyState.IsKeyDown(Keys.Down))
                force.Y += forcePower * (float)gameTime.ElapsedGameTime.TotalSeconds;


            KeyboardState oldState = keyState;


GameObject's SetupPhysics function:

        protected virtual void SetupPhysics(PhysicsSimulator physics,
            Vector2 pos, float width, float height, float mass)
            this.width = width;
            this.height = height;

            body = BodyFactory.Instance.CreateRectangleBody(physics,
                width, height, mass);
            body.Position = position;

            body.IsStatic = true;

            geom = GeomFactory.Instance.CreateRectangleGeom(physics,
                body, width, height);
            geom.FrictionCoefficient = 0.5f;
Mar 21, 2012 at 12:14 PM
Edited Mar 21, 2012 at 12:16 PM


I few things from looking at your code. The force magnitude is too big which makes me thing your world isn't scaled properly. That could make the solver unstable (it's a limitation with implicit integration). You should work with realistic kg/m/s in the physics (e.g. a player is about 2m tall and weighs about 80kg) and convert to pixels only when drawing. Also when you apply the force you are somehow trying to reinvent what an impulse is (multiplying by delta time) but the engine has specific methods for that because it's needs some extra calculations.

As for your question this is a known issue. It's due to the fact that the solver doesn't know that the tiles have neighbours so in correcting overlap with one tile it can push the body into a new collision conflict with the next tile which it would try to resolve in another iteration. See this thread for info:

Possible solutions:

- Combine the polygons (tiles)

- Use edge/loop shapes for the surface

- Make your player a capsule instead of rectangle

Also this: