This time I decided to understand how to rotate things around a centre as I wanted to achieve the effect of rotating a map in a game.
Please bear with me as it got a bit messy, but it looks better if you understand how I thought:
Let's start with the rotating “map” as it is what I wanted to achieve with the code.
In LoadContent():
int top = -windowedHeight / 2; int bottom = windowedHeight / 2 - Art.Skull.Height; int left = -windowedWidth / 2; int right = windowedWidth / 2 - Art.Skull.Width;
for (int i = 0; i < 10; i++) { things.Add(new PositionScaleRotation() { position = new Vector2(randomizer.Next(left, right), randomizer.Next(top, bottom)), rotation = 0.0f, scale = 1.0f }); }
Here we create 10 skulls at random positions. Please note the top
and left
variables! They are negative. Since we want to rotate them around the centre of the screen, we want them randomized all around this centre, so some should have a negative position.
We are not using the rotation
or scale
in this code example but you can easily add it.
In Update():
angle += (float)(fullCircle / (3600.0d * 2) * gameTime.ElapsedGameTime.TotalMilliseconds);
We continuously increase the angle which is the rotation angle of the “map”.
In Draw() we are just calling RotateSomeSkulls(), which has the following code:
Matrix rotationMatrix = Matrix.CreateRotationZ(angle); Matrix positionMatrix = Matrix.CreateTranslation(windowedWidth / 2, windowedHeight / 2, 0.0f); rotationMatrix *= positionMatrix;
We create two matrixes, the rotationMatrix
which rotates around the Z-axis, and the positionMatrix
which translates to the centre of the monogame window.
Then we multiply them with each other. Multiplication of matrixes are different from ordinary multiplication; the order matters! Written more clearly, this is what happens:
rotationMatrix = rotationMatrix * positionMatrix;
What happens here? Since we are multiplying the rotation matrix with the position matrix we are effectively moving the rotation centre to the given position on the screen.
If you would do the opposite then, multiplying the position matrix with the rotation matrix? Doing that would effectively rotate the position around the 0,0 position. That is what we are doing in the 1.6 version.
The easiest way of learning these things is to just test around!
spriteBatch.Begin( SpriteSortMode.Deferred, BlendState.NonPremultiplied, null, null, null, null, rotationMatrix);
Calling spriteBatch.Begin() with our rotationMatrix will do the magic for us; everything we draw now are rotated around the centre of the window.
foreach (PositionScaleRotation thing in things) { spriteBatch.Draw(Art.Skull, thing.position, Color.White); }
And that is what we do here, we draw every skull in things
at its position. The position is then rotated around the centre of the window.