【问题标题】:XNA/C# 2D Coordinate Scaling in World Matrix to 3D View Matrix?世界矩阵中的 XNA/C# 2D 坐标缩放到 3D 视图矩阵?
【发布时间】:2011-08-17 16:33:54
【问题描述】:

这是我的变换。我从一个简单的 2D 相机的例子中得到它。

    public Matrix Transform(GraphicsDevice graphicsDevice)
    {
        float ViewportWidth = graphicsDevice.Viewport.Width;
        float ViewportHeight = graphicsDevice.Viewport.Height;

        matrixTransform =
          Matrix.CreateTranslation(new Vector3(-cameraPosition.X, -cameraPosition.Y, 0)) *
              Matrix.CreateRotationZ(Rotation) *
              Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) *
              Matrix.CreateTranslation(
                    new Vector3(ViewportWidth * 0.5f, ViewportHeight * 0.5f, 0));
        return matrixTransform;
    } 

如果我理解正确的话,它允许滚动(旋转)、缩放时精灵比例的变化以及世界和相机之间的平移,以实现简单的上、下、左、右控制。但是,它不会改变 Z 深度。

但我需要的是让游戏世界缩放,而不仅仅是绘制的精灵。我假设为了做到这一点,我需要改变相机和世界矩阵之间的 Z 距离。

我对编程非常陌生,对矩阵只有简单的了解。我对 XNA 如何在 draw 方法中使用它们的了解更少。到目前为止,我想把我的头发从无结果的搜索中拉出来......我只需要世界坐标来缩放缩放,这样在我的鼠标在预缩放 X.60 之前 Y.60 将在 X .600 Y.600 缩放后(即:缩放级别 0.1)。但是我的鼠标没有移动,只是世界变得更大(或缩小)。

【问题讨论】:

  • 我目前正在消化这个矩阵教程,希望它能帮助我理解我做错了什么。 stevehazen.wordpress.com/2010/02/15/…
  • 你试过改变 ViewportWidth 和 ViewportHeight 吗?我认为这可能会达到您想要的效果。
  • 似乎所做的只是改变相机的位置。仍然在窗口中获得相同数量的坐标。无论缩放级别如何,它们似乎都锁定在 1:1。
  • 能否包含在世界坐标中获取鼠标位置的代码?
  • 我想通了...但是我的名声使我无法再回答我自己的问题 4 小时...对不起各位。

标签: c# matrix xna camera


【解决方案1】:

我知道这个问题很老,但这是为了以防万一有人遇到这个问题并且找不到解决方案。 @RogueDeus 在使用相机放大或缩小时试图转换缩放的输入坐标。为了缩放鼠标,你只需要得到缩放的逆矩阵。

所以如果他的比例矩阵是这样创建的:

Matrix.CreateScale(zoom, zoom, 0);

鼠标坐标应按必要的平移进行反向缩放和移动:

float ViewportWidth = graphicsDevice.Viewport.Width;
float ViewportHeight = graphicsDevice.Viewport.Height;

Matrix scale = Matrix.CreateScale(zoom, zoom, 0);
Matrix inputScalar = Matrix.Invert(scale);

...

public MouseState transformMouse(MouseState mouse)
{
    /// Shifts the position to 0-relative
    Vector2 newPosition = new Vector2(mouse.X - ViewportWidth,
                                      mouse.Y - ViewportHeight);

    /// Scales the input to a proper size
    newPosition = Vector2.Transform(newPosition, InputScalar);

    return new MouseState((int)newPosition.X, (int)newPosition.Y,
                          mouse.ScrollWheelValue, mouse.LeftButton,
                          mouse.MiddleButton, mouse.RightButton,
                          mouse.XButton1, mouse.XButton2);
}

【讨论】:

    【解决方案2】:

    您使用的是 2D 坐标,因此 Z 坐标绝对不重要。实际上,您使用的比例矩阵 (Matrix.CreateScale(new Vector3(Zoom, Zoom, 0))) 将 Z 坐标乘以 0,实际上将其设置为 0。

    由于这个缩放矩阵在视图矩阵中,它将缩放整个世界。我不确定是否真的了解您的问题。请您再解释一下好吗?

    【讨论】:

    • 例如:我在位置 600,600(右下角)单击鼠标,得到的世界位置返回值为 600,600。我缩小到 0.1,因此屏幕上的坐标应该是 10 倍,所以在没有移动鼠标的情况下,我应该能够在相同的位置单击,但得到的坐标离最后一个世界坐标更远。 .. 但是当我这样做时,它仍然返回 600,600。所以,我移动我的相机 +25,+25(仍然没有移动我的鼠标)并点击,返回一个新的世界坐标 625,625。
    • 因此我知道我得到的是世界坐标而不是视图坐标。但是世界坐标根本没有随着我的缩放级别缩放。这会破坏以鼠标单击为中心的任何尝试,或使用世界点的位置将相机旋转到适当位置的其他功能。毕竟,缩小(查看更多)是重点......但是选择应该在几英里之外的东西,只是将相机移动几英尺,因为实际坐标没有缩放到所看到的距离。我希望这是有道理的?...
    • @Eilistraee 将 Z 比例设置为 1(不变)通常要好得多。将 Z 缩放为 0 可能会在各种情况下导致问题。
    • 感谢您的信息。会解决的。
    【解决方案3】:

    我似乎已经想出了如何让坐标按比例缩放...

    我假设当前的鼠标状态会反映它点击的世界矩阵,但显然它从未真正做到这一点。它总是链接到视图矩阵。 (屏幕本身)并且该值需要与世界矩阵(在变换中)一起缩放。

    因此,由于变换受 Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) 中的缩放影响,mouseState X 和 Y 坐标也需要通过它缩放以虚拟镜像世界矩阵。

        //Offsets any cam location by a zoom scaled window bounds
        Vector2 CamCenterOffset
        {
            get { return new Vector2((game.Window.ClientBounds.Height / Zoom)
                 * 0.5f, (game.Window.ClientBounds.Width / Zoom) * 0.5f);
            }
        }
    
        //Scales the mouse.X and mouse.Y by the same Zoom as everything.
        Vector2 MouseCursorInWorld
        {
            get
            {
                currMouseState = Mouse.GetState();
                return cameraPosition + new Vector2(currMouseState.X / Zoom,
                    currMouseState.Y / Zoom);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-04
      • 1970-01-01
      • 2016-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-07
      • 1970-01-01
      相关资源
      最近更新 更多