title | description | requireMSLicense |
---|---|---|
Rotating a Group of Sprites |
Demonstrates how to rotate a group of sprites around a single point. |
true |
Sometimes either an individual character is made up of many sprites/textures, or you simply want to arrange a group of sprites in a grid and have them move as one. The process is simple enough and simply an extension of what is covered in HowTo Rotate a Sprite.
-
Follow the steps of Drawing a Sprite.
-
Create one array of Vector2 variables that represent the un-rotated positions of the sprites and another to hold the rotated values.
private Vector2[] myVectors; private Vector2[] drawVectors; protected override void Initialize() { myVectors = new Vector2[9]; drawVectors = new Vector2[9]; base.Initialize(); }
-
After loading the sprite, calculate the positions of the un-rotated group of sprites based on the sprite's size.
private Texture2D spriteTexture; private Vector2 spriteOrigin; private Vector2 spritePosition; protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. _spriteBatch = new SpriteBatch(GraphicsDevice); spriteTexture = Content.Load<Texture2D>("Character"); viewport = _graphics.GraphicsDevice.Viewport; spriteOrigin.X = spriteTexture.Width / 2; spriteOrigin.Y = spriteTexture.Height / 2; spritePosition.X = viewport.Width / 2; spritePosition.Y = viewport.Height / 2; // Populate the `myVectors` array with a grid of Vector2 positions for the character to draw. These will then be rotated around the center of the screen. int i = 0; while (i < 9) { for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { myVectors[i] = new Vector2(x * 200, y * 200); // Assign positions i++; } } } }
-
In your Game.Update method, copy the un-rotated vectors and determine the screen position around which all the sprites will rotate.
private float rotationAngle = 0f; private Matrix rotationMatrix = Matrix.Identity; protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); // The time since Update was called last. float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; // TODO: Add your game logic here. rotationAngle += elapsed; float circle = MathHelper.Pi * 2; rotationAngle %= circle; // Copy and rotate the sprite positions. drawVectors = (Vector2[])myVectors.Clone(); RotatePoints(ref spritePosition, rotationAngle, ref drawVectors); base.Update(gameTime); }
Transform each vector using a rotation matrix created for the rotation angle.
-
To rotate around the origin, transform each vector relative to the origin by subtracting the origin vector.
-
Add the origin vector to the transformed vector to create the final rotated vector.
private static void RotatePoints(ref Vector2 origin, float radians, ref Vector2[] Vectors) { Matrix myRotationMatrix = Matrix.CreateRotationZ(radians); for (int i = 0; i < 9; i++) { // Rotate relative to origin. Vector2 rotatedVector = Vector2.Transform(Vectors[i] - origin, myRotationMatrix); // Add origin to get final location. Vectors[i] = rotatedVector + origin; } }
-
Draw each sprite using the rotated vectors as screen locations.
protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here _spriteBatch.Begin(); for (int i = 0; i < drawVectors.Length; i++) { _spriteBatch.Draw(spriteTexture, drawVectors[i], null, Color.White, rotationAngle, spriteOrigin, 1.0f, SpriteEffects.None, 0f); } _spriteBatch.End(); base.Draw(gameTime); }
-
When all the sprites have been drawn, call SpriteBatch.End.
This results in the Grid of characters that are drawn being rotated
Together
around a position in the center of the screen, instead of each sprite rotating individually.
- SpriteBatch
- SpriteBatch.Draw
- Texture2D