基于相邻矩形的旋转后矩形的位置

时间:2014-01-31 11:14:25

标签: c# xna xna-4.0

我有四个32 x 32矩形用于我的游戏角色(统称它们是一艘船,每个矩形代表一个单元(船舱),它有自己的碰撞检测系统)。

我将这些单元格保持为2x2格式。沿着X轴和Y轴移动“船”都很好。然而,当我旋转“船”时,各个矩形旋转并面向正确的方向,但它们不再“在一起”。也就是说,矩形A1的右边框与矩形A2的左边框不同步,依此类推......

如何纠正矩形的位置,使它们在旋转后仍然对齐?这是我的第一场比赛,我不是数学家,因此我发现自己在这件事上要求你的专业知识!

非常感谢您的协助。如果您需要更多信息(即代码),那么我将提供!

更新:

我终于有了这个工作!以下是我的代码。我希望这有助于其他人!

//The point we want to rotate around (in this example, I was rotating around another ship)
Vector2 origin = new Vector2(selectedShip.Position.X, selectedShip.Position.Y);

test1.Position = Vector2.Transform(test1.Position - origin, Matrix.CreateRotationZ(testRot)) + origin;
test2.Position = Vector2.Transform(test2.Position - origin, Matrix.CreateRotationZ(testRot)) + origin;
test3.Position = Vector2.Transform(test3.Position - origin, Matrix.CreateRotationZ(testRot)) + origin;
test4.Position = Vector2.Transform(test4.Position - origin, Matrix.CreateRotationZ(testRot)) + origin;

// Alter the rotation of the four ship compartments for drawing
test1.Rotation += testRot;
test2.Rotation += testRot;
test3.Rotation += testRot;
test4.Rotation += testRot;

// Update rectangle positions
test1.Rect = new Rectangle((int)test1.Position.X, (int)test1.Position.Y, ship01Texture.Width, ship01Texture.Height);
test2.Rect = new Rectangle((int)test2.Position.X, (int)test2.Position.Y, ship01Texture.Width, ship01Texture.Height);
test3.Rect = new Rectangle((int)test3.Position.X, (int)test3.Position.Y, ship01Texture.Width, ship01Texture.Height);
test4.Rect = new Rectangle((int)test4.Position.X, (int)test4.Position.Y, ship01Texture.Width, ship01Texture.Height);

theSprite.Draw(ship01Texture, test1.Rect, null, Color.White, test1.Rotation, Vector2.Zero, SpriteEffects.None, 0.0f);
theSprite.Draw(ship01Texture, test2.Rect, null, Color.White, test2.Rotation, Vector2.Zero, SpriteEffects.None, 0.0f);
theSprite.Draw(ship01Texture, test3.Rect, null, Color.White, test3.Rotation, Vector2.Zero, SpriteEffects.None, 0.0f);
theSprite.Draw(ship01Texture, test4.Rect, null, Color.White, test4.Rotation, Vector2.Zero, SpriteEffects.None, 0.0f);

非常感谢所有帮助过的人!

2 个答案:

答案 0 :(得分:3)

根据你的问题,我假设你从左边开始,最后是中间图像,而不是右边。

enter image description here

图像之间的区别在于中间图像的矩形都围绕各个中心旋转,而不是全部围绕同一点旋转。

请参阅here了解如何围绕给定点旋转

答案 1 :(得分:2)

将矩形固定在它们的中心,而不是四个顶点中的一个。

您将拥有分层结构:

  • 带翻译的集合(集合中心的位置)
  • 对于集合中的每个元素,您将拥有与集合中心的相对位置

此时,您必须以这种方式旋转矩形和矩形的位置:

  • 在原点旋转元素(翻译前)
  • 旋转相对位置
  • 添加绝对位置和相对位置
  • 翻译矩形

这是一个小图:

+-----+-----+
|     |     |
|  e  |  e  |
|     |     |
+-----C-----+
|     |     |
|  e  |  e  |
|     |     |
+-----+-----+

C是集合的中心,e是元素的中心。 相对位置是向量e-C。 这是非常基本的东西,听起来可能很困难,但这只是添加/减去矢量(位置)并按正确顺序旋转它们的问题。

翻译/旋转元素/集合的顺序非常重要。

围绕矩形的中心旋转:

RotateAboutOrigin(new Vector2(test1.Width / 2, test1.Height / 2), Vector2.zero, rotation)

此时通过相对位置进行平移,这是其中一个(每个矩形一行):

Vector2 p1 = new Vector2(+test1.Width / 2, +test1.Height / 2)
Vector2 p2 = new Vector2(+test2.Width / 2, -test2.Height / 2)
Vector2 p3 = new Vector2(-test3.Width / 2, +test3.Height / 2)
Vector2 p4 = new Vector2(-test4.Width / 2, -test4.Height / 2)

必须确定相对翻译到矩形的实际映射,在这里我只想尝试一下。通过向上/向下改变实际线条,可以很容易地找到正确的组合。

最后,按集群中心进行翻译:

p1 + c // c is also a Vector2

之后可以通过删除大量多余的代码并在适当的位置保存向量来纠正和优化所有这些代码。特别是CreateRotationZ()里面的RotateAboutOrigin应该被缓存,如下所示:

Matrix[] rot = new Matrix[64];

for(phi = 0; phi < 64; phi++)
{
    rot[phi] = Matrix.CreateRotationZ(phi / 64 * 2 * Math.PI);
}

在上面的示例中,您将拥有64个矩阵和64个逐步旋转。然后,您只能通过最小角度1 / 64 * 2 * Math.PI的离散倍数进行旋转。这将使功能更快。