0

首先,我真的很抱歉,因为我看到了一些与这个主题相关的话题,但我无法理解......

当我使用相机 2d 时,我需要帮助来学习如何在地图上移动精灵。

地图有 1800x968。当我在没有相机的情况下移动精灵时,一切正常。

让我解释一下。我用我想要移动的精灵的当前位置保留一个vector2d。

当我点击地图的任何区域时,我会得到点击的坐标并将精灵移动到那里。所以,我刷新了精灵的当前位置。

我保持当前位置是因为(我认为)我必须使用它来决定,例如,我必须向右还是向左移动。例如:如果我在 x 轴上的当前位置大于 x 轴上的单击区域,我必须向左移动。我不知道这个策略是否正确,但是......

好的。我的屏幕有 800x480,而且,正如我所说,我的地图有 1800x968(比我的屏幕区域大)。

如果我单击位置 750(x 轴,屏幕右侧),精灵会正确移动直到那里。相机也动了。一切正常,但问题来了:

精灵的当前位置,在 x 轴上,现在是 750。但是,因为我的相机移动了,我的精灵现在位于屏幕的中心(它不再位于 750 x 轴,因为相机移动了)。这是我的问题。我现在必须以某种方式再次单击,例如这次在700位置,并使精灵向右移动,但它的当前位置是750(> 700)。我该如何解决这个问题?也许,当相机改变时,我必须刷新精灵当前位置,但我不知道如何......

同样的问题出现在 y 轴上。

谁能帮我?

下面是我的 camera2d 代码,我从一个主题复制的示例(提前感谢!):

public sealed class Camera2D
{
    private const float zoomUpperLimit = 1.5f;
    private const float zoomLowerLimit = .5f;

    private float _zoom;
    private Matrix _transform;
    private Vector2 _pos;
    private float _rotation;
    private int _viewportWidth;
    private int _viewportHeight;
    private int _worldWidth;
    private int _worldHeight;

    public Camera2D(Viewport viewport, int worldWidth,
       int worldHeight, float initialZoom)
    {
        _zoom = initialZoom;
        _rotation = 0.0f;
        _pos = Vector2.Zero;
        _viewportWidth = viewport.Width;
        _viewportHeight = viewport.Height;
        _worldWidth = worldWidth;
        _worldHeight = worldHeight;
    }

    public float Zoom
    {
        get { return _zoom; }
        set
        {
            _zoom = value;
            if (_zoom < zoomLowerLimit)
                _zoom = zoomLowerLimit;
            if (_zoom > zoomUpperLimit)
                _zoom = zoomUpperLimit;
        }
    }

    public float Rotation
    {
        get { return _rotation; }
        set { _rotation = value; }
    }

    public void Move(Vector2 amount)
    {
        _pos += amount;
    }

    public Vector2 Pos
    {
        get { return _pos; }
        set
        {
            float leftBarrier = (float)_viewportWidth * .5f / _zoom;
            float rightBarrier = _worldWidth - (float)_viewportWidth * .5f / _zoom;
            float topBarrier = _worldHeight - (float)_viewportHeight * .5f / _zoom;
            float bottomBarrier = (float)_viewportHeight * .5f / _zoom;
            _pos = value;
            if (_pos.X < leftBarrier)
                _pos.X = leftBarrier;
            if (_pos.X > rightBarrier)
                _pos.X = rightBarrier;
            if (_pos.Y > topBarrier)
                _pos.Y = topBarrier;
            if (_pos.Y < bottomBarrier)
                _pos.Y = bottomBarrier;
        }
    }

    public Matrix GetTransformation()
    {
        _transform =
           Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
           Matrix.CreateRotationZ(Rotation) *
           Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
           Matrix.CreateTranslation(new Vector3(_viewportWidth * 0.5f,
               _viewportHeight * 0.5f, 0));

        return _transform;
    }
}
4

2 回答 2

0

您需要将相机的位置添加到鼠标位置,以将位置从屏幕坐标转换为世界坐标。例如,相机位于 750 x 并且您单击屏幕上的像素 700 x,这是世界 x 轴上的 1450 (750+700)。

于 2013-07-03T11:47:31.000 回答
0

如果您已经移动了相机以使其以视口中心为中心,则在跟踪鼠标位置时需要撤消数学运算。

现在,我让我的跟踪摄像机将目标置于屏幕中间:

 obj.lookAt(new Vector2(mouseState.X, mouseState.Y) + scene.camera.target.Position - new Vector2(Global.graphicsDevice.GraphicsDevice.Viewport.Width * 0.5f,
                                     Global.graphicsDevice.GraphicsDevice.Viewport.Height * 0.5f));

注意:可以从中取出新的向量内容以进行优化并在类范围内初始化一个。

作为参考,代码如下:

    public void lookAt(Vector2 lookAt)
    {
        Vector2 lookVector = lookAt - Position;

        //Normalization is not necessary here IMO but from what I have seen in other examples trying to solve
        //the offset issue, people seem to throw this in. I'll leave it here for now
        lookVector.Normalize();

        rotation = (float)Math.Atan2(lookVector.Y, lookVector.X);
    }
于 2013-08-25T18:45:53.870 回答