XNA - 在相机2d改变后再次获得鼠标位置(再次)

时间:2013-07-02 23:52:24

标签: xna camera mouse coordinate

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

当我使用相机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;
    }
}

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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);
    }