Bad capsule/rectangle collision?

Topics: Developer Forum
Mar 5, 2011 at 12:33 PM

I'm having some problems with a player (capsule) colliding with a block (rectangl)e - the point where the circle and the rectangle of the capsule intersect gets "stuck" on the corner of the rectangle block.  Because a picture is worth a thousand words, it gets stuck like this:

Is there any way around this? Or is it a bug? I have some code to reproduce it here (press space to run the character towards the block, and the enter to jump and get stuck)

using System.Collections.Generic;
using FarseerPhysics.DebugViews;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace FreeRunnerPrototype
    public class Game1 : Microsoft.Xna.Framework.Game
        GraphicsDeviceManager graphics;

        DebugViewXNA _debugView;
        Body player;
        World world;

        public Game1()
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            graphics.PreferredBackBufferHeight = 600;
            graphics.PreferredBackBufferWidth = 800;

        protected override void Initialize()
            world = new FarseerPhysics.Dynamics.World(-20f * Vector2.UnitY);

            List<Fixture> capsule = FixtureFactory.CreateCapsule(world, 1f, 0.4f, 1);
            player = capsule[0].Body;
            player.BodyType = BodyType.Dynamic;
            player.Position = new Vector2(2f, 1.9f);
            player.FixedRotation = true;
            foreach (var f in capsule)
                f.Friction = 0;

            Fixture block = FixtureFactory.CreateRectangle(world, 1f, 0.5f, 1);
            block.Body.BodyType = BodyType.Static;
            block.Body.Position = new Vector2(5f, 0.5f);
            block.Friction = 0;

            Fixture ground = FarseerPhysics.Factories.FixtureFactory.CreateRectangle(world, 50, 1, 1);
            ground.Body.Position = new Vector2(0, -0.5f);


        protected override void LoadContent()
            _debugView = new DebugViewXNA(world);
            _debugView.LoadContent(GraphicsDevice, Content);

        protected override void UnloadContent()

        protected override void Update(GameTime gameTime)
            KeyboardState state = Keyboard.GetState();
            if (state.IsKeyDown(Keys.Escape)) Exit();

            if (state.IsKeyDown(Keys.Space))
                player.LinearVelocity = new Vector2(5, 0);
            if (state.IsKeyDown(Keys.Enter) && player.LinearVelocity == Vector2.Zero)
                player.ApplyLinearImpulse(new Vector2(0, 15));

            float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

        protected override void Draw(GameTime gameTime)

            Matrix proj = Matrix.Identity;
            Matrix view = Matrix.CreateOrthographicOffCenter(0, 8, -1, 5, -1, 1);
            _debugView.RenderDebugData(ref proj, ref view);


Mar 5, 2011 at 5:17 PM

This is a known bug and it comes from the fact that the capsule shape is made up of 2 circles and a rectangle. You have 2 options:

1. Edit the code to make the circles slightly bigger.

2. Use PolygonTools.CreateCapsule() method to create a capsule shape that is based on a polygon. However, this might give you other kinds of problems since it is made of many smaller fixtures.

There is a third option of using a LoopShape instead. Simply create a LoopShape from the Capsule vertices given by the PolygonTools. It is a little hacky though.

Mar 5, 2011 at 11:20 PM
Edited Mar 5, 2011 at 11:34 PM

Awesome, thanks.

I just used Height/2.1f instead of Height/2 for the width of the rectangle. Now it should only break if there's a diagonal spike or something jutting into it. Which isn't going to happen.