2
\$\begingroup\$

I want to create a body based on its texture. But the body I created just falls through the floor instead of colliding and resting on it.

My Code:

using FarseerPhysics;
using FarseerPhysics.Common;
using FarseerPhysics.Common.Decomposition;
using FarseerPhysics.Common.PolygonManipulation;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;

namespace MonTest2
{
/// <summary>
/// This is the main type for your game.
/// </summary>
public class Game1 : Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    KeyboardState oldKeyState;
    //SpriteFont font;

    World world;

    Body ball;
    Body floor;

    Texture2D floorTexture;

    //Camera

    Matrix view;
    Vector2 cameraPosition;
    Vector2 screenCenter;
    Vector2 floorOrigin;

    Texture2D texture;
    Vector2 _origion;
    Body _compound;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        world = new World(new Vector2(0f, 9.82f)); //world with natural gravity
        graphics.PreferredBackBufferHeight = 720;
        graphics.PreferredBackBufferWidth = 1080;
    }


    protected override void Initialize()
    {
        IsMouseVisible = true;
        base.Initialize();
    }


    protected override void LoadContent()
    {

        spriteBatch = new SpriteBatch(GraphicsDevice);
        //init camera
        view = Matrix.Identity;
        cameraPosition = Vector2.Zero;
        screenCenter = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2f, graphics.GraphicsDevice.Viewport.Height / 2f);

        //load textures
        floorTexture = Content.Load<Texture2D>("GroundSprite");
        texture = Content.Load<Texture2D>("EnemyShip");

        //set centers of textures
        floorOrigin = new Vector2(floorTexture.Width / 2f, floorTexture.Height / 2f);

        // Farseer expects objects to be scaled to MKS (meters, kilos, seconds)
        // 1 meters equals 64 pixels here
        ConvertUnits.SetDisplayUnitToSimUnitRatio(64f);

        /* Ground */
        Vector2 groundPosition = ConvertUnits.ToSimUnits(screenCenter) + new Vector2(0, 4f);

        floor = BodyFactory.CreateRectangle(world, ConvertUnits.ToSimUnits(512f), ConvertUnits.ToSimUnits(64f), 1f, groundPosition);
        //floor.BodyType = BodyType.Static;
        floor.IsStatic = true;
        floor.Restitution = 0.3f;
        floor.Friction = 0.5f;

        /*enemy ship*/
        uint[] data = new uint[texture.Width * texture.Height];
        texture.GetData(data);
        Vertices textureVertices = PolygonTools.CreatePolygon(data, texture.Width, false);
        Vector2 centroid = -textureVertices.GetCentroid();
        textureVertices.Translate(ref centroid);
        _origion = -centroid;
        textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 4f);
        List<Vertices> list = Triangulate.ConvexPartition(textureVertices, TriangulationAlgorithm.Bayazit);
        _compound = BodyFactory.CreateCompoundPolygon(world, list, 1f, BodyType.Dynamic);
        _compound.BodyType = BodyType.Dynamic;

    }


    protected override void UnloadContent()
    {

    }


    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();
        //We update the world
        world.Step((float)gameTime.ElapsedGameTime.TotalMilliseconds * 0.001f);


        base.Update(gameTime);
    }


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

        spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, view);

        spriteBatch.Draw(texture, ConvertUnits.ToDisplayUnits(_compound.Position), null, Color.White, _compound.Rotation, _origion, 1f, SpriteEffects.None, 0f);
        System.Diagnostics.Debug.WriteLine(ConvertUnits.ToDisplayUnits(_compound.Position).ToString() + "ship");

        spriteBatch.Draw(floorTexture, ConvertUnits.ToDisplayUnits(floor.Position), null, Color.White, 0f, floorOrigin, 1f, SpriteEffects.None, 0f);

        spriteBatch.End();

        base.Draw(gameTime);
    }

This Code is copy of the Farseer Hello world sample and from the AdvancedDemo1.cs for the EnemyShip. Am I missing something that'll make these bodies collide with each other? The floor body and the _compound body should be able to collide with each other, but the _compound just falls through.

SpaceShip: EnemyShip

Ground: Ground

NuGet Packages used:

1.Monogame.Framework.Linux
2.FarseerPhysics MonoGame (Unofficial Package)
\$\endgroup\$

Your Answer

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

Browse other questions tagged or ask your own question.