Reputation: 950
I have a ship texture, and just below the ship's port wing is a missile texture. When I rotate the ship, I need the missile to stay in the same position relative to the ship (i.e., under the port wing). I read some articles and came up with this (sorry, it's a bit messy):
private void RotateWeapons()
{
float x, y;
/*
x = leftMissile.X + (radius * (float)Math.Cos(Rotation));
y = leftMissile.Y + (radius * (float)Math.Sin(Rotation));
*/
leftMissile = Vector2.Transform(leftMissile - center, Quaternion.CreateFromAxisAngle(Vector3.Backward, Rotation)) + center;
//leftMissile.X = x;
//leftMissile.Y = y;
}
Where leftMissile
is a Vector2
describing the middle of the missile, and center
is the center of the ship as a Vector2
. It almost works, the sprite rotates around the center. The problem is, it doesn't stay at the same point on the port wing.
This is normal:
This is 90 degrees, it's further off the wing:
And when rotated 180 degrees, it's not even on the ship anymore:
Upvotes: 0
Views: 859
Reputation:
What you should consider doing is keeping a constant (readonly
) offset from your ship for the missile:
//non-rotated, where is the missile relative to the ship?
readonly Vector2 missileOffset = new Vector2(5.0f, 2.0f);
This keeps things in the ship's relative space. Then you can simply transform only the offset, and then add this to the ship's position:
//rotation of ship as quaternion
Quaternion rotation = Quaternion.CreateFromAxisAngle(Vector3.Backward, angle);
//the final position for the missile
Vector2 leftMissile = Vector2.Transform(missileOffset, rotation) + shipPosition;
This will get the missile in the proper place. Then, assuming you're using SpriteBatch
, just rotate both ship and missile by passing in the angle to both:
batch.Begin();
batch.Draw(shipTex, shipPosition, null, Color.White, angle, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);
batch.Draw(missileTex, leftMissile, null, Color.White, angle, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);
batch.End();
Upvotes: 2
Reputation: 5762
If you have a forward vector and the center, is easy to calc it.
Normalize forward.
Forward.Normalize();
Get a normal vector to forward.
Normal.X = Forward.Y; Normal.Y = -Forward.X;
Get the pos of the missile.
MissilePos = CenterShip - Forward * OffsetY (+ or -) Normal * OffsetX;
Upvotes: 0