0
votes

I am developing a 2d plane fighting game, trying to design enemy AI. The AI is very simple: rotate the enemy towards the player, and fly forward. I have set up a function that takes the position of the player and returns the rotation value the enemy should try to achieve to be flying directly at them, as followed:

        public function getFlyAngle( player:PlaneGeneric ):Number
    {
        var playerX:Number = player.x;
        var playerY:Number = player.y;
        var xDistance:Number = playerX - x;
        var yDistance:Number = playerY - y;
        var slope:Number = yDistance/xDistance;
        var angle:Number = 180/Math.PI * Math.atan(slope);

        if(slope < 0 && yDistance < 0 || 
           slope > 0 && yDistance > 0)
            angle += 90;
        else if(slope < 0 && yDistance > 0 ||
                slope > 0 && yDistance < 0)
            angle += 270;

        return angle;
    }

This returns a value between 0 (inclusive) and 360 (exclusive) that represents what the rotation of the rotateReference object should be when flying directly at the player plane.

The issue is in the function that turns it: I simply have it compare the current rotation to the angle that it needs to be flying at, then add or subtract the fixed amount I want (9) in effort to bring the current rotation closer to the desired rotation.

public function turnTowardsPlayer( player:PlaneGeneric ):void
    {

        var angleToPlayer:Number = getFlyAngle( player );
        var rotation360:Number = rotateReference.rotation;
        if(rotateReference.rotation < 0)
            rotation360 = (360 - (rotateReference.rotation * -1) );

        trace("angleToPlayer: " + angleToPlayer + ", rotation360: " + rotation360);

        if(angleToPlayer - 9 <  rotation360 && rotation360 < angleToPlayer + 9);
        else if(rotation360 > angleToPlayer)
        {
            rotateReference.rotation -= 9;
            if(currentFrame == 1)
                gotoAndStop (totalFrames);
            else
                prevFrame();
        }
        else if(rotation360 < angleToPlayer)
        {
            rotateReference.rotation += 9;
            if(currentFrame == totalFrames)
                gotoAndStop(1);
            else
                nextFrame();
        }

The issue arises when the player flies overhead the enemy plane, and the angleToPlayer value jumps suddenly from 360 to ~0. because 0 is much less than the 300~ rotation value of the plane, it starts rotating the long way around to try to match the angle again.

It seems like a simple problem, but I've been bashing my head against it for so long I feel like I need a fresh set of eyes to help me write the fix.

Thanks for your time.

1
Rotation is a bit confusing since eventho degrees are 0-360, rotation returns -180 to 180. Try converting angle to that, here's super good explanation - kaarto

1 Answers

0
votes

If the angle difference is greater than 180, subtract 360 from it.

Example.... 350 - 10 = 340 (you know that's more than half a circle) so subtract... 340 - 360 = -20 (the actual difference you want)

Hope that helps. Remember you can always add or subtract 360 b/c on circles you end up in the same spot!