Question

I'm making a battleship simulator that controls a battleship with the WASD keys and the turret with the mouse pointer. The turret can move 360 degrees.

It rotates as it should; however, whenever the mouse pointer makes the turret reach an angle of 0 or 360 degrees, it begins rotating endlessly until I move the mouse pointer back to a different angle.

Attached is the code I have so far for turret movement:

var PTurret1angle:Number = 270;

function PTurretRotate(Evt:Event){

var Turret1x:Number;
var Turret1y:Number;
var Turret1Angle:Number;

Turret1x = mvi_PTurret1.x - mouseX;
Turret1y = mvi_PTurret1.y - mouseY;

Turret1Angle = Math.round(Math.atan2(Turret1y,Turret1x) * (180/Math.PI) + 180);

if(Turret1Angle > PTurret1angle){
    mvi_PTurret1.rotation += 1;
    PTurret1angle += 1;
    if(PTurret1angle == 360){
        PTurret1angle = 0;
    }
}
else if(Turret1Angle < PTurret1angle){
    mvi_PTurret1.rotation -= 1;
    PTurret1angle -= 1;
    if(PTurret1angle == 0){
        PTurret1angle = 360;
    }
}


txt_Turret1Angle.text = Turret1Angle.toString();
txt_PTurret.text = PTurret1angle.toString();
}

So, my two questions are:

1) How do I ensure that the turret will remain locked on to where the mouse pointer is, regardless of mouse pointer position?

2) Is there any way to make the rotation more efficient? For example, if my pointer requires the turret to only turn about 30 degrees, it will actually turn 330 degrees depending on the circumstance.

Thank you for your help.

Was it helpful?

Solution

Your turret angles are funky because of these two if statements:

if(PTurret1angle == 0){
    PTurret1angle = 360;
}

and

if(PTurret1angle == 360){
    PTurret1angle = 0;
}

These are making your endless rotation (mouse on top, angle is zero, angle is set to 360 which is greater than zero, you subtract one, oh man now it's at 359 which is greater than zero, gotta rotate all the way around, oh man we got to zero, gotta set it to 360, ......etc.....).

You can accomplish the "efficient rotation" by checking the difference between Turret1Angle and PTurret1angle. Here are my assumptions:

  • Zero is pointing straight up.
  • Positive rotation is clockwise rotation.
  • Turret1Angle is mouse angle and PTurret1angle is actual current turret angle
  • The most you ever want to turn is 180 degrees. (efficient rotation)

That being said, you can figure out which way to turn based on two things: the sign of the difference between Turret1Angle (mouse angle) and PTurret1angle (actual turret angle), and the magnitude of this difference. What do I mean by this?

examples using Turret1Angle (mouse) - PTurret1angle (actual):

  • Mouse is at 1 degree, turret is at 359. Mouse - turret = -358. The most you want to turn is 180 degrees, so since abs(-358) > 180, then add 360 (as the difference is negative). This gives you +2, which means turn 2 degrees clockwise!
  • Mouse is at 359, turret is at 1. Mouse - turret = 358. abs(358) > 180, so subtract 360 degrees (as the difference is positive). This gives you -2, so turn 2 degrees counterclockwise!
  • Mouse is at 1, turret is at 3. Mouse - turret = -2. Since abs(-2) < 180, we don't need to add 360, just turn 2 degrees counterclockwise!

I'm a little rusty with my ActionScript, so I won't actually code this out for you. I think I've explained how to implement the two fixes you asked about thoroughly, but if you have any trouble I'd be happy to psuedocode it.

EDIT: Here's some psuedocode:

var AngleDiff:Number;

// starting after declarations/getting basic information, within your function

Turret1Angle = Math.round(Math.atan2(Turret1y,Turret1x) * (180/Math.PI) + 180);
AngleDiff = Turret1Angle - PTurret1angle;

if(Math.abs(AngleDiff) > 180){  // efficient movement
    if(AngleDiff > 0){
        AngleDiff -= 360;
    }else if(AngleDiff < 0){
        AngleDiff += 360;
}

if(AngleDiff > 0){  //  do the actual movement
    PTurret1Angle += 1;
    mvi_PTurret1.rotation += 1;
}else if(AngleDiff < 0){
    PTurret1Angle -= 1;
    mvi_PTurret1.rotation -= 1;
}

You can probably fix the numbers greater than 360 problem with modulo division, as Lukasz suggests.

PTurret1Angle = PTurret1Angle % 360;

(note: that was more actual code than psuedocode. I haven't actually tested it though so it may/may not work)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top