坦克与旋转炮塔AS3

时间:2014-04-16 05:20:14

标签: actionscript-3 actionscript trigonometry flash-cs3

我制作了一艘战舰模拟器,用WASD键控制战舰,用鼠标指针控制炮塔。炮塔可以移动360度。

它应该旋转;但是,每当鼠标指针使炮塔达到0或360度的角度时,它就会开始无休止地旋转,直到我将鼠标指针移回另一个角度。

附件是我到目前为止用于炮塔运动的代码:

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();
}

所以,我的两个问题是:

1)无论鼠标指针位置如何,如何确保炮塔仍然锁定在鼠标指针的位置?

2)有没有办法让轮换效率更高?例如,如果我的指针要求炮塔只转动约30度,它实际上会根据情况转为330度。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

由于这两个if语句,你的炮塔角度很时髦:

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

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

这些正在进行无休止的旋转(鼠标在顶部,角度为零,角度设置为360,大于零,你减去一个,哦,现在,人在359,大于零,得到一路旋转,哦,我们得零,要把它设置为360,......等........

您可以完成&#34;高效轮换&#34;通过检查Turret1AnglePTurret1angle之间的差异。以下是我的假设:

  • 零指向上方。
  • 正向旋转是顺时针旋转。
  • Turret1Angle是鼠标角度,PTurret1angle是实际当前炮塔角度
  • 曾经想要转动的最多是180度。 (有效轮换)

话虽这么说,你可以根据两件事找出转向的方式:Turret1Angle(鼠标角度)和PTurret1angle(实际炮塔角度)之间差异的符号,以及幅度这种差异。这是什么意思?

使用Turret1Angle(鼠标)的示例 - PTurret1angle(实际):

  • 鼠标位于1度,炮塔位于359.鼠标 - 炮塔= -358。你要转的最多是180度,所以因为abs(-358)&gt; 180,然后加360(差异为负)。这给你+2,这意味着顺时针旋转2度!
  • 鼠标位于359,转塔处于1.鼠标 - 炮塔= 358.abs(358)&gt; 180,因此减去360度(因为差异为正)。这给你-2,逆时针旋转2度!
  • 鼠标位于1,炮塔位于3.鼠标 - 炮塔= -2。由于abs(-2)&lt; 180,我们不需要添加360,逆时针旋转2度!

我的ActionScript有点生疏,所以我实际上并没有为你编写代码。我想我已经解释了如何彻底实施你所提到的两个修复,但是如果你有任何问题,我很乐意对它进行伪装。

编辑:这里有一些伪代码:

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;
}

正如Lukasz建议的那样,你可以用模数除法修正大于360的数字。

PTurret1Angle = PTurret1Angle % 360;

(注意:那是比psuedocode更实际的代码。我实际上并没有对它进行测试,所以它可能/可能不起作用)