I want to zoom about an arbitrary zoom point. For example, if the player tabs on a place on his windows phone display, this place(position) should get the new center of his viewport. In addition, the camera zooms so that the place looks bigger. If the player tabs again in zoom mode, the camera just needs to zoom out and the center of the viewport rests the same like in zoom mode.
I'm doing a 2D point and click adventure, so it is very important to examine the environment.
If I tab on a place, it's not getting the center of the viewport. The center of the viewport always is somewhere else. What is wrong with my code?
I found the camera class in this tutorial: http://www.david-amador.com/2009/10/xna-camera-2d-with-zoom-and-rotation/
How can I do the zoom? I found a similar question on stackoverflow but I don't understand how they solved the problem: http://stackoverflow.com/questions/9348866/xna-2d-camera-with-arbitrary-zoom-center
Camera class:
public class Camera2d
{
protected float _zoom; // Camera Zoom
public Matrix _transform; // Matrix Transform
public Vector2 _pos; // Camera Position
protected float _rotation; // Camera Rotation
public Camera2d()
{
_zoom = 1.0f;
_rotation = 0.0f;
_pos = Vector2.Zero;
}
// Sets and gets zoom
public float Zoom
{
get { return _zoom; }
set { _zoom = value; if (_zoom < 0.1f) _zoom = 0.1f; } // Negative zoom will flip image
}
public float Rotation
{
get { return _rotation; }
set { _rotation = value; }
}
// Auxiliary function to move the camera
public void Move(Vector2 amount)
{
_pos += amount;
}
// Get set position
public Vector2 Pos
{
get { return _pos; }
set { _pos = value; }
}
public Matrix get_transformation(GraphicsDevice graphicsDevice)
{
Viewport viewPort = graphicsDevice.Viewport;
_transform =
Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
Matrix.CreateRotationZ(Rotation) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
Matrix.CreateTranslation(new Vector3(viewPort.Width * 0.5f, viewPort.Height * 0.5f, 0));
return _transform;
}
}
How I use the camera:
GestureSample gs;
cam.Pos = new Vector2(graphics.PreferredBackBufferWidth / 2, graphics.PreferredBackBufferHeight / 2);
TouchPanel.EnabledGestures = GestureType.Tap;
void UpdateZoom(float newZoom)
{
Vector2 currentMouseTarget = new Vector2(cam.Zoom * gs.Position.X, cam.Zoom * gs.Position.Y);
Vector2 nextMouseTarget = new Vector2(newZoom * gs.Position.X, newZoom * gs.Position.Y);
cam.Pos += (nextMouseTarget - currentMouseTarget) * newZoom;
cam.Zoom = newZoom;
}
protected override void Update(GameTime gameTime)
{
while (TouchPanel.IsGestureAvailable)
{
gs = TouchPanel.ReadGesture();
switch (gs.GestureType)
{
case GestureType.Tap:
UpdateZoom(2.0f);
break;
}
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend,
null,
null,
null,
null,
cam.get_transformation(graphics.GraphicsDevice));
spriteBatch.Draw(TestSprite, new Rectangle(200, 200, TestSprite.Width,TestSprite.Height), null,Color.White,0,new Vector2(TestSprite.Width/2,TestSprite.Height/2), SpriteEffects.None,1);
spriteBatch.End();
base.Draw(gameTime);
}