Max speed moving a body

Jul 9, 2011 at 4:22 PM

First off I would like to thank you for making such a great physics engine.  It truly has saved me a lot of time in my development.  I'm currently working on an XNA game for WP7 using Farseer 3.3.1.  The game is a 2d side scrolling shooter with a flying body (Zero gravity world).  Currently I am using a virtual thumbstick to control my body's position in the world.  I would like to give my body a Min Speed and Max Speed but I cannot figure out how to do this using ApplyForce or updating LinearVelocity.  Also, if my controls move from right to left quickly, I do not want there to be any drag on the body (Basically move immediately to the left or vise versa).   The following sudo code shows how I am updating my body's position:



float direction = virtualThumbStick.LeftThumbStick;

float speed = 10;

velocity += direction * speed;

body.LinearVelocity += ConvertUnits.ToSimUnits(velocity);

velocity *= .98f;


Jul 11, 2011 at 2:37 PM

I remember having real trouble with this with a platformer I made last year. My movement updates ended up being quite complicated to get the motion I wanted. Unforunately, I don't have the code any more or I'd take a look and hopefully give you some help!

One of the major problems we had was that we wanted the body to still be hit by objects and move with a bit of air control to push back against the force. You can't really do this with setting velocity because as soon as someone hits the body left and the player moves right, the velocity flip-flops straight away.

If I remember correctly, eventually we got things working quite well by applying a force or impulse until the player got to a certain speed. This, coupled with a drag coefficient meant that there was a kind of 'maximum' speed the player could achieve. The drag also slows the character down nicely, so while the direction might not change from frame to frame, it does change quite quickly but in a smooth way.

I imagine you could do the opposite for a minimum speed, but given the nature of your game (which I can only assume is a 2D constant scrolling flying shoot 'em up game) I would give the player a minimum 'x' coordinate and apply a force if the player is less than that coordinate unless the player is unable to move backwards, in which case, forget I said anything.

If you want to see the movement I got on my game, take a look at the games section under videos, the game is Legendary Crusaders. I have to warn you, this was made using farseer 2.something, so it may not work in 3.1.

Jul 18, 2011 at 8:04 PM

Thanks Grave.  The movement in your game looks really well done.  I managed to get the control over my body that I wanted by increasing the LinearDamping:


Body.LinearDamping = 3;
float speed = 50;

Vector2 force = new Vector2(leftStickDirection.X * speed, -leftStickDirection.Y * speed);
            force = (force - Body.LinearVelocity) * Body.Mass;



Using the above example, I get very little drag against the body, which means I can move from right to left or up to down quickly.  The only problem I have with
this method is the body is jerky while moving in the world.  I tried setting the Damping to zero as I am controlling the body but then the 'drag effect' comes back.  Any ideas how I can reduce that 'drag effect' while keeping control of the Body the way I want to?


Jul 19, 2011 at 2:51 PM

I'm not sure what you mean by 'drag effect'. Is it that the body accelerates slowly up to speed?

I'd keep the linear damping and try to find why the body is jerky while moving in the world. In what way is it jerky? Is it all the time during movement? Or just when you stop or start moving?

Jul 19, 2011 at 5:12 PM

To explain that 'drag effect' lets assume the following:

Body.LinearDamping = 0;
float speed = 50f;
Vector2 directionalForce = new Vector2(0,-10);
Body.ApplyLinearImpulse(ConvertUnits.ToSimUnits(force * speed)); //I really apply the 'speed' from a left thumbstick, but this is just as an example

Now lets say I apply this force for a few seconds, but I suddenly change to the opposite direction:

Vector2 directionalForce = new Vector2(0, 10);

The faster the body is going, the longer it takes for it to change direction.  To get the control I want, I do the following:

Body.LinearDamping = 3;
float speed = 100f; //I need to increase this value as I increase the LinearDamping
Vector2 directionalForce = new Vector2(0,-10);
Body.ApplyLinearImpulse(ConvertUnits.ToSimUnits(force * speed));

This gives me the precise control I want to move but it causes that 'jerky' feeling.  The body seems to do this throughout the movement.  It hard to tell watching the body but I can see it as I watch my background move when the camera is following the body.  I suspect this has to do with the increase in damping coupled with the 'speed'.  It looks like the force I give to the body gives it a slight movement (10 pixels or so) and the damping then tries to stop the body.  Since I apply a force constantly(as long as the player has the left thumbstick enabled), the body doesn't stop but you see that slight 'jerk'.  I hope I explained this well enough, if not I can upload a video to show an example.

Jul 19, 2011 at 5:55 PM

10 pixels sounds like a lot of movement. I think I know what you mean in terms of the camera moving. It could be that things are moving too fast for things to draw smoothly, or you'll need to add motion blur or something to the background to improve how things look.

A video might help though, at least it'll let me see what the game is doing.