0
\$\begingroup\$

Im building a tile-based game, and Im trying to implement zooming in on the center of the screen. My problem is, when I get to the edge of the map and im zoomed in, Im noticing that my camera doesn't scroll all the way to the very last tile when zoomed in. If my zoom scale value is 1(not zoomed in), the camera moves to the last edge of the tile map just fine.

I have a feeling my matrix math is wrong, and I should be setting the position of the camera differently. It could also be that my tile map edge checking is incorrect. I currently limit the user to zoom in by a factor of 2 at maximum

Heres my code:

public class CameraPositionComponent : PositionComponent
{
    private Vector2 mOrigin;
    private Viewport mViewport;
    private Matrix mMatrix;
    private float mZoom;

    public CameraPositionComponent(int x, int y, Viewport viewport, Entity owner) :   base(x, y, owner)
    {
        mZoom = 1.0f;
        mViewport = viewport;
        mPosition = new Vector2(viewport.Width / 2, viewport.Height / 2);
        mOrigin = new Vector2(viewport.Width / 2, viewport.Height / 2);
        mMatrix = Matrix.CreateTranslation(1, 1, 1);
    }

    public Matrix Matrix
    {
        get { return mMatrix; }
        set { mMatrix = value; }
    }

    public float Zoom
    {
        get { return mZoom; }
        set { mZoom = value; }
    }

    public Vector2 Origin
    {
        get { return mOrigin; }
        set { mOrigin = value; }
    }


    public Viewport Viewport
    {
        get { return mViewport; }
    }
}

public class CameraTouchComponent : TouchComponent
{

    public CameraTouchComponent(Entity owner) : base(owner)
    {

    }

    public override void Update()
    {
        GameTime gameTime = ServiceLocator.GetService<GameTime>();
        Camera camera = mOwner as Camera;
        CameraPositionComponent positionComponent = camera.PositionComponent;

       /////input handling here
      ////zoom/drag etc..

        if (positionComponent.Position.X < positionComponent.Viewport.Width / 2)
            positionComponent.Position = new Vector2((positionComponent.Viewport.Width / 2), positionComponent.Position.Y);
        if (positionComponent.Position.Y < positionComponent.Viewport.Height / 2)
            positionComponent.Position = new Vector2(positionComponent.Position.X, positionComponent.Viewport.Height / 2);
        if (positionComponent.Position.X + positionComponent.Viewport.Width/2 > TileMap.Width)
            positionComponent.Position = new Vector2(TileMap.Width - positionComponent.Viewport.Width/2,
                positionComponent.Position.Y);
        if (positionComponent.Position.Y + positionComponent.Viewport.Height / 2 > TileMap.Height)
            positionComponent.Position = new Vector2(positionComponent.Position.X,  TileMap.Height - positionComponent.Viewport.Height / 2);
        //positionComponent.Origin = new Vector2((positionComponent.Viewport.Width / 2) / positionComponent.Zoom, (positionComponent.Viewport.Height / 2) / positionComponent.Zoom);

        Layer layer = LayerManager.GetLayerOfEntity(mOwner);
        layer.Matrix =  Matrix.CreateTranslation(new Vector3(-positionComponent.Position, 0)) *
                  Matrix.CreateScale(positionComponent.Zoom, positionComponent.Zoom, 1) *
                   Matrix.CreateTranslation(positionComponent.Origin.X, positionComponent.Origin.Y, 0); ;

    }
}

All the bounds checking stuff seems wrong to me as well.

\$\endgroup\$
  • \$\begingroup\$ i feel like you should update the positionComponent.Origin like you have commented out, but without dividing it by positionComponent.Zoom and put this code before you change the Position. Also, try with and without multiplying Matrix.CreateTranslation(positionComponent.Origin.X, positionComponent.Origin.Y, 0); where you calculate the layer.Matrix. Also, try moving this code before the Matrix.CreateScale(...) multiplication. See if any of this works \$\endgroup\$ – dimitris93 Apr 13 '15 at 0:15
  • \$\begingroup\$ Ive basically tried all of this already. If I dont multiply Matrix.CreateTranslation(positionComponent.Origin.X, ...) it will just end up zooming in as the top right corner as the origin. If i update the origin, the zooming doesnt work quite right etc \$\endgroup\$ – iNFiNiTY Apr 13 '15 at 2:31
0
\$\begingroup\$

for anyone else wondering how to do this. Try this:

http://www.david-gouveia.com/portfolio/limiting-2d-camera-movement-with-zoom/

\$\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.