0

Okay, so I made some ai where a guard is following my character.

I am using this code:

    private function getDegrees(radians:Number):Number
    {
        //return Math.floor(radians/(Math.PI/180));

        return radians / 0.01745 | 0;
    }

    private function getRadians(delta_x:Number, delta_y:Number):Number
    {
        var r:Number = Math.atan2(delta_y, delta_x);

        if (delta_y < 0)
        {
            //r += (2 * Math.PI);

            r += 6.283;
        }

        return r;
    }

And then in the loop

        if(isShooting)
        {
            // calculate rotation based on mouse X & Y
            _dx = this.x - _root.assassin.x;
            _dy = this.y - _root.assassin.y;

            // which way to rotate
            _rotateTo = getDegrees(getRadians(_dx, _dy));   

            // keep rotation positive, between 0 and 360 degrees
            if (_rotateTo > this.rotation + 180) _rotateTo -= 360;
            if (_rotateTo < this.rotation - 180) _rotateTo += 360;

            // ease rotation
            _trueRotation = (_rotateTo - this.rotation) / _rotateSpeedMax;

            // update rotation
            this.rotation += _trueRotation;         


            gotoAndStop(5);
            isWalking = false;
            isStanding = false;
        }

The thing is, the guard rotates weirdly, it's as if he isn't looking at the player. It's as if the player is somewhere else. Dunno, it just doesn't work.. I have no idea what is wrong with the code!

2 Answers2

0

To keep the rotation positive you should use modulus 360 like below for readability and (code) simplicity until and unless it's a clear performance issue: (I think this is right for AC3, just looked it up online quick)

_rotateTo = _rotateTo % 360;

The other possible issue is with how you define _dx and _dy. I'm guessing that the assassin is facing in the opposite direction as intended. The fix is to useI'm thinking it should either be:

_dx = _root.assassin.x - this.x;
_dy = _root.assassin.y - this.y;
Nuclearman
  • 5,029
  • 1
  • 19
  • 35
0

You should just compute the relative angle

 _rotateTo = getDegrees(getRadians(_dx, _dy));   
 _trueRotation = (_rotateTo - this.rotation) / _rotateSpeedMax;

then normalize this to be as close to zero as possible

  _trueRotation = (_trueRotation+900) %360 - 180;

and then cut this to the maximal rotation per step

  _trueRotation = max(_trueRotation,_rotateSpeedMax* _timestep);
  _trueRotation = min(_trueRotation,-_rotateSpeedMax*_timestep);

and use this then to update the forward direction

  this.rotation += _trueRotation;         

Speed usually is change per time, so there should be a multiplication with some time step for semantic consistency. Of course, you may have the time step equal to 1, or rotateSpeedMax is really a rotateMaxAngle (per step), then the multiplication with timestep can be removed.

Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51
  • Wow, you made me feel even dumber than before. Thank you :) – user3123633 Mar 07 '14 at 20:44
  • You are welcome. Did it work as you intended? I have no possibility to try this out in context, I just produced the code that would do the mathematical equivalent of your code in fewer steps. Are there any particular steps that you want deeper explained? – Lutz Lehmann Mar 07 '14 at 21:27
  • Nope, everything is fine :) Thank you so much. Maybe you could answer something else? XD stackoverflow dot com /questions/22260948/as3-containers-depth-and-walls – user3123633 Mar 07 '14 at 21:32
  • It still would be interesting to see a minimal example (AS or jsfiddle) using this routine. In the center some pointy object, e.g., circle with triangle, in the field a marker for the last mouse-click, the pointy object turning its point slowly towards its marker. It may turn out that in the current state, after 4 or 5 turns clock-wise, unexpected behavior will occur. – Lutz Lehmann Mar 08 '14 at 13:25