Search code examples
mathvectorbox2dgame-physicstrigonometry

Getting a turret to turn until facing a target direction?


I'm trying to get a turret to face an enemy, I have all the logic setup my problem is trigonometry.

Here's an illustration I've draw:

enter image description here Here's the code I've got so far:

//Get the target degree (Is returned with a box2d world facing right, so make it face up)
        float targetDegree = (((currentLockedEnemy.getBody().getPosition().sub(getBody().getPosition()).angle() + 270f) % 360f));

        //Get the turret current facing degree.
        float currentTurretFacingDirection = (getBody().getAngle() * MathUtils.radiansToDegrees) % 360f;
        //Because box2d can go negative angles.
        if(currentTurretFacingDirection < 0f){
            currentTurretFacingDirection += 360f;
        }

        //Because it will go over 360 to 0. Make it within the 180 to -180 range. Fixes the skip
        if(currentTurretFacingDirection > 180f){
            currentTurretFacingDirection -= 360f;
        }
        if(targetDegree > 180f){
            targetDegree -= 360f;
        }

        //Subtract the current turret facing angle from the target.
        float rotationalOffset = targetDegree - currentTurretFacingDirection;


        //If it's greater than the accuracy turn towards the object.
        if(Math.abs(rotationalOffset) > getAccuracy())
        {

            if(rotationalOffset > 0f)
            {
                this.revoluteJoint.setMotorSpeed(TURN_SPEED);
            }
            else
            {
                this.revoluteJoint.setMotorSpeed(-TURN_SPEED);
            }
        }
        else{
            this.revoluteJoint.setMotorSpeed(0f);
        }

My question is, how on earth do I get the turret to turn at the right angle?

FYI I'm using Box2d with Libgdx and the language is JAVA.


Solution

  • First off, you should take the angle of the target relative to the turret, not the other way around. This can be fixed by swapping the position vectors in the subtraction.

    Second, once you have the target angle, subtracting the turret's current angle will give you the rotation offset you need to apply. Then, use some modular arithmetic and a few ifs to shift that offset between -180 and +180. If the result is positive, you need to rotate one way. If it's negative, you need to rotate the other way. If the result is "close enough" to zero, then the turret is aiming "close enough" to the target ("close enough" depends on how accurate you need it to be).