I have a weird problem with my game, namely that units all the sudden bend towards a different angle when they're approaching said object/location.
This is the idea: The game is a 2D tile-based RTS, and when units are moving, they calculate their angle towards to target(-area) and update their position accordingly. This happens every frame to make sure the unit arrives at the exact center of the tile.
My code to calculate the angle is:
protected float CalculateDesiredAngle(float opposite, float adjacent, out float hypotenuse)
{
// Calculate the desired angle to the unit
hypotenuse = (float)Math.Sqrt(opposite * opposite + adjacent * adjacent);
float desiredAngle = Math.Abs((float)Math.Atan(opposite / adjacent));
// Correct the angle along the unit circle
if (opposite < 0.0f)
{
if (adjacent == 0.0f)
desiredAngle += (float)Math.PI;
else if (adjacent > 0)
desiredAngle += (float)Math.PI;
else
desiredAngle += (float)Math.PI * 1.5f;
}
else if (opposite > 0.0f)
{
if (adjacent > 0)
desiredAngle += (float)Math.PI * 0.5f;
}
else
{
if (adjacent > 0.0)
desiredAngle += (float)Math.PI;
}
// Correct the desiredAngle so it's not negative or higher than 2 PI
if (desiredAngle >= (float)Math.PI * 2)
desiredAngle -= (float)Math.PI * 2;
else if (desiredAngle < 0.0f)
desiredAngle += (float)Math.PI * 2;
return desiredAngle;
}
It checked by not moving the unit, and it worked, except that 0.0 points eastwards. Not a problem, since I can change how the unit is position when drawing.
During update, I do this:
Point next = path[0];
nextTile.X = next.X * Tile.Size + Tile.Size / 2;
nextTile.Y = next.Y * Tile.Size + Tile.Size / 2;
float hypotenuse;
float desiredAngle = CalculateDesiredAngle((next.X * Tile.Size + Tile.Size / 2) - Position.X, (next.Y * Tile.Size + Tile.Size / 2) - Position.Y, out hypotenuse);
if (angle != desiredAngle) // Make sure we don't rotate too much
{
if (Rotate(desiredAngle, (float)Math.PI, deltaTime) != desiredAngle)
{
AdjustDirection();
return false; // We haven't reached the correct angle yet
}
AdjustDirection();
}
// ... Code related to reserving tiles, checking if movement can occur, etc.
float x = ((float)Math.Cos(angle) * speed) * deltaTime;
float y = ((float)Math.Sin(angle) * speed) * deltaTime;
// Some code related to rounding down movement
position.X += x;
position.Y += y;
Now, it starts out perfectly, and moves up:
Angle = 270,7619
Angle = 270,7822
Angle = 270,7832
Angle = 270,7843
Angle = 270,7854
...
Angle = 276,9893
Angle = 277,5833
Angle = 278,2739
Angle = 279,061
Angle = 279,9727
Angle = 280,9644
Angle = 282,0956
Angle = 283,4937
As you can see, the further it moves towards the target tile, the more the angle bends off to the east.
I have no idea what I am doing wrong here, so any help might be appreciated.
Toolmaker