【问题标题】:Issue with matrix transformations and sprite direction矩阵变换和精灵方向的问题
【发布时间】:2014-08-19 11:53:23
【问题描述】:

我有一个名为 Tool 的精灵,它以浮点数表示的速度和 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);
    }

【问题讨论】:

  • 您需要将接触点转换为与Camera.View相反的世界空间。

标签: c# camera xna


【解决方案1】:

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

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

那么你的方向是:

direction = adjustedPosition - toolPos;

【讨论】:

    猜你喜欢
    • 2015-10-08
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    相关资源
    最近更新 更多