矩阵变换和精灵方向的问题

时间:2014-08-19 11:53:23

标签: c# camera xna

我有一个名为Tool的精灵,它以一个表示为float的速度和一个表示为Vector2的方向移动。当我在屏幕上单击鼠标时,精灵会改变其方向并开始向鼠标点击移动。除此之外,我旋转精灵,使其朝向它前进的方向。但是,当我添加一个假定跟随精灵的摄像机以使精灵始终在屏幕上居中时,精灵不会沿给定方向移动并且旋转不再准确。这只发生在spriteBatch.Begin()中添加Camera.View时。我希望任何人都可以了解我在代码中遗漏的内容,我将非常感激。

这是我使用的相机类:

    public class Camera
{
    private const float zoomUpperLimit = 1.5f;
    private const float zoomLowerLimit = 0.1f;

    private float _zoom;
    private Vector2 _pos;

    private int ViewportWidth, ViewportHeight;

    #region Properties

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

    public Rectangle Viewport 
    {
        get
        {
            int width = (int)((ViewportWidth / _zoom));
            int height = (int)((ViewportHeight / _zoom));
            return new Rectangle((int)(_pos.X - width / 2), (int)(_pos.Y - height / 2), width, height);
        }
    }

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

    public Vector2 Position
    {
        get { return _pos; }
        set { _pos = value; }
    }

    public Matrix View
    {
        get
        {
            return Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
                Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
                    Matrix.CreateTranslation(new Vector3(ViewportWidth * 0.5f, ViewportHeight * 0.5f, 0));
        }
    }

    #endregion

    public Camera(Viewport viewport, float initialZoom)
    {
        _zoom = initialZoom;
        _pos = Vector2.Zero;
        ViewportWidth = viewport.Width;
        ViewportHeight = viewport.Height;
    }

}

这是我的更新和绘图方法:

protected override void Update (GameTime gameTime)
    {
        float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
        TouchCollection touchCollection = TouchPanel.GetState ();

        foreach (TouchLocation tl in touchCollection) {
            if (tl.State == TouchLocationState.Pressed || tl.State == TouchLocationState.Moved) {

                //direction the tool shall move towards
                direction = touchCollection [0].Position - toolPos;

                if (direction != Vector2.Zero) {
                    direction.Normalize ();
                }   

                //change the direction the tool is moving and find the rotationangle the texture must rotate to point in given direction
                toolPos += (direction * speed * elapsed);
                RotationAngle = (float)Math.Atan2 (direction.Y, direction.X);
            }
        }

        if (direction != Vector2.Zero) {
            direction.Normalize ();
        }

        //move tool in given direction
        toolPos += (direction * speed * elapsed);
        //change cameracentre to the tools position
        Camera.Position = toolPos;
        base.Update (gameTime);
    }

        protected override void Draw (GameTime gameTime)
    {
        graphics.GraphicsDevice.Clear (Color.Blue);
        spriteBatch.Begin (SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, Camera.View);
        spriteBatch.Draw (tool, new Vector2 (toolPos.X, toolPos.Y), null, Color.White, RotationAngle, originOfToolTexture, 1, SpriteEffects.None, 1);
        spriteBatch.End ();

        base.Draw (gameTime);
    }

1 个答案:

答案 0 :(得分:1)

您需要将光标位置转换为世界位置:

Vector2 adjustedPosition = Vector2.Transform(touchCollection[0].Position, Matrix.Invert(camera.View));

然后你的方向是:

direction = adjustedPosition - toolPos;