【问题标题】:XNA ViewPort projection and SpriteBatchXNA ViewPort 投影和 SpriteBatch
【发布时间】:2011-04-03 23:13:07
【问题描述】:

我正在开发一款 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();

这就是我想要做的(使用 SpriteBatch.Begin() 的 XNA 4.0 版本)

            // 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();

【问题讨论】:

    标签: c# matrix xna


    【解决方案1】:

    我写过关于SpriteBatch 和各种“空间”(世界、投影、客户端等)hereherehere。这些答案可能值得一读。

    SpriteBatch 假设您的 World 空间与 Client 空间相同 - 无论视口的高宽是多少像素,原点左上角,Y+ 向下。

    看起来(基于您对CreateOrthographic 的使用)您希望您的世界空间在屏幕上显示为 40 个单位高,但是许多单位都适合横向。您还希望 World 原点位于屏幕中心,并且 Y+ 向上。

    因此,您必须在两者之间添加另一个矩阵才能将您的世界空间转换为客户端空间。我相信正确的矩阵是(在伪代码中):scale(40/viewport.Height) * scale(1, -1) * translate(viewport.Width/2, viewport.Height/2)。缩放、翻转和转换以从世界到客户端。

    您还必须记住,精灵假定 Y+ 已关闭。因此,您必须将 (1, -1) 比例传递给 SpriteBatch.Draw,否则它们将被反转(并且由于背面剔除,不可见)。

    【讨论】:

    • 很棒的答案。对于正在阅读的其他人,如果您还想拥有一个表示相机的 View 矩阵,我认为正确的顺序是 View * scale(40/viewport.Height) * scale(1, -1) * translate(viewport. Width/2, viewport.Height/2),其中视图变换采用世界空间单位。
    猜你喜欢
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多