Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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.

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

4 Answers 4

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());
share|improve this answer

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.

share|improve this answer

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

share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.