2017-03-18 56 views
0

所以我有一個炮塔式槍,有一個基準精靈()和一個單獨的精靈(Turret Shaft)。軸被拉到底座後面,並旋轉指向鼠標位置。軸的角度存儲爲_turretAngleMonogame/XNA Gun跟隨鼠標,發射子彈問題

當我嘗試正確定位子彈時,出現了我的問題。問題中的子彈(Bullet)需要始終從軸的尖端點火,並且正確地向正確的方向發射,當然也應該朝正確的方向發射。

要調整子彈的角度,我只需使用_turretAngle,方向是new Vector2(-Math.Cos(_turretAngle), -Math.Sin(_turretAngle));但我無法獲得正確的初始位置。

我現在有它如下:

int i = _bullets.Count - 1; 
Bullet b = _bullets[i]; 

b.SetAngle(_turretAngle); 

float cos = (float)Math.Cos(_turretAngle); 
float sin = (float)Math.Sin(_turretAngle); 

b.SetDirection(new Vector2(-cos, -sin)); 

var posX = (Position.X - (Shaft.Width * cos) - (b.Width * cos)) + (Width/2) - ((b.Width/2) * cos); 
var posY = Position.Y - (Shaft.Height * sin) - (b.Height * sin); 

b.SetPosition((int)posX, (int)posY); 

b.BulletState = Bullet.State.Active; 

子彈是如此接近被位置正確,但它不是位置在軸上,而不是(取決於轉檯的角度)定位的任何位置從炮塔前方5-15像素。

怎麼而且目前已出現:

Current

如何我想它顯示:

Ideal

我知道我可能會被挑剔的在這裏,但我我真的很想知道數學的錯誤。

我意識到可能會丟失一些信息,因此讓我知道是否需要添加任何內容。

+0

我會建議只是在與子彈的相同位置產生這個子彈,然後應用相同的旋轉矩陣,然後應用平移矩陣,它應該在y方向上移動物體,使其等於炮塔高度+子彈高度。原因是您首先應用旋轉矩陣,然後移動該對象。它應該完全對齊,甚至沒有一個像素的差距。 –

回答

2

擴展我的評論與一些代碼示例和更多描述性解釋。
您沒有指定您的角度是度數還是弧度,所以我假設您正在使用必須轉換的度數。接下來的事情就是創建一個旋轉和翻譯矩陣,然後將它應用到你的子彈對象上。

我的建議是創建一個擴展類喜歡這樣:

public static class TransformEx 
{ 
    // method to convert degree into radians 
    public static double ToRadians(this double degree) 
    { 
     return ((degree % 360.0D)/180.0D) * Math.PI; 
    } 

    // get the rotation matrix 
    public static Matrix GetRotationMatrix(this double angle, Vector2 rotationCenter) 
    { 
     double radians = angle.ToRadians(); 
     double cos = Math.Cos(radians); 
     double sin = Math.Sin(radians); 

     return new Matrix 
     { 
      M11 = cos, 
      M12 = sin, 
      M21 = -sin, 
      M22 = cos, 
      M41 = (rotationCenter.X * (1.0 - cos)) + (rotationCenter.Y * sin), 
      M42 = (rotationCenter.Y * (1.0 - cos)) - (rotationCenter.X * sin) 
     }; 
    } 

    // get translation matrix 
    public static Matrix GetTranslationMatrix(this Vector2 position) 
    { 
     return new Matrix 
     { 
      M41 = position.X, 
      M42 = position.Y, 
      M43 = 0 
     }; 
    } 
} 

有了這個,你現在可以計算出發,建立你的子彈。請記住,您必須計算X軸上的平移才能正確顯示子彈。

// spawn the bullet 
Bullet b = _bullets[i]; 

// get size of bullet and turret for further calculations 
Vector2 bulletSize = new Vector2(b.Width, b.Height); 
Vector2 turretSize = new Vector2(turret.Width, turret.Height); 

// move bullet to the same position as turret 
b.Position = turret.Position; 

// calculate new translation depending on the size difference 
double deltaX = (turretSize.X - bulletSize.X)/2; 
Vector2 bulletNewPos = new Vector2(b.Position.X + deltaX, b.Position.Y + turretSize.Height); 

// using extension methods get rotation matrix 
// this will rotate referencing the middle point of your bullet 
Matrix mtxRotation = _turretAngle.GetRotationMatrix(new Vector2(bulletSize.X/2, bulletSize.Y/2)); 

// now you have to create translation matrix 
// but remember to calculate position correctly 
Matrix mtxTranslation = bulletNewPos.GetTranslationMatrix(); 

// now all you have to do is to rotate and then translate your bullet 
Matrix transformMatrix = mtxTranslation * mtxRotation; 

現在transformMatrix包含您需要的所有必要的轉換細節。您可以使用SpriteBatch.Begin的重載方法來使用此轉換矩陣。

但是如果你仍然想用你的SetPositionSetAngle方法。你可以簡單地使用這個矩陣中提取新的位置,這一點使用適用於:

b.SetAngle(_turretAngle); 
// M41 >> position.X 
// M42 >> position.Y 
// M43 >> position.Z 
b.SetPosition((int)transformMatrix.M41, (int)transformMatrix.M42); 

編輯:
這假定您的軸值定義爲這樣:

Y + 
^
    | 
    | 
    |   
-X +------------> X + 
    Y-