基于二维视差相机获取图像的正确位置

时间:2016-09-27 00:23:21

标签: math camera xna monogame

我的2D引擎与分辨率无关,并且有一个基于以下文章的相机:http://www.david-gouveia.com/portfolio/2d-camera-with-parallax-scrolling-in-xna/

我已经实现了视差滚动到我的相机类中,就像上面提到的那样。它工作得很好,但它搞砸了我的剔除代码,我很难弄清楚数学。

我的每张背景图片都有一个矩形,用于检查它当前是否在屏幕上。如果它没有与我的相机矩形相撞,我就不能画它。问题在于,如果图像是作为视差图层绘制的,则不会计算矩形在屏幕上真正显示的位置。

我的Camera类中的变换矩阵如下所示:

public static Matrix GetTransformMatrix(Vector2 parallax)
        {
            return Matrix.CreateTranslation(new Vector3(-position * parallax, 0)) * Matrix.CreateRotationZ(rotation) *
                        Matrix.CreateScale(new Vector3(zoom, zoom, 1)) * Matrix.CreateTranslation(new Vector3(Resolution.VirtualWidth
                            * 0.5f, Resolution.VirtualHeight * 0.5f, 0));
        }

对于每个视差层,我调用SpriteBatch.Begin()并传递上面的变换矩阵,并传递正确的视差偏移,具体取决于我们绘制的图层(前景,背景等)

我已成功制作了一个ScreenToWorld功能,可以获取点击鼠标的位置。请注意,我需要计算我的分辨率矩阵和相机矩阵才能工作。

public static Vector2 ScreenToWorld(Vector2 input, Vector2 parallax)
        {
            input.X -= Resolution.VirtualViewportX;
            input.Y -= Resolution.VirtualViewportY;

            Vector2 resPosition = Vector2.Transform(input, Matrix.Invert(Resolution.getTransformationMatrix()));
            Vector2 finalPosition = Vector2.Transform(resPosition, Matrix.Invert(Camera.GetTransformMatrix(parallax)));

            return finalPosition;    
        }

所以我想计算我的视差图层的正确矩形位置我需要一个WorldToScreen函数......我试过这个,但它没有工作:

public static Vector2 WorldToScreen(Vector2 input, Vector2 parallax) //I pass the same parallax value that is used in the Camera matrix function.
        {
            input.X -= Resolution.VirtualViewportX;
            input.Y -= Resolution.VirtualViewportY;

            Vector2 resPosition = Vector2.Transform(input, Resolution.getTransformationMatrix());
            Vector2 finalPosition = Vector2.Transform(resPosition, Camera.GetTransformMatrix(parallax));

            return finalPosition;    
        }

我猜我在正确的轨道上,但我的数学错了?我将上述函数传递给非视差矩形位置,希望将其更新到实际绘制视差图像的位置。如果有人可以提供帮助,请提前致谢!

1 个答案:

答案 0 :(得分:0)

结束我的数学运算是正确的,但我需要根据相机的矩阵计算我的相机的屏幕矩形。如果你这样做,你根本不需要触摸背景矩形。只需将背景的视差值传入此函数,然后检查它返回的矩形:

/// <summary>
/// Calculates the Camera's screenRect based on the parallax value passed in. 
/// </summary>
public static Rectangle VisibleArea(Vector2 parallax)
{
    Matrix inverseViewMatrix = Matrix.Invert(GetTransformMatrix(parallax));
    Vector2 tl = Vector2.Transform(Vector2.Zero, inverseViewMatrix);
    Vector2 tr = Vector2.Transform(new Vector2(Resolution.VirtualWidth, 0), inverseViewMatrix);
    Vector2 bl = Vector2.Transform(new Vector2(0, Resolution.VirtualHeight), inverseViewMatrix);
    Vector2 br = Vector2.Transform(new Vector2(Resolution.VirtualWidth, Resolution.VirtualHeight), inverseViewMatrix);
    Vector2 min = new Vector2(
        MathHelper.Min(tl.X, MathHelper.Min(tr.X, MathHelper.Min(bl.X, br.X))),
        MathHelper.Min(tl.Y, MathHelper.Min(tr.Y, MathHelper.Min(bl.Y, br.Y))));
    Vector2 max = new Vector2(
        MathHelper.Max(tl.X, MathHelper.Max(tr.X, MathHelper.Max(bl.X, br.X))),
        MathHelper.Max(tl.Y, MathHelper.Max(tr.Y, MathHelper.Max(bl.Y, br.Y))));
    return new Rectangle((int)min.X, (int)min.Y, (int)(max.X - min.X), (int)(max.Y - min.Y));
}