如何旋转一组精灵
示范如何通过一个旋转Matrix (矩阵)以一点为中心来旋转一组精灵。它使用两个方法,在Update中旋转精灵位置,并创建一个旋转矩阵用于Draw的SpriteBatch。源码下载
在屏幕上绘制一组旋转的精灵
在屏幕上绘制一组旋转的精灵
-
按照如何绘制精灵 所讲的1-4步进行操作。
-
创建一组Vector2对象来表示为旋转精灵的位置,再创建一组 Vector2对象来保存旋转值。
private Vector2[] myVectors; private Vector2[] drawVectors; protected override void Initialize() { myVectors = new Vector2[9]; drawVectors = new Vector2[9]; base.Initialize(); }
-
加载完精灵之后,基于精灵的高度(假设我们使用的是一个正方形的纹理)来计算未旋转的初始精灵组中各个精灵的位置。
private Texture2D SpriteTexture; private Vector2 origin; private Vector2 screenpos; protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); SpriteTexture = Content.Load<Texture2D>("ship"); origin.X = SpriteTexture.Width / 2; origin.Y = SpriteTexture.Height / 2; Viewport viewport = graphics.GraphicsDevice.Viewport; screenpos.X = viewport.Width / 2; screenpos.Y = viewport.Height / 2; }
-
在你的Update 方法中,将未旋转的向量数组克隆一份副本传给drawVectors,然后确定向量旋转后的各个精灵在屏幕的位置保存在drawVectors向量中。
private float RotationAngle = 0f; private bool batchAutoRotate = false; private Matrix rotationMatrix = Matrix.Identity; protected override void Update(GameTime gameTime) { ... float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; RotationAngle += elapsed; float circle = MathHelper.Pi * 2; RotationAngle = RotationAngle % circle; // Copy and rotate the sprite positions. drawVectors = (Vector2[])myVectors.Clone(); if (!batchAutoRotate) RotatePoints(ref screenpos, RotationAngle, ref drawVectors); else UpdateMatrix(ref screenpos, RotationAngle); base.Update(gameTime); }
使用一个用旋转角度创建的旋转矩阵来转换每一个向量的位置信息。
-
为了让这些精灵相对于原点旋转,应该使用每个精灵的drawVectors向量减去屏幕原点向量。
-
等转换完以后再与屏幕原点向量相加 ,这样我们最终就得到了一个旋转后的向量了。
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; } }
-
使用旋转后的向量作为屏幕位置绘制每一个精灵。
private void DrawPoints() { // Draw using manually rotated vectors spriteBatch.Begin(); for (int i = 0; i < drawVectors.Length; i++) spriteBatch.Draw(SpriteTexture, drawVectors[i], null, Color.White, RotationAngle, origin, 1.0f, SpriteEffects.None, 0f); spriteBatch.End(); }
-
当所有精灵绘制完毕以后,调用End。
使用SpriteBatch变换旋转一组精灵
-
按照 如何绘制精灵 所讲的1-4步进行操作。
-
创建一组 Vector2对象来表示为旋转精灵的位置,再创建一组 Vector2 对象来保存旋转值。
private Vector2[] myVectors; private Vector2[] drawVectors; protected override void Initialize() { myVectors = new Vector2[9]; drawVectors = new Vector2[9]; base.Initialize(); }
-
加载完精灵之后,基于精灵的高度(假设我们使用的是一个正方形的纹理)来计算未旋转的初始精灵组中各个精灵的位置。
private Texture2D SpriteTexture; private Vector2 origin; private Vector2 screenpos; protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); SpriteTexture = Content.Load<Texture2D>("ship"); origin.X = SpriteTexture.Width / 2; origin.Y = SpriteTexture.Height / 2; Viewport viewport = graphics.GraphicsDevice.Viewport; screenpos.X = viewport.Width / 2; screenpos.Y = viewport.Height / 2; }
-
在你的Update方法中,将未旋转的向量数组克隆一份副本传给drawVectors,然后确定向量旋转后的各个精灵在屏幕的位置保存在drawVectors向量中。
private float RotationAngle = 0f; private bool batchAutoRotate = false; private Matrix rotationMatrix = Matrix.Identity; protected override void Update(GameTime gameTime) { ... float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; RotationAngle += elapsed; float circle = MathHelper.Pi * 2; RotationAngle = RotationAngle % circle; // Copy and rotate the sprite positions. drawVectors = (Vector2[])myVectors.Clone(); if (!batchAutoRotate) RotatePoints(ref screenpos, RotationAngle, ref drawVectors); else UpdateMatrix(ref screenpos, RotationAngle); base.Update(gameTime); }
-
在Draw方法中为SpriteBatch创建一个旋转矩阵。
-
为了绕一个不在左上角的点旋转,首先要使用一个平移矩阵减去旋转原点。
-
将平移矩阵乘以旋转矩阵。
-
将结果乘以加上旋转原点的平移矩阵。
这是因为旋转矩阵必须围绕 (0,0,0)旋转。
private void UpdateMatrix(ref Vector2 origin, float radians) { // Translate sprites to center around screen (0,0), rotate them, and // translate them back to their original positions Vector3 matrixorigin = new Vector3(origin, 0); rotationMatrix = Matrix.CreateTranslation(-matrixorigin) * Matrix.CreateRotationZ(radians) * Matrix.CreateTranslation(matrixorigin); }
-
在Draw方法中,调用SpriteBatch.Begin,指定旋转矩阵作为第四个参数。
private void DrawMatrix() { // Draw using a rotation matrix with SpriteBatch spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.None, rotationMatrix); for (int j = 0; j < myVectors.Length; j++) spriteBatch.Draw(SpriteTexture, myVectors[j], null, Color.White, 0, origin, 1.0f, SpriteEffects.None, 0f); spriteBatch.End(); }
-
当所有精灵绘制完毕以后,调用End。
发布时间:2009/2/23 上午9:52:40 阅读次数:5630