我正在开发一个XNA游戏,我正在使用ViewPort.Project和ViewPort.Unproject在世界坐标之间来回转换。目前,我使用SpriteBatch绘制的每个对象都使用它们。我想要做的是计算一个矩阵,我可以发送给SpriteBatch.Begin来为我做屏幕空间转换。
下面是我目前用来转换和转换屏幕空间的函数:
Vector2 ToWorldCoordinates(Vector2 pixels)
{
Vector3 worldPosition = graphics.GraphicsDevice.Viewport.Unproject(new Vector3(pixels, 0),
Projection, View, Matrix.Identity);
return new Vector2(worldPosition.X, worldPosition.Y);
}
Vector2 ToScreenCoordinates(Vector2 worldCoords)
{
var screenPositon = graphics.GraphicsDevice.Viewport.Project(new Vector3(worldCoords, 0),
Projection, View, Matrix.Identity);
return new Vector2(screenPositon.X, screenPositon.Y);
}View设置为Matrix.Identity,Projection设置如下:
Projection = Matrix.CreateOrthographic(40 * graphics.GraphicsDevice.Viewport.AspectRatio, 40, 0, 1);这就是我现在画东西的方式:
spriteBatch.Begin();
foreach (var thing in thingsToDraw)
{
spriteBatch.Draw(thing.Texture, ToScreenCoordinates(thing.PositionInWorldCoordinates), thing.Color);
spriteBatch.End();
}
spriteBatch.End();这就是我想要做的(使用XNA4.0版本的SpriteBatch.Begin())
// how do I calculate this matrix?
Matrix myTransformationMatrix = GetMyTransformationMatrix();
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, null,
myTransformationMatrix);
foreach (var thing in thingsToDraw)
{
// note: no longer converting each object's position to screen coordinates
spriteBatch.Draw(thing.Texture, thing.PositionInWorldCoordinates, thing.Color);
spriteBatch.End();
}
spriteBatch.End();发布于 2010-08-26 07:10:46
我写过关于SpriteBatch和各种“空间”(世界、投影、客户端等) here、here和here的文章。这些答案可能值得一读。
SpriteBatch假设你的世界空间和客户端空间是一样的-无论视口有多少像素高和宽,原点在左上角,Y+是向下的。
看起来(基于您使用的CreateOrthographic),您希望您的世界空间在屏幕上显示为40个单位高,以及多少个单位将适合宽度。您还希望世界原点位于屏幕的中心,并且Y+处于打开状态。
因此,您必须在两者之间插入另一个矩阵,以便将World空间转换为客户端空间。我相信正确的矩阵是(在伪代码中):scale(40/viewport.Height) * scale(1, -1) * translate(viewport.Width/2, viewport.Height/2)。缩放、翻转和平移以从World转到Client。
您还必须记住,sprites假定Y+已关闭。因此,您必须将(1, -1) scale传递给SpriteBatch.Draw,否则它们将被反转绘制(并且,由于背面剔除,将不可见)。
https://stackoverflow.com/questions/3570192
复制相似问题