0
votes

First of all, i really sorry, because i saw some related topics to this subject, but i could not understand...

I need help to learn how to move a sprite over a map when iam using a camera 2d.

The map has 1800x968. When i move the sprite without the camera, everything works fine.

Let me explain it. I keep a vector2d with the current position of the sprite that i want to move.

When i click in any area of the map, i get the coordinate of the click and move the sprite until there. So, i refresh the current position of the sprite.

I keep the current position because (i think) i have to use it to decide if, for example, i have to move righ or left side. For example: if my current position in x-axis is > than click area in x-axis, i have to move left. I don't know if this strategy is correct, but...

Ok. My screen has 800x480, and, how i said, my map has 1800x968 (bigger than my screen area).

If i click the position 750 (x-axis, right side of the screen), the sprite moves correctly until there. The camera moves too. Everything is ok, but the problem comes now:

The current position of the sprite, in x-axis, is 750 now. But, because my camera moves, my sprite is now at the center of the screen (its not at 750 x-axis anymore, because the camera moved). This is my problem. I have now to thing in an way to click again, for example, in the position 700 this time, and make the sprite moves to the right, but its current position is 750 ( > 700). How can i solve this? Maybe, when the camera changes, i have to refresh the sprite currente position, but i dont know how...

The same problem occurs in y-axis.

Can anyone help me?

Below, is my camera2d code, a sample that i copy from a topic (Thanks in advanced!):

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

2 Answers

0
votes

You need to add the camera's position to the mouse position to give the convert the location from screen coordinates to world coordinates. For example, the camera is at 750 x and you click on pixel 700 x on the screen, this is 1450 (750+700) on the world x axis.

0
votes

If you have displaced your camera so that it it centers itself to the center of your viewport, you need to undo the math when tracking down the mouse position.

Here is now I got mine to work with a tracking camera that centers a target to the middle of the screen:

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

Note: The new vector stuff can be taken out of this for optimization and initialized one in the class scope.

For reference the look at code is:

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