0
\$\begingroup\$

The ball is not getting slower when it rolls over a straight platform. I added friction but that changed nothing, the ball still gets not slower. I want that the ball gets slower and slower and stops rolling after a certain time. Like in real life. How can I do that?

In addition, the ball jumps weird when it touches two platforms at the same time. Is there a possibility to avoid that weird jumping?

Jumping ball video: http://www.vidup.de/v/p2DDO/

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

    private static float _displayUnitsToSimUnitsRatio = 100f;

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

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

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

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

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

        ballcircle = BodyFactory.CreateCircle(world, 0.25f, 1.0f);
        ballcircle.BodyType = BodyType.Dynamic;
        ballcircle.Position = new Vector2(2.76f, 0f);
        ballcircle.Restitution = 0.5f;
        ballcircle.Friction = 0.3f;

        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.Friction = 0.9f;
        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.Friction = 0.9f;
        rectangle2.CollisionCategories = Category.Cat5;

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

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

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

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

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();
        spriteBatch.Draw(ballSprite, ConvertUnits.ToDisplayUnits(ballcircle.Position),
                                       null,
                                       Color.White, ballcircle.Rotation, new Vector2(ballSprite.Width / 2.0f, ballSprite.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);
    }
}
\$\endgroup\$
1
\$\begingroup\$

In addition, the ball jumps weird when it touches two platforms at the same time. Is there a possibility to avoid that weird jumping?

Nope your going to get that behavior with 2 platforms. You should combine them together into 1 shape. If the shape is more complex you can create a polygon that encompasses the entire area.

Anyways friction is going to take a very very long time to stop a perfectly round object. However, you can apply angularDamping to the object which will continually apply force with the goal of making the object stable.

A really good resource is the Box2D Manual and iforce2d.

\$\endgroup\$
  • \$\begingroup\$ Thanx. It works. \$\endgroup\$ – Bryan May 13 '13 at 8:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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