2016-09-27 71 views
0

我的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;  
     } 

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

回答

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)); 
}