Thursday, April 2, 2015

xna - How do I rotate a sprite so that it is 'pointing' in the direction it is moving?


I have a sprite, e.g a missile, heading in a certain direction (using a velocity vector). How do I figure out its how much to rotate it so that it gets drawn 'pointing' in the direction it is heading?




Answer



The angle you need to rotate by is the the angle your velocity vector makes with the positive x-axis.


veclocity vector


This angle can be calculated using the inverse tan of the slope of the vector. In XNA, we use the Math.Atan2 function. Give the function the y coordinate and the x coordinate of the velocity vector (in that order). Atan2 will return an angle between +PI/2 and -PI/2. (+180 to -180 degrees) depending on the vector. Vectors below the x-axis (pointing down) have a negative angle. Vectors above the x-axis (pointing up) have positive angle.


Use this angle in your draw method to rotate the sprite.


    public void UpdateSprite(GameTime gameTime, GraphicsDeviceManager graphics)
{
// Move the sprite by speed, scaled by elapsed time.
spritePosition += spriteSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;


//figure out the angle that the sprits velocity vector is making with the
//positive x-axis
//Atan2 will return an angle (in radians) from -PI to +PI

angle = (float)Math.Atan2(spriteSpeed.Y , spriteSpeed.X);
flip = SpriteEffects.None;
if (spriteSpeed.X < 0)
{ //for cases when the sprite is moving right to left, the rotation angle will be >90deg or < -90deg,
//so the sprite will be drawn upside down.
// fix this by flipping the sprite vertically

flip = SpriteEffects.FlipVertically;

}
}

public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
if(!alive) return;

spriteBatch.Draw(myTexture, spritePosition, null, Color.White, angle, spriteOrigin, 1,flip, 1);




}

enter image description here


In my example I used a duck sprite, which if rotated by more than PI/4 (90deg) will start to look 'upside-down'. This might not be a problem for some spites if they do not have 'correct' orientation. (e.g. a missile), but things like aeroplanes or birds might look 'wrong'. Fix this issue by flipping the sprite vertically if the sprite is moving right to left (rotation is not in range -PI/4 to PI/4).


We can check for this either by looking at the angle to see if it is greater than PI/4 or less than -PI/4, OR, equivalently, we can simply check which direction along the x-axis the sprite is moving. If it is moving right to left it will have a negative x-component, this is the way I check in the code above.


enter image description here


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...