Farseer: Object not bouncing back from static objects

267 views Asked by At

I have a dynamic circular object bounded inside four static rectangle objects. Consider a ball inside a box with the static rectangle objects simulating the walls of the box . IgnoreGravity is set to true for circular object. I want the circular object to hit and bounce back from the walls. However, when the circular object collides with the wall, it stucks to it and moves along the wall instead of bouncing back.

Following is the code I am using:

Body CircleBody;

const int CircleRadiusInPixels = 20;
const int CircleCentreXInPixels = 100;
const int CircleCentreYInPixels = 100;
Texture2D CircleTexture;

Body[] RectangleBody;
Texture2D RectangleTexture;

struct RectagleProperties
{
    public int WidthInPixels;
    public int HeightInPixels;
    public int CenterXPositionInPixels;
    public int CenterYPositionInPixels;

    public RectagleProperties(int Width, int Height, int X, int Y)
    {
        WidthInPixels = Width;
        HeightInPixels = Height;
        CenterXPositionInPixels = X;
        CenterYPositionInPixels = Y;
    }

};

RectagleProperties[] rectangleProperties;

World world;

const float PixelsPerMeter = 128.0f;
float GetMetres(int Pixels)
{
    return (float)(Pixels / PixelsPerMeter);
}

int GetPixels(float Metres)
{
    return (int)(Metres * PixelsPerMeter);
}



protected override void LoadContent()
{
    ...
    RectangleTexture = Content.Load<Texture2D>("Sprites/SquareBrick");
    CircleTexture = Content.Load<Texture2D>("Sprites/Circle");

    world = new World(new Vector2(0, 9.8f));

    CircleBody = BodyFactory.CreateCircle(world, GetMetres(CircleRadiusInPixels), 
                                          1, 
                                          new Vector2(
                                                GetMetres(CircleCentreXInPixels), 
                                                GetMetres(CircleCentreYInPixels)));
    CircleBody.BodyType = BodyType.Dynamic;
    CircleBody.IgnoreGravity = true;
    CircleBody.LinearVelocity = new Vector2(1, 1);

    rectangleProperties = new RectagleProperties[4];
    rectangleProperties[0] = new RectagleProperties(800, 20, 400, 10);
    rectangleProperties[1] = new RectagleProperties(800, 20, 400, 460);
    rectangleProperties[2] = new RectagleProperties(20, 480, 10, 240);
    rectangleProperties[3] = new RectagleProperties(20, 480, 790, 240);

    RectangleBody = new Body[4];
    for (int i = 0; i < rectangleProperties.Length; i++)
    {
        RectangleBody[i] = BodyFactory.CreateRectangle(world,
                                                       GetMetres(rectangleProperties[i].WidthInPixels),
                                                       GetMetres(rectangleProperties[i].HeightInPixels),
                                                       0.5f,
                                                       new Vector2(GetMetres(rectangleProperties[i].CenterXPositionInPixels),
                                                                   GetMetres(rectangleProperties[i].CenterYPositionInPixels)));
        RectangleBody[i].BodyType = BodyType.Static;

    }
    ....
}

After a little digging around I found out that the VelocityConstraint was causing the collision to be treated as inelastic. However, if I reduce the value of VelocityConstraint then it results in weird collision response.

Does anybody know how to get the ball object bounce back after colliding with the static objects?

1

There are 1 answers

2
DOOMDUDEMX On

Since you haven't posted the contents of the Update-method where the problem probably lies i will make a qualified guess.

This seems to be related to a very common problem:

Say that the circular object has a certain speed. In event of a collision you reverse the speed over the walls axis and the speed is reduced a bit either by gravity or something else.

Now you apply the new speed in order to resolve the collision but since the speed is reduced it is not enough to resolve the collision which means the object will still be colliding with the wall in the next update.

This will cause the speed to be reversed over and over since the object will never gain enough speed to get out of the collision again.

The solution to this is to move the object out of collision preferably on the shortest axis (check out the "Separating axis theorem") before proceeding with other code.