Converting Box2D Car Demo to Farseer

Topics: Developer Forum, User Forum
Mar 2, 2011 at 5:24 PM

I've been putting to getting an example of a top down racing game for Advanced samples.

I cant seem to work out what this means in c#

killOrthogonalVelocity(leftWheel);
	killOrthogonalVelocity(rightWheel);
	killOrthogonalVelocity(leftRearWheel);
	killOrthogonalVelocity(rightRearWheel);
 
	//Driving
	var ldirection = leftWheel.GetXForm().R.col2.Copy();
	ldirection.Multiply(engineSpeed);
	var rdirection = rightWheel.GetXForm().R.col2.Copy()
	rdirection.Multiply(engineSpeed);
	leftWheel.ApplyForce(ldirection, leftWheel.GetPosition());
	rightWheel.ApplyForce(rdirection, rightWheel.GetPosition());
 
	//Steering
	var mspeed:Number;
	mspeed = steeringAngle - leftJoint.GetJointAngle();
	leftJoint.SetMotorSpeed(mspeed * STEER_SPEED);
	mspeed = steeringAngle - rightJoint.GetJointAngle();
	rightJoint.SetMotorSpeed(mspeed * STEER_SPEED);

I need this so i can get my car to move and turn.
My code so far is

            PolygonShape box2 = new PolygonShape(1f);
            box2.SetAsBox(1f, 2f);
            PolygonShape box = new PolygonShape(1f);
            box.SetAsBox(0.3f, 0.5f);

            body = new Body(World);
            body.BodyType = BodyType.Dynamic;
            body.LinearDamping = 1;
            body.AngularDamping = 1;
            body.Position = StartingPosition;
            body.CreateFixture(box2);

            leftwheel = new Body(World);
            leftwheel.BodyType = BodyType.Dynamic;
            leftwheel.Position = StartingPosition - leftfrontwheelpostion;
            leftwheel.CreateFixture(box);

            rightwheel = new Body(World);
            rightwheel.BodyType = BodyType.Dynamic;
            rightwheel.Position = StartingPosition - rightfrontwheelpostion;
            rightwheel.CreateFixture(box);

            Body leftbackwheel = new Body(World);
             leftbackwheel.BodyType = BodyType.Dynamic;
            leftbackwheel.Position = StartingPosition - leftrearwheelpostion;
            leftbackwheel.CreateFixture(box);

            Body rightbackwheel = new Body(World);
            rightbackwheel.BodyType = BodyType.Dynamic;
            rightbackwheel.Position = StartingPosition - rightrearwheelpostion;
            rightbackwheel.CreateFixture(box);

            //RevoluteJoint wheelrvj = new RevoluteJoint(body, leftwheel, leftwheel.GetWorldPoint);
            // Car

            rightrjd = new RevoluteJoint(body, rightwheel,
                          body.GetLocalPoint(rightwheel.Position),
                          Vector2.Zero);

            leftrjd = new RevoluteJoint(body, leftwheel,
                          body.GetLocalPoint(leftwheel.Position),
                          Vector2.Zero);

            RevoluteJoint rightpjd = new RevoluteJoint(body, rightwheel,
                                      body.GetLocalPoint(rightwheel.Position),
                                      Vector2.Zero);

            PrismaticJoint leftpjd = new PrismaticJoint(body, leftbackwheel, body.Position, leftrearwheelpostion, leftrearwheelpostion);

            leftwheel.IgnoreCollisionWith(body);
            body.IgnoreCollisionWith(leftwheel);
            leftbackwheel.IgnoreCollisionWith(body);
            body.IgnoreCollisionWith(leftbackwheel);

            rightwheel.IgnoreCollisionWith(body);
            body.IgnoreCollisionWith(rightwheel);
            rightbackwheel.IgnoreCollisionWith(body);
            body.IgnoreCollisionWith(rightbackwheel);
I just need help with the input. Thank You

Mar 2, 2011 at 10:36 PM

I've uploaded the code to patchs.

I've updated the controls, however some of the math for Acceleration and Steering is'nt right.

  private void killOrthogonalVelocity(Body body)
        {
            Vector2 sidewaysAxis;
            Vector2 velocity;
            Vector2 localPoint = new Vector2(0, 0);
            velocity = this.body.GetLinearVelocityFromLocalPoint(localPoint);

           // Vector2 sidewaysAxis = this.body.GetTransform();
           
            Transform tmp;
            this.body.GetTransform(out tmp);
            sidewaysAxis = tmp.R.Col2;
           sidewaysAxis = Vector2.Multiply(sidewaysAxis, Vector2.Dot(velocity, sidewaysAxis));
           this.body.ApplyLinearImpulse(sidewaysAxis);


        }
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            killOrthogonalVelocity(leftwheel);
            killOrthogonalVelocity(rightwheel);
            killOrthogonalVelocity(leftbackwheel);
            killOrthogonalVelocity(rightbackwheel);

            Vector2 localPoint = new Vector2(0, 0);
            Vector2 ldirection = leftwheel.GetLinearVelocityFromLocalPoint(localPoint);
            ldirection = Vector2.Multiply(ldirection,);
            leftwheel.ApplyForce(ldirection,leftwheel.Position);
                        Vector2 rdirection = rightwheel.GetLinearVelocityFromLocalPoint(localPoint);
            rdirection = Vector2.Multiply(ldirection,);
            rightwheel.ApplyForce(ldirection,leftwheel.Position);


            float mspeed;
             float mspeed2;
            mspeed = steeringangle - leftrjd.JointAngle();
            leftrjd.MotorSpeed = mspeed * steer_speed;
            mspeed2 = steeringangle - rightrjd.JointAngle();
            rightrjd.MotorSpeed = mspeed * steer_speed;
}

   public override void HandleInput(InputHelper input, GameTime gameTime)
        {
            if (input.KeyboardState.IsKeyDown(Keys.W))
            {
                body.Awake = true;
                enginespeed = -housepower;
                
            }
            else if (input.KeyboardState.IsKeyDown(Keys.D))
            {
                steeringangle = max_steer_angle;                
            
            }
            else if (input.KeyboardState.IsKeyDown(Keys.A))
            {
                steeringangle = -max_steer_angle;              
            }
            else
            {
              
            }

            base.HandleInput(input, gameTime);
        }

 

If someone could help me out that would be great and i can update the Advanced samples

 

Thanks

Coordinator
Mar 4, 2011 at 9:20 PM

What is the source of this code?

Mar 4, 2011 at 11:58 PM

I converted http://www.emanueleferonato.com/2009/04/06/two-ways-to-make-box2d-cars/
to C# and to use Farseer however i dont understand the way its moves forward thou. So looking for abit of help so i can add it to advanced samples

Coordinator
Mar 5, 2011 at 2:32 AM

Well, you have a couple of problems in your code. It does not compile as you don't supply the last argument for the Multiply method. You also need to use the right variables. Example:

float mspeed;
float mspeed2;
mspeed = steeringangle - leftrjd.JointAngle();
leftrjd.MotorSpeed = mspeed * steer_speed;
mspeed2 = steeringangle - rightrjd.JointAngle();
rightrjd.MotorSpeed = mspeed * steer_speed;

mspeed2 is assigned, but never used. I suspect it is used in rightrjd.MotorSpeed.

I've taken a look at the code in the link you posted, and I've ported the sample to work with FPE. However, I can't seem to find any steering correcting code even tho it is present in the sample on the link you posted. Here is the code:

using System;
using System.Text;
using FarseerPhysics.Common;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Joints;
using FarseerPhysics.Collision.Shapes;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace FarseerPhysics.SamplesFramework
{
    internal class GameDemo2 : PhysicsGameScreen, IDemoScreen
    {
        #region IDemoScreen Members

        public string GetTitle()
        {
            return "Top Down Car";
        }

        public string GetDetails()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("TODO: Add sample description!");
            sb.AppendLine(string.Empty);
            sb.AppendLine("GamePad:");
            sb.AppendLine("  - Exit to menu: Back button");
            sb.AppendLine(string.Empty);
            sb.AppendLine("Keyboard:");
            sb.AppendLine("  - Exit to menu: Escape");
            return sb.ToString();
        }

        #endregion

        const float MaxSteerAngle = Settings.Pi / 3;
        const float SteerSpeed = 1.5f;
        const float Horsepower = 40f;
        Vector2 _carStartingPosition = new Vector2(10, 10);

        Vector2 _leftRearWheelPosition = new Vector2(-1.5f, 1.9f);
        Vector2 _rightRearWheelPosition = new Vector2(1.5f, 1.9f);
        Vector2 _leftFrontWheelPosition = new Vector2(-1.5f, -1.9f);
        Vector2 _rightFrontWheelPosition = new Vector2(1.5f, -1.9f);

        float _engineSpeed;
        float _steeringAngle;

        private Body _leftWheel;
        private Body _rightWheel;
        private Body _leftRearWheel;
        private Body _rightRearWheel;
        private Body _body;
        private RevoluteJoint _leftJoint;
        private RevoluteJoint _rightJoint;

        public override void LoadContent()
        {
            base.LoadContent();

            World.Gravity = new Vector2(0f, 0f);

            _body = new Body(World);
            _body.BodyType = BodyType.Dynamic;
            _body.LinearDamping = 1;
            _body.AngularDamping = 1;
            _body.Position = _carStartingPosition;

            _leftWheel = new Body(World);
            _leftWheel.BodyType = BodyType.Dynamic;
            _leftWheel.Position = _carStartingPosition + _leftFrontWheelPosition;

            _rightWheel = new Body(World);
            _rightWheel.BodyType = BodyType.Dynamic;
            _rightWheel.Position = _carStartingPosition + _rightFrontWheelPosition;

            _leftRearWheel = new Body(World);
            _leftRearWheel.BodyType = BodyType.Dynamic;
            _leftRearWheel.Position = _carStartingPosition + _leftRearWheelPosition;

            _rightRearWheel = new Body(World);
            _rightRearWheel.BodyType = BodyType.Dynamic;
            _rightRearWheel.Position = _carStartingPosition + _rightRearWheelPosition;

            // define our shapes
            PolygonShape box = new PolygonShape(1);
            box.SetAsBox(1.5f, 2.5f);
            _body.CreateFixture(box);

            //Left Wheel shape
            PolygonShape leftWheelShape = new PolygonShape(1);
            leftWheelShape.SetAsBox(0.2f, 0.5f);
            _leftWheel.CreateFixture(leftWheelShape);

            //Right Wheel shape
            PolygonShape rightWheelShape = new PolygonShape(1);
            rightWheelShape.SetAsBox(0.2f, 0.5f);
            _rightWheel.CreateFixture(rightWheelShape);

            //Left Wheel shape
            PolygonShape leftRearWheelShape = new PolygonShape(1);
            leftRearWheelShape.SetAsBox(0.2f, 0.5f);
            _leftRearWheel.CreateFixture(leftRearWheelShape);

            //Right Wheel shape
            PolygonShape rightRearWheelShape = new PolygonShape(1);
            rightRearWheelShape.SetAsBox(0.2f, 0.5f);
            _rightRearWheel.CreateFixture(rightRearWheelShape);

            _leftJoint = new RevoluteJoint(_body, _leftWheel, _body.GetLocalPoint(_leftWheel.Position), Vector2.Zero);
            _leftJoint.MotorEnabled = true;
            _leftJoint.MaxMotorTorque = 100;
            World.AddJoint(_leftJoint);

            _rightJoint = new RevoluteJoint(_body, _rightWheel, _body.GetLocalPoint(_rightWheel.Position), Vector2.Zero);
            _rightJoint.MotorEnabled = true;
            _rightJoint.MaxMotorTorque = 100;
            World.AddJoint(_rightJoint);

            PrismaticJoint leftRearJoint = new PrismaticJoint(_body, _leftRearWheel, _leftRearWheelPosition, Vector2.Zero, new Vector2(1, 0));
            leftRearJoint.LimitEnabled = true;
            leftRearJoint.LowerLimit = leftRearJoint.UpperLimit = 0;
            World.AddJoint(leftRearJoint);

            PrismaticJoint rightRearJoint = new PrismaticJoint(_body, _rightRearWheel, _rightRearWheelPosition, Vector2.Zero, new Vector2(1, 0));
            rightRearJoint.LimitEnabled = true;
            rightRearJoint.LowerLimit = rightRearJoint.UpperLimit = 0;
            World.AddJoint(rightRearJoint);
        }

        private void killOrthogonalVelocity(Body body)
        {
            Vector2 localPoint = new Vector2(0, 0);
            Vector2 velocity = body.GetLinearVelocityFromLocalPoint(localPoint);

            Transform tmp;
            body.GetTransform(out tmp);
            Vector2 sidewaysAxis = tmp.R.Col2;

            sidewaysAxis = Vector2.Multiply(sidewaysAxis, Vector2.Dot(velocity, sidewaysAxis));
            body.LinearVelocity = sidewaysAxis;
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            killOrthogonalVelocity(_leftWheel);
            killOrthogonalVelocity(_rightWheel);
            killOrthogonalVelocity(_leftRearWheel);
            killOrthogonalVelocity(_rightRearWheel);

            //Driving
            Transform tmp;
            _leftWheel.GetTransform(out tmp);
            Vector2 ldirection = tmp.R.Col2 * _engineSpeed;

            Transform tmp2;
            _rightWheel.GetTransform(out tmp2);
            Vector2 rdirection = tmp.R.Col2 * _engineSpeed;

            _leftWheel.ApplyForce(ldirection);
            _rightWheel.ApplyForce(rdirection);

            //Steering
            float mspeed = _steeringAngle - _leftJoint.JointAngle;
            _leftJoint.MotorSpeed = mspeed * SteerSpeed;
            mspeed = _steeringAngle - _rightJoint.JointAngle;
            _rightJoint.MotorSpeed = mspeed * SteerSpeed;

            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
        }

        public override void HandleInput(InputHelper input, GameTime gameTime)
        {
            if (input.IsNewKeyPress(Keys.W))
            {
                _engineSpeed = -Horsepower;
            }
            else if (input.IsNewKeyPress(Keys.S))
            {
                _engineSpeed = Horsepower;
            }
            else if (input.IsNewKeyPress(Keys.D))
            {
                _steeringAngle = MaxSteerAngle;
            }
            else if (input.IsNewKeyPress(Keys.A))
            {
                _steeringAngle = -MaxSteerAngle;
            }

            base.HandleInput(input, gameTime);
        }
    }
}

Mar 5, 2011 at 3:02 AM

Thank You, you are da man!

Ill add a statement that see's if the user is turning and if not the put the _steeringAngle to 0;

Im off to bed, but ill sort out tommorrow and post the last update that should have Car demo working perfect once ive done it.

 

Thank you genbox