Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I created a ball that is rolling over platforms. When it falls from one platform to another, it should bounce just like in real life, but the ball keeps bouncing constantly and I don't know how to recreate a realistic bounce-behaviour in Farseer. In addition, the ball sometimes bounces higher but I don't know the reason for this. How can I improve the bouncing of the ball?

In this video, you can see how it bounces: http://www.vidup.de/v/I55qn/

public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    World world;
    Body rectangle, rectangle2, rectangle3, rectangle4, rectangle5, playerrect;
    Texture2D rectangleSprite, playerSprite;

    private static float _displayUnitsToSimUnitsRatio = 100f;

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

    private bool isOnGround;

    bool Player_OnCollision(Fixture fixtureA, Fixture fixtureB, FarseerPhysics.Dynamics.Contacts.Contact contact)
    {
        if (fixtureB.CollisionCategories == Category.Cat5)
        {
            isOnGround = true;
        }
        return true;
    }
    void Player_OnSeparation(Fixture fixtureA, Fixture fixtureB)
    {
        if (fixtureB.CollisionCategories == Category.Cat5)
        {
            isOnGround = false;
        }
    }

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

    protected override void Initialize()
    {
        base.Initialize();
    }

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

        if (world == null)
        {
            world = new World(new Vector2(0, 1));
        }
        else
        {
            world.Clear();
        }

        playerrect = BodyFactory.CreateCircle(world, 0.25f, 1.0f);
        playerrect.BodyType = BodyType.Dynamic;
        playerrect.Position = new Vector2(2.76f, 0f);

        rectangle = BodyFactory.CreateRectangle(world, 1.50f, 0.50f, 1.0f);
        rectangle.BodyType = BodyType.Static;
        rectangle.Position = new Vector2(2.96f, 1.16f);
        rectangle.Rotation = -0.3f;
        rectangle.CollisionCategories = Category.Cat5;

        rectangle2 = BodyFactory.CreateRectangle(world, 1.50f, 0.50f, 1.0f);
        rectangle2.BodyType = BodyType.Static;
        rectangle2.Position = new Vector2(1.0f, 1.80f);
        rectangle2.Rotation = 1.0f;
        rectangle2.CollisionCategories = Category.Cat5;

        rectangle3 = BodyFactory.CreateRectangle(world, 1.50f, 0.50f, 1.0f);
        rectangle3.BodyType = BodyType.Static;
        rectangle3.Position = new Vector2(4.1f, 4.80f);
        rectangle3.CollisionCategories = Category.Cat5;

        rectangle4 = BodyFactory.CreateRectangle(world, 1.50f, 0.50f, 1.0f);
        rectangle4.BodyType = BodyType.Static;
        rectangle4.Position = new Vector2(2.6f, 4.80f);
        rectangle4.CollisionCategories = Category.Cat5;

        rectangle5 = BodyFactory.CreateRectangle(world, 1.50f, 0.50f, 1.0f);
        rectangle5.BodyType = BodyType.Static;
        rectangle5.Position = new Vector2(5.6f, 4.80f);
        rectangle5.CollisionCategories = Category.Cat5;

        playerrect.OnCollision += Player_OnCollision;
        playerrect.OnSeparation += Player_OnSeparation;
    }

    protected override void Update(GameTime gameTime)
    {
        float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
        world.Step(Math.Min(elapsed, (1f / 60f)));
        KeyboardState kbState = Keyboard.GetState();       

        if (isOnGround == true)
        {
          playerrect.ApplyForce(new Vector2(0, -4.5f));
        }

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();
        spriteBatch.Draw(playerSprite, ConvertUnits.ToDisplayUnits(playerrect.Position),
                                       null,
                                       Color.White, playerrect.Rotation, new Vector2(playerSprite.Width / 2.0f, playerSprite.Height / 2.0f), 1.0f,
                                       SpriteEffects.None, 0f);

        spriteBatch.Draw(rectangleSprite, ConvertUnits.ToDisplayUnits(rectangle.Position),
                                        null,
                                        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),
                                        null,
                                        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),
                                        null,
                                        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),
                                        null,
                                        Color.White, rectangle4.Rotation, new Vector2(rectangleSprite.Width / 2.0f, rectangleSprite.Height / 2.0f), 1f,
                                        SpriteEffects.None, 0f);
        spriteBatch.Draw(rectangleSprite, ConvertUnits.ToDisplayUnits(rectangle5.Position),
                                       null,
                                       Color.White, rectangle5.Rotation, new Vector2(rectangleSprite.Width / 2.0f, rectangleSprite.Height / 2.0f), 1f,
                                       SpriteEffects.None, 0f);
        spriteBatch.End();

        base.Draw(gameTime);
    }
}
share|improve this question

1 Answer 1

up vote 2 down vote accepted

Are you just adding force to the ball? If you need elastic collisions don't do this. Farseer body has property called restitution, it controls ratio of the speed before and after collision.

share|improve this answer
    
Thanx. It works. –  Bryan May 12 '13 at 18:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.