2013-02-09 66 views
0

我已经得到了通过旋转移动,其旋转是不断变化的,但我也需要制定出如果目标是到它的左边或右边和玩家精灵不在前后旋转45度内。制订一个目标的方位旋转精灵

我写这个代码,我认为应该工作,但拿起一边,稍另一方面,它似乎只是偶尔。

 public void GrappleCheck(AsteroidSprite target) 
    { 
     float targetTragectory = (float)Math.Atan2(Position.Y - target.Position.Y, Position.X - target.Position.X); 

     if (targetTragectory < 0) 
      targetTragectory += (float)(Math.PI * 2); 

     if (Rotation < 0) 
      Rotation += (float)(Math.PI * 2); 

     if ((targetTragectory > Rotation + (float)(MathHelper.PiOver4/2)) && (targetTragectory < Rotation + (float)(Math.PI - (MathHelper.PiOver4/2)))) 
     { 
      target.Distance = Vector2.Distance(Position, target.Position); 
      if (RightTarget != null) 
      { 
       if (RightTarget.Distance > target.Distance) 
       { 
        RightTarget.isTarget = false; 
        RightTarget = target; 
        RightTarget.ColorTint = Color.Blue; 
        RightTarget.isTarget = true; 
       } 
      } 
      else 
      { 
       RightTarget = target; 
       RightTarget.ColorTint = Color.Blue; 
       RightTarget.isTarget = true; 
      } 
     } 
     else if ((targetTragectory < Rotation - (float)(MathHelper.PiOver4/2)) && (targetTragectory > Rotation - (float)(Math.PI - (MathHelper.PiOver4/2)))) 
     { 
      target.Distance = Vector2.Distance(Position, target.Position); 
      if (LeftTarget != null) 
      { 
       if (LeftTarget.Distance > target.Distance) 
       { 
        LeftTarget.isTarget = false; 
        LeftTarget = target; 
        LeftTarget.ColorTint = Color.Red; 
        LeftTarget.isTarget = true; 
       } 
      } 
      else 
      { 
       LeftTarget = target; 
       LeftTarget.ColorTint = Color.Red; 
       LeftTarget.isTarget = true; 
      } 
     } 
     else 
     { 
      target.isTarget = false; 
     } 

     if (controlInput.IsHeld(Keys.X)) 
     { 
      Speed = Speed; 
     } 
+0

我工作出了问题,我的球员是旋转0 - 2 * PI,其中的“targetTragectory”旋转(顺时针)0 - PI然后-PI - 0,但没有解决如何解决这个问题 – DeviousSquire 2013-02-10 19:49:04

回答

0

好吧,我已经解决了它,玩家可以旋转从0到2×PI +或 - ,以保持它虽然+我把

if (Rotation < 0) 
    Rotation += (float)Math.PI * 2; 

转动到目标可以是0〜 PI或0 - 负PI取决于你声明atan2的方式和玩家的位置。

//This works out the difference from the targets rotation to the players rotation. 

RotationDif = TargetRotation - PlayerRotation; 

//If the difference is greater than PI then when we check to see if its is within 
//the range 0-PI or 0-Negative PI it will be missed whilst still possibly being on 
//either side of the player, adding PI * 2 to the targets rotation basically spins 
//it past the player so the Difference will be the shortest angle. 

if(Math.Abs(RotationDif) > Math.PI) 
    RotationDif = TargetRotation + (float)(Math.PI * 2) - PlayerRotation; 

//Next we check to see if the target is left(negative) or 
//the right(positive), the negative/positive assignment will depend 
//on which way round you did the atan2 to get the target rotation. 

if ((RotationDif > 0) && (RotationDif < (float)Math.PI)) 

    //Insert right target code here 

else if ((RotationDif < 0) && (RotationDif > -(float)Math.PI)) 

    //Insert left target code here 

else 

    //Insert no target code here to cover all basis 

就是这样,我已经取得了如果(RotationDif> 0)等不同,因此以45度角正面和背面通过使忽略它

If ((RotationDif > (float)(Math.PI/8) && 
    (RotationDif < (float)(Math.PI - (Math.PI/8))) 

和相对的另一边,希望这可以帮助别人,因为我花了近2周该死的工作了:/

1

使用角度可能会很烦人。以下是为您解决问题,而无需使用角度的一些方法:

首先,我们需要的方向目标和运动方向:

var targetDirection = target.Positon - Position; 
// Update this to match the actual direction. The following line assumes that 
// a rotation of 0 results in the right direction. 
var movementDirection = new Vector2((float)Math.Cos(Rotation), (float)Math.Sin(Rotation)); 

要解决的是确定,如果目标的第一个问题在45°锥体内。可以用下面的公式计算出实际的角度:

var dot = Vector2.Dot(myDirection, targetDirection); 
//if dot is negative, then target is behind me, so just use the absolute value 
var cos = Math.Abs(dot)/myDirection.Length()/targetDirection.Length(); 
var angle = Math.Acos(cos); 
if(angle < MathHelper.PiOver4/2) //45° opening angle 
    ; // within cone 
else 
    ; // outside cone 

你的第二个问题是确定,如果目标是在左侧或右侧。我们用一个矢量,ortogonal到myDirection和指向左侧此:

//assuming that +x is the right axis and +y is the down axis 
var normal = new Vector2(myDirection.Y, -myDirection.X); 
dot = Vector2.Dot(normal, targetDirection); 
if(dot > 0) 
    ; // target is on the left side 
else 
    ; // target is on the right side 

我希望这是清理你的代码有点容易和更容易理解。您应该考虑在单独的方法中提取一些代码以使其更具可读性。