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);
}
}