views:

38

answers:

1

I wrote some code for a projectile class in my game that makes it track targets if it can:

            if (_target != null && !_target.IsDead)
            {
                Vector2 currentDirectionVector = this.Body.LinearVelocity;
                currentDirectionVector.Normalize();
                float currentDirection = (float)Math.Atan2(currentDirectionVector.Y, currentDirectionVector.X);
                Vector2 targetDirectionVector = this._target.Position - this.Position;
                targetDirectionVector.Normalize();
                float targetDirection = (float)Math.Atan2(targetDirectionVector.Y, targetDirectionVector.X);
                float targetDirectionDelta = targetDirection - currentDirection;
                if (MathFunctions.IsInRange(targetDirectionDelta, -(Info.TrackingRate * deltaTime), Info.TrackingRate * deltaTime))
                {
                    Body.LinearVelocity = targetDirectionVector * Info.FiringVelocity;
                }
                else if (targetDirectionDelta > 0)
                {
                    float newDirection = currentDirection + Info.TrackingRate * deltaTime;
                    Body.LinearVelocity = new Vector2(
                        (float)Math.Cos(newDirection),
                        (float)Math.Sin(newDirection)) * Info.FiringVelocity;
                }
                else if (targetDirectionDelta < 0)
                {
                    float newDirection = currentDirection - Info.TrackingRate * deltaTime;
                    Body.LinearVelocity = new Vector2(
                        (float)Math.Cos(newDirection),
                        (float)Math.Sin(newDirection)) * Info.FiringVelocity;
                }
            }

This works sometimes, but depending on the relative angle to the target projectiles turn away from the target instead. I'm stumped; can someone point out the flaw in my code?

Update: thinking about it and trying stuff has led me to the conclusion that it has something to do with when the direction (being in radians) is below 0 and the current projectile angle is above 0.

+1  A: 

The variable targetDirectionDelta is not always the shortest direction to the target. If the absolute value of targetDirectionDelta is greater than PI radians, it will appear the projectile is turning away from the target. Turning in the other direction is shorter and expected.

Example:

currentDirection = 2
targetDirection = -2

The projectile can turn -4 radians (in the negative direction), or 2*(PI-2) radians (about 2.2 radians) (in the positive direction).

For this case, your code always calculates the longer direction, but you are expecting the projectile to turn towards the shorter direction:

targetDirectionDelta = targetDirection - currentDirection

Leftium
Yes, somehow i forgot to say this. I solved it by adding in a check to see if `targetDirectionDelta` is above pi or below -pi first, which tells me that i would take the long way otherwise.
RCIX