1
\$\begingroup\$

In the below code, is the method I use to move a bullet to its destination and stop when bullet is near to destination. But the problem is the bullet is stopping not accurately, sometimes there's a small offset or span or sometimes is accurate depends on the angle.

public Vector2 getVelocity(Vector2 currentPosition, Vector2 targetPosition) {
    Vector2 targetDirection = targetPosition.cpy().sub(currentPosition);
    return targetDirection
            .nor();
}

final float SPEED = 6;
float pos = bulletPosition.len();
float des = bullet.destination.len();
float tol = Constants.TIME_STEP * SPEED;

if(MathUtils.isEqual(pos,des, tol)) {
    body.setLinearVelocity(0,0); 
} else {
    body.setLinearVelocity(getVelocity(bulletPosition, destination).scl(SPEED));
}

[SOLVED]

if(MathUtils.isEqual(pos, des, tol)) {
     // quick & dirty way
     body.setTransform(destination, angle);
     // better way
     ...
}
\$\endgroup\$
  • \$\begingroup\$ What does MathUtils.isEqual do exactly, is it a direct comparision or an approximation? \$\endgroup\$ – S. Tarık Çetin Jul 30 '16 at 14:30
  • \$\begingroup\$ here is the link for MathUtils java doc link \$\endgroup\$ – ronscript Jul 30 '16 at 15:16
2
\$\begingroup\$

Quick & Dirty Way:
You can simply teleport the bullet to location you want after it stops.

Long & Better Way:
For the last moments of movement, you can disable the physics and control the movement yourself by lerp'ing (or any other way, lerp is my favorite) towards the target. This way, you can stop the bullet whenever you want.


Edit
I would solve the situation like this in Unity, and actually this might be a better way than the two above:

float minDisableDistance, minStopDistance, bulletSpeed;
Transform target;

// I'm skipping the parts that you create the bullet, and simply do the job on these:
GameObject bullet; //Assuming this is the bullet.
Rigidbody bulletRigidbody; //Assuming this is the rigidbody of bullet.

void Update()
{
    Vector3 relPos = target.position - bullet.postion;
    float distance = relPos.magnitude;

    if(distance > minDisableDistance)
    {
        //use physics.
    }
    else
    {
        bulletRigidbody.velocity = 0;

        if(distance > minStopDistance)
        {
            bullet.position += bulletSpeed * relPos.normalized * time.deltaTime;
        }
        else
        {
            bullet.position = target.position;
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ ***** it works perfectly! I just tried the "quick & dirty way" . I want to try the better way \$\endgroup\$ – ronscript Jul 30 '16 at 15:23
  • \$\begingroup\$ can you give me a little pseudo-code on how do I properly do the properway? \$\endgroup\$ – ronscript Jul 30 '16 at 15:25
  • \$\begingroup\$ @ronscript I can't, I have never used libgdx or box2d. The wikipedia article about lerp is great, take a look: en.wikipedia.org/wiki/Linear_interpolation \$\endgroup\$ – S. Tarık Çetin Jul 30 '16 at 15:28
  • \$\begingroup\$ On the lerp method third parameter t. Because my bullet is speed is 6. the t is also 6? \$\endgroup\$ – ronscript Jul 30 '16 at 15:33
  • \$\begingroup\$ @ronscript No, the third parameter indicates the "ratio" of movement from beginning to end (and third parameter should be in between 0-1 in general). For example if it is 0.5, it means the result is exactly the middle of start and end points. \$\endgroup\$ – S. Tarık Çetin Jul 30 '16 at 15:39
0
\$\begingroup\$

I found out the best way! I just use the Vector2 dst method to get the distance between the destination. And hooray!! it was accurate!

float distance = bulletPosition.cpy().dst(destination);

float tol = (Constants.TIME_STEP * SPEED) / 2;

if(distance <= tol) {

     body.setLinearVelocity(0, 0);

}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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