Object don't falls vertically

Jan 19, 2012 at 9:29 PM

Hi,

I try to use Farseer Engine to simulate physics in my game. So I used Samples XNA AdvancedDemo1.Cs, and I put my own picture, instead of a polygon shape that was used in this example. It looks like this:

http://i41.tinypic.com/24neavb.png

and I set it up like this:

        protected override void LoadContent()
        {
            world = new World(new Vector2(5));

            spriteBatch = new SpriteBatch(GraphicsDevice);
            ship = new Ship();
            ship.texture = Content.Load<Texture2D>("hull");

            ship.LoadContent(world);

            camera = new Camera2D(GraphicsDevice);
        }
where ship.LoadContent is:

        public void LoadContent(World world)
        {
            uint[] data = new uint[texture.Width * texture.Height];
            texture.GetData(data);
            Vertices vertices = PolygonTools.CreatePolygon(data, texture.Width, false);
            Vector2 centroid = -vertices.GetCentroid();
            vertices.Translate(ref centroid);
            origin = -centroid;
            vertices = SimplifyTools.ReduceByDistance(vertices, 4f);
            List<Vertices> list = BayazitDecomposer.ConvexPartition(vertices);
            Vector2 scale = new Vector2(ConvertUnits.ToSimUnits(1));
            foreach (Vertices v in list)
                vertices.Scale(ref scale);
            body = BodyFactory.CreateCompoundPolygon(world, list, 1f, BodyType.Dynamic);
            body.BodyType = BodyType.Dynamic;
        }

This is Draw operation:

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin(0, null, null, null, null, null, camera.View);
            ship.Draw(spriteBatch);
            spriteBatch.End();
            base.Draw(gameTime);
        }

where ship.Draw is:

        public void Draw(SpriteBatch spriteBatch)
        {
            position = body.Position;
            spriteBatch.Draw(texture, ConvertUnits.ToDisplayUnits(position), null, Color.White, body.Rotation, origin, 1f, SpriteEffects.None, 0f);
        }

And this is an Update method:

        protected override void Update(GameTime gameTime)
        {
            world.Step((float)(gameTime.ElapsedGameTime.TotalMilliseconds * 0.001));
            camera.Update(gameTime);
            base.Update(gameTime);
        }

My problem is, that ship don't falls vertically ("down") but to the down-right corner. Is there any possibility to change that? If so, then how?

Thanks in advance,

Łukasz

        public void LoadContent(World world)
        {
            uint[] data = new uint[texture.Width * texture.Height];
            texture.GetData(data);
            Vertices vertices = PolygonTools.CreatePolygon(data, texture.Width, false);
            Vector2 centroid = -vertices.GetCentroid();
            vertices.Translate(ref centroid);
            origin = -centroid;
            vertices = SimplifyTools.ReduceByDistance(vertices, 4f);
            List<Vertices> list = BayazitDecomposer.ConvexPartition(vertices);
            Vector2 scale = new Vector2(ConvertUnits.ToSimUnits(1));
            foreach (Vertices v in list)
                vertices.Scale(ref scale);
            body = BodyFactory.CreateCompoundPolygon(world, list, 1f, BodyType.Dynamic);
            body.BodyType = BodyType.Dynamic;
            //body.Restitution = 0.3f;
            //body.Friction = 0.5f;
            body.OnCollision += Collision;
        }

 

 

 

Developer
Jan 20, 2012 at 12:24 AM
abery wrote:

 

        protected override void LoadContent()
        {
            world = new World(new Vector2(5));

            spriteBatch = new SpriteBatch(GraphicsDevice);
            ship = new Ship();
            ship.texture = Content.Load<Texture2D>("hull");

            ship.LoadContent(world);

            camera = new Camera2D(GraphicsDevice);
        }

My problem is, that ship don't falls vertically ("down") but to the down-right corner. Is there any possibility to change that? If so, then how?

Thanks in advance,

Łukasz

        public void LoadContent(World world)
        {
            uint[] data = new uint[texture.Width * texture.Height];
            texture.GetData(data);
            Vertices vertices = PolygonTools.CreatePolygon(data, texture.Width, false);
            Vector2 centroid = -vertices.GetCentroid();
            vertices.Translate(ref centroid);
            origin = -centroid;
            vertices = SimplifyTools.ReduceByDistance(vertices, 4f);
            List<Vertices> list = BayazitDecomposer.ConvexPartition(vertices);
            Vector2 scale = new Vector2(ConvertUnits.ToSimUnits(1));
            foreach (Vertices v in list)
                vertices.Scale(ref scale);
            body = BodyFactory.CreateCompoundPolygon(world, list, 1f, BodyType.Dynamic);
            body.BodyType = BodyType.Dynamic;
            //body.Restitution = 0.3f;
            //body.Friction = 0.5f;
            body.OnCollision += Collision;

Your problem is that you messed up the gravity. Vector2 (as the name implies) has two dimensions. So new Vector2(5) equals new Vector2(5f, 5f) ...see what you did there? ;)

Jan 20, 2012 at 9:49 PM

Thank you. thank you, thank you! At last it works! :)

Jan 20, 2012 at 9:53 PM
Edited Jan 21, 2012 at 10:46 AM

I have a problem. When I set up two ships, they of course collides, because they're in the same position. But when I try to change Position of one of them (no matter if during game or in ship.LoadContent), they still collides, even if each one is in different place on a map... Can you help me somehow?

 

 

Developer
Jan 21, 2012 at 5:20 PM

Can you show the code where you change its position?

Jan 23, 2012 at 9:28 PM
Edited Jan 23, 2012 at 9:42 PM

I use modified version of previously quoted ship.LoadContent:

public void LoadContent(World world, int x, int y) 
{
uint[] data = new uint[texture.Width * texture.Height];
texture.GetData(data);
Vertices vertices = PolygonTools.CreatePolygon(data, texture.Width, false);
Vector2 centroid = -vertices.GetCentroid();
vertices.Translate(ref centroid);
origin = -centroid;
vertices = SimplifyTools.ReduceByDistance(vertices, 4f);
List<Vertices> list = BayazitDecomposer.ConvexPartition(vertices);
Vector2 scale = new Vector2(ConvertUnits.ToSimUnits(1));
foreach (Vertices v in list)
vertices.Scale(ref scale);
body = BodyFactory.CreateCompoundPolygon(world, list, 1f, new Vector2(x, y)); // I try to set it here
body.BodyType = BodyType.Dynamic;

body.onCollision += Collision;
//body.Position = new Vector2(x, y); or here
}
public bool Collision(Fixture f1, Fixture f2, Contact contact)
{
return true;
}
 

  

Or in Draw method of ship:
        public void Draw(SpriteBatch spriteBatch)
        {
            position = body.Position;
            position.X += offset.X;
            position.Y += offset.Y;
            spriteBatch.Draw(texture, ConvertUnits.ToDisplayUnits(position), null, Color.White, body.Rotation, origin, zoom, SpriteEffects.None, 0f);
        }


So no matter if I set, for example:

ship1.LoadContent(world, 0, 0);

and

ship2.LoadContent(world, 10, 0); // 10 is for example, I tried also many other values

or

ship2.offset.X = 10;
ship2.LoadContent(world, 0, 0);

they still collides...