0
\$\begingroup\$

I have a sprite called Tool that moves with a speed represented as a float and in a direction represented as a Vector2. When I click the mouse on the screen the sprite change its direction and starts to move towards the mouseclick. In addition to that I rotate the sprite so that it is facing in the direction it is heading. However, when I add a camera that is suppose to follow the sprite so that the sprite is always centered on the screen, the sprite won't move in the given direction and the rotation isn't accurate anymore. This only happens when I add the Camera.View in the spriteBatch.Begin(). I was hoping anyone could maybe shed a light on what I am missing in my code, that would be highly appreciated.

Here is the camera class i use:

    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;
    }

}

And here is my Update and Draw-method:

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);
    }
\$\endgroup\$
  • \$\begingroup\$ Shouldnt toolPos be incremented by (RotationAngle * speed * angle)? \$\endgroup\$ – Battle_Pasture Aug 18 '14 at 23:16
  • \$\begingroup\$ This sounds like an issue with the order of the transformations. The faulty rotation and faulty displacement seem like separate issues. What happens if you disable one or the other? Post a minimal example. \$\endgroup\$ – Anko Aug 19 '14 at 11:06
  • 1
    \$\begingroup\$ @Anko ff i don't add the Camera.View in the SpriteBatch.Begin()-method the rotation and the direction the sprite shall move works fine. If I add the camera and disable the rotation, the sprite don't move in the correct direction when I click the mouse on the screen. If i disable that the sprite shall move when I click in a direction and just enable the rotation, the rotation is faulty too when the Camera is added. Don't exactly know what example you want, I'm sorry if I misunderstood. Does the order of transformations in the Camera class look wrong? \$\endgroup\$ – user2236165 Aug 19 '14 at 11:49
  • \$\begingroup\$ It all looks OK, but I can't run your code and "running it in my head" is really hard. On further thought, this question seems to have an XY problem: It might be clearer for everyone if you phrased the question as "How can I do X?" rather than "What's the bug in my implementation of X?". \$\endgroup\$ – Anko Aug 19 '14 at 11:58
0
\$\begingroup\$

You need to convert your cursor position into world position:

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

Then your direction would be:

direction = adjustedPosition - toolPos;
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.