(XNA) No collision, no gravity

Topics: Developer Forum
Feb 2, 2013 at 10:11 PM
Edited Feb 2, 2013 at 10:25 PM
So I'm mixing XNA and Farseer, the first for graphics and the latter for collision and physics. If this is a horrible choice to start out with, tell me that as well.

In any case, I have set up a entity class upon which I build my other classes (players and enemies). However, none of the functions in Farseer seem to work. Nothing related to physics that is. I can walk through a box, my bullet gives no collision detection, nothing.

Main:
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    World world;

    //Create a lists
    List<Entity> entityList = new List<Entity>();

    //Player
    Player player;

    //Target
    Target target;

    //Others
    float framerate;

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

        graphics.PreferMultiSampling = false;
        graphics.ApplyChanges();

    }

    protected override void Initialize()
    {

        //Create world
        world = new World(new Vector2(0f,10f));

        base.Initialize();

    }

    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);

        //Create player
        player = new Player(BodyType.Dynamic, Content, entityList, world);
        entityList.Add(player);

        //Create target
        target = new Target(BodyType.Dynamic, Content, entityList, world);
        entityList.Add(target);
    }

    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }

    protected override void Update(GameTime gameTime)
    {

        framerate = 1 / (float)gameTime.ElapsedGameTime.TotalSeconds;

        // Allows the game to exit
        if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            this.Exit();

        //Update the world
        world.Step(1f);

        //Update players and entities
        player.Update();
        target.Update();

        base.Update(gameTime);
    }


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

        spriteBatch.Begin();

        //Draw target
        target.Draw(spriteBatch);

        //Draw player
        player.Draw(spriteBatch);

        spriteBatch.End();

        base.Draw(gameTime);
    }
}
Target (child of Entity):
class Target : Entity {
    public Target(BodyType newBodyType, ContentManager content, List<Entity> entitylist, World newWorld)
        : base(newBodyType, content, entitylist, newWorld) {

        //Get texture
        Texture2D texture = content.Load<Texture2D>("Enemies/Target");

        //Create farseer object
        Body body = BodyFactory.CreateRectangle(newWorld, ConvertUnits.ToSimUnits(texture.Width), ConvertUnits.ToSimUnits(texture.Height), 1f);
        body.Position = ConvertUnits.ToSimUnits(new Vector2(300f, 300f));

        Fixture fixture = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(texture.Width), ConvertUnits.ToSimUnits(texture.Height), 1, new Vector2(0f, 0f), body);
        fixture.UserData = "Target";

        //Set other stuff
        setWorld(newWorld);
        setBody(body);
        setFixture(fixture);
        setTexture(texture);
        Update();

    }

    public void Update() {

    }

    public void Draw(SpriteBatch spriteBatch) {

        spriteBatch.Draw(getTexture(), ConvertUnits.ToDisplayUnits(getBody().Position), null, Color.White, getBody().Rotation, new Vector2(getTexture().Width / 2, getTexture().Height / 2), 3f, SpriteEffects.None, 1f);

    }
}
Entity:
class Entity
{

    public List<Entity> entityList;

    //Get physics stuff
    Texture2D texture;
    BodyType bodytype;
    Fixture fixture;
    World world;
    Body body;

    public Entity(BodyType newBodyType, ContentManager content, List<Entity> entityList, World world){

        bodytype = newBodyType;
        this.world = world;
        this.entityList = entityList;

    }

    public void Update() {

        fixture.OnCollision += entityCollision;

    }

    public void Draw(SpriteBatch spriteBatch) {


    }

    public bool entityCollision(Fixture f1, Fixture f2, Contact contact) {

        Console.WriteLine("Collision detected!");
        Console.WriteLine("F1: " + f1.UserData);
        Console.WriteLine("F2: " + f2.UserData);
        return false;
    }
}
Coordinator
Feb 3, 2013 at 4:03 AM
Edited Feb 3, 2013 at 4:03 AM
First of all, you are sending 1f to the World.Step(). You should use something like 1/60, which is a lot less than 1.

Inside you Entity, you are creating a body with a rectangle shape, and then attaching a rectangle shape. Remove this code:
Fixture fixture = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(texture.Width), ConvertUnits.ToSimUnits(texture.Height), 1, new Vector2(0f, 0f), body);

Take a look at the HelloWorld project if you have trouble setting up Farseer Physics. If you still have problems, try packing your project and upload it to a fileshare service so we can have a look at it.