# box2d and constant movement

i'm developing a game with a top down view, the players body is a circle. To move the character you need to tap on the screen and it moves to the spot.

To achieve this i'm saving the coordinate of the touch and call a method every frame which applies linear velocity to the body with a vector of the direction the body should go

``````_body->SetLinearVelocity(b2Vec2((a.x - currPos.x)/SPEED_RATIO,(size.height - a.y - currPos.y)/SPEED_RATIO));
//click position - current position, screen height - click position (since the y axis is flipped, (0,0) is in the bottom left ) - current position = vector of the direction we want to go
``````

now the problem with this is that the body slows down until it finally stops when getting closer to the point we want it to go, since the closer we are to that point the lenght of the vector gets smaller. Besides that i've read that it's bad practice to set linear velocity in box2d and i should use apply force instead, but that way the forces would add up and overshoot the target where it's supposed to stop.

So what i'm asking is how to move a box2d body to a coordinate in constant speed.

-
Can you set the body's velocity to 0 once it reaches the destination? – Chuck D Mar 26 '12 at 1:48
Take a look at iforce2d.net/b2dtut/constant-speed – XiaoChuan Yu May 25 '12 at 5:19

## 4 Answers

I'm no expert on Box2D, but I think what you're looking for is dynamic friction or damping. Both of these will apply a counter-fource to the movement, so that, for a certain constant force, an equilibrium velocity is reached after an initial acceleration. I'm not sure if this is how Box2D models it, but in real physics dynamic damping is frequently modelled as proportional to current velolcity, so:

``````    acceleration = force - velocity * damping
=> 0 = force - maxVelocity * damping
<=> force = maxVelocity * damping
<=> damping = force / maxVelocity
``````

You must then calculate a point from the target where you stop applying the force, so that the damping will decelerate it until it reaches the target.

-

If you're doing this on every frame and want no negative acceleration then why don't you just no take into concideration the length of the vector between origin and target?

sudo:

``````1. onTouchEvent(): capture coords
2. onRender():
- Check if coordinates of body are on target yet
- True: Remove all forces from body.
- False: Apply force again(?)
``````

Another method would be to remove all friction and damping on the body depending on if there's contact with any other bodies, and what the gravity of the world might be.

Straight from box2d manual:

Damping

Damping is used to reduce the world velocity of bodies. Damping is different than friction because friction only occurs with contact. Damping is not a replacement for friction and the two effects should be used together.Damping parameters should be between 0 and infinity, with 0 meaning no damping, and infinity meaning full damping. Normally you will use a damping value between 0 and 0.1. I generally do not use linear damping because it makes bodies look float

-

Besides that i've read that it's bad practice to set linear velocity in box2d and i should use apply force instead, but that way the forces would add up and overshoot the target where it's supposed to stop.

Setting the linear velocity isn't necessarily a bad thing. You just don't want it to jump around so doing things like clamping the velocity is perfectly fine.

Anyways to answer you question I would apply a force of a fixed magnitude pointing to the last contact point. I would also create a finger sized sensor and use the BeginContact and EndContact events.

In the BeginContact event I would set the dampening of the circle to a very large amount (large enough to prevent the circle from moving out from under the finger) and block the application of forces to the circle.

For the EndContact event reset the dampening and unset the flag that prevents the circle from accepting forces.

Also its perfectly fine to teleport sensors around. So feel free to set the position directly to wherever the finger presses the screen.

-

You DO want to use applyForce() or applyLinearImpulse instead of setLinearVelocity().

I would recommend using applyLinearImpulse() to apply an impulse proportional to the distance between your object and it's destination divided by it's speed each update. I used Java, so excuse my C++ errors(not sure if I use a dot operator or whatever -> is), but it would be something like this:

``````applyLinearImpulse(b2Vec2((a.x-_body.getPosition().x)/SPEED_RATIO, (a.y-_body.getPosition().y)/SPEED_RATIO), _body.getWorldCenter());
``````
-