XNA farseer 3.3.1 - Collision detection help!

Topics: User Forum
Feb 4, 2013 at 9:52 PM
Hello before i ask my question i would like to mention i am very new to farseer physics engine.

lol okay, so i am creating a game where it is a top down 2D car type of game. You controll a player and move around and after i learn how to use collision detection with this engine i would like the player to be able to enter the vehicle with the press of a button on collsion.
            myPlayer.Body.OnCollision += new OnCollisionEventHandler(Player_OnCollision);
            Car.Body.OnCollision += new OnCollisionEventHandler(player.Player_OnCollision);

        public bool Player_OnCollision(Fixture fixtureA, Fixture fixtureB, FarseerPhysics.Dynamics.Contacts.Contact contact)
        {
            KeyboardState keyState = Keyboard.GetState();

            if (keyState.IsKeyDown(Keys.E))
            {
                Player_Draw = false;
            }

            return true;
        }
i can stop the player from drawing with this code but i have to hold E down befor i run into the car.. i want to be able to walk up to the car and press E once to enter.. i know i shouldnt be using isKeyDown() for something like that.

im planing on stopping the player from being drawn and have the user control the car, while at the same time the player character is not being drawn and is following the car.

Thanks for any help i recieve.
Feb 4, 2013 at 10:27 PM
Edited Feb 4, 2013 at 10:29 PM
I have several suggestions.

First, the way you have set up the collision handlers is redundant. I would use only one collision handler for myPlayer and then check fixtureB to see if it is the car body. You could accomplish this by setting Userdata for the car and checking that in Player_OnCollision, although I do not know if that is the best practice. Others might have better suggestions.

As for polling for input on the E key, you don't want to put that in the OnCollision handler or, as you've observed, it will only work if the key is already pressed at the moment of collision. The OnCollision handler is only called at the first moment of contact between the player and another object (not just the car but any object). Instead, you should set a value, such as bool touchingCar = true; and use a complementary OnSeparation handler to set it to false again if the player loses contact with the car.

Then in your update cycle you can check the state of the E key and touchingCar and change the player state accordingly.

I hope this helps.
Feb 4, 2013 at 11:07 PM
First of all thank you for the help and guiding me in the right direction. so far i got it to do what i want as of right now let me post the code.
 bool Player_Draw = true;
 bool Is_Touching = false;

//  players  loadContent()
myPlayer.Body.UserData = "Player";
 myPlayer.Body.OnCollision += Player_OnCollision;

// in Cars LoadContent()
Car.Body.UserData = "Car";

// in Update()

            if (keyState.IsKeyDown(Keys.E) && Is_Touching == true)
            {
                Player_Draw = false;
            }

//Collision function
        public bool Player_OnCollision(Fixture fixtureA, Fixture fixtureB, FarseerPhysics.Dynamics.Contacts.Contact contact)
        {
            if (fixtureB.Body.UserData == "Car")
            {
                Is_Touching = true;
                return true;
            }
            Is_Touching = false;
            return true;
        }

// Draw function
        public void Draw(SpriteBatch spriteBatch)
        {
            if (Player_Draw == true)
            {
                myPlayer.Draw(spriteBatch);
            }
        }
There is much more stuff in the loadcontent but i decided to only post what is relevant to this disscussion.

Later in the project i plan to have a list or cars, and i want to have the player able to enter and exit each car and of course controll it.

I love this physics engine i am porting my old project into this one because my physics were horrible and this physics engine does it so well.

Thank you for help

any more advice will be appreciated
Feb 5, 2013 at 3:06 AM
Edited Feb 5, 2013 at 3:07 AM
One more thing. The way you have your collision handler set up, it will set Is_Touching = true if you collide with the car but will only set it false if you collide with something other than the car, so you'd still be able to enter the car even if you walked away from it. This also means that if the player collides with something while still touching the car, Is_Touching will be set to false and you'll no longer be able to enter the car. Instead, you should set up an OnSeparation handler.
myPlayer.OnSeparation += new OnSeparationEventHandler(Player_OnSeparation);

public override void Player_OnSeparation(Fixture fixtureA, Fixture fixtureB)
{
if (fixtureB.Body.UserData == "Car")
{
Is_Touching = false;
}
}
I'm glad I had enough experience with this to be of help. Hopefully my karma balance will lead someone to help me with my own FixedPrismaticJoint issues.
Feb 8, 2013 at 4:39 AM
Thank you i didn't know about that like i said im still new to this physics engine and enjoying it more and more as i understand how to use it.

Thanks again for the help.