2013-02-09 68 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 

我希望這是清理你的代碼有點容易和更容易理解。您應該考慮在單獨的方法中提取一些代碼以使其更具可讀性。