XNA Creators Club Online
Page 1 of 1 (10 items)
Sort Posts: Previous Next

2D Camera Zoom Problem

Last post 09-05-2008 3:39 AM by Aeon. 9 replies.
  • 09-02-2008 4:50 PM

    2D Camera Zoom Problem

    Hello Everyone,

    I've got a simple 2D camera which I would like to zoom in on the middle of a background texture.  The problem I have is that when I move the camera, it always zooms back to the origin, not the new center of the screen.  Here is my Draw method: 

    spriteBatch.Draw(backgroundTexture, position, null, Color.White, 0, origin, scale, SpriteEffects.None, 1);

    After figuring out that the camera was zooming in on the origin, I subtracted the camera's position:

    spriteBatch.Draw(backgroundTexture, position, null, Color.White, 0, origin - camera.Position, scale, SpriteEffects.None, 1);

    While it doesn't zoom as sharply to the origin this way, it still nudges over to the origin instead of straight into the middle of the screen.  I've checked out the Tiled Sprite Sample and how it created a straight-down zoom, and that's where I got the idea to subtract the position.  But I can't quite figure out how to make it go straight into the middle of the screen.  Can anyone see where the problem is?

    Thanks for any help!

    Wayne

  • 09-02-2008 6:40 PM In reply to

    Re: 2D Camera Zoom Problem

    Don't forget that you aren't actually zooming a camera but scaling the texture itself. When an 800x600 background grows to 2x the size then its origin moves from 400x300 to 800x600. Modify your origin proportional to the scale value. But I would also suggest taking a look at a 2d camera class which uses matrices instead. This will provide something closer to a camera where you just modify the camera rather than having to manually modify everything you draw. Holler if you decide to try this route and need some help. Here is an example.
  • 09-03-2008 4:50 AM In reply to

    Re: 2D Camera Zoom Problem

    Hi R333,

    Thanks for the reply.  I went with your second suggestion and downloaded the sample from the link you provided.  From that sample I made a new camera transform Matrix like so:

    transform = Matrix.CreateScale(new Vector3(scale, scale, 0)) *Matrix.CreateTranslation(new Vector3((graphicsDevice.Viewport.Width / 2) + position.X, (graphicsDevice.Viewport.Height / 2) + position.Y, 0)

    So now the scale is taken into account in the camera, instead of the Draw method of Game1.cs.  It still only zooms straight forward when you run the game initially, though.  As soon as you move the camera around, zooming in and out shifts toward the initial position, instead of straight down.  Do I still need to modify the origin in proportion to the scale value?  I'm not quite sure what this would look like.

    Thanks again for any help,

    Wayne 

  • 09-03-2008 1:50 PM In reply to

    Re: 2D Camera Zoom Problem

    Hi! Are you using the position vector2 to change the camera position? I see no reason why zooming shouldn't work after that. Have you made sure that all your draw calls no longer take the camera position or zoom into account?
  • 09-03-2008 3:00 PM In reply to

    Re: 2D Camera Zoom Problem

    Short circuit your draw method and try a test render to make sure its not something you forgot to remove. Something like this right at the beginning.

    graphics.GraphicsDevice.Clear(Color.Purple);
    spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None, transform
    );
    spriteBatch.Draw(marioSprite, new Vector2(100), Color.White);
    spriteBatch.End();
    return;
    If this doesn't work then your problem is something minor in the camera matrix or how you update its position. If it does then you need to sort out what you forgot to remove from the way you USED to draw the objects. And by the way the matrix handles everything for you so only use the scale parameter of a draw call if you are trying to stretch the image out in addition to the camera's zoom.
  • 09-04-2008 4:24 AM In reply to

    Re: 2D Camera Zoom Problem

    Thanks for both of those suggestions.  I made sure to take out any reference to the camera scale or zoom.  So here is my complete Draw call in Game1.cs:

    spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState,
    camera.Transform);
    spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);
    spriteBatch.End();

    Here is my complete Update method in my camera class (the scale has a default value of 1):

    if (Keyboard.GetState().IsKeyDown(Keys.A))
    position.X -= speed;
    if (Keyboard.GetState().IsKeyDown(Keys.D))
    position.X += speed;
    if (Keyboard.GetState().IsKeyDown(Keys.S))
    position.Y += speed;
    if (Keyboard.GetState().IsKeyDown(Keys.W))
    position.Y -= speed;

    if (Keyboard.GetState().IsKeyDown(Keys.Q))
    scale += 0.01f;
    if (Keyboard.GetState().IsKeyDown(Keys.E))
    scale -= 0.01f;

    transform = Matrix.CreateScale(new Vector3(scale, scale, 0))
    * Matrix.CreateTranslation(new Vector3(
    (graphicsDevice.Viewport.Width / 2) - position.X,
    (graphicsDevice.Viewport.Height / 2) - position.Y, 0)); 

    So it's all really basic, but it still will not zoom in directly forward when the camera is moved.  It seems like it takes the Vector2.Zero in the Draw call

    and always zooms in toward that, because whenever I change that number to something else, like maybe (400, 300), then it always zooms in towards that

    coordinate.  I'm not sure how to make the position parameter of the Draw call always update as the middle of the screen, wherever the camera is.  Any ideas?

    Wayne

     

     

  • 09-04-2008 8:42 AM In reply to

    Re: 2D Camera Zoom Problem

    Try switching around the transform matrices!

    transform = Matrix.CreateTranslation(new Vector3( (graphicsDevice.Viewport.Width / 2) - position.X, (graphicsDevice.Viewport.Height / 2) - position.Y, 0)) * Matrix.CreateScale(new Vector3(scale, scale, 0);

  • 09-04-2008 10:24 PM In reply to

    Re: 2D Camera Zoom Problem

    Wow that is totally my bad. I was just looking at the code in the example and noticed that his code would do what you are describing.. Its not your fault that its not working. I'm not at home right now to double check this so you might need to tweak it a bit. This will help you visualize whats happening.

                _transform = Matrix.Identity *
                    Matrix.CreateTranslation(-_position.X, -_position.Y, 0) *
                    Matrix.CreateRotationZ(_rotation) *
                    Matrix.CreateTranslation(_origin.X, _origin.Y, 0) *
                    Matrix.CreateScale(new Vector3(_scale, _scale, _scale));

                Camera.Origin = ScreenCenter / Camera.Scale;
                Camera.Position = Player.Position;
                Camera.Update(gameTime);

    Remember that camera position is where you want the CENTER of the screen instead of the top left. I'm house hunting for the next few days but there are lots of people here with way more experience than me if you need further help. I'll try and drop in from time to time though.
  • 09-05-2008 12:30 AM In reply to

    Re: 2D Camera Zoom Problem

    Thanks R333, that is perfect!  I made up the ScreenCenter like so:

    screenCenter = new Vector2(graphicsDevice.Viewport.Width / 2, graphicsDevice.Viewport.Height / 2);

    and it works really well.  It does stagger when zooming when you initially hit the zoom button, but that's minor and I can figure that out.  Thanks very much for all your help, and you too zanders.  Good luck with your house hunting,

    Wayne 

  • 09-05-2008 3:39 AM In reply to

    Re: 2D Camera Zoom Problem

    a useful bit of math for easing to a Vector2 position in your update loop could loop like...
    Position.X += (Destination.X - Position.X) * 0.5f;
    Position.Y += (Destination.Y - Position.Y) * 0.5f;
    //By subtracting your position from your destination, you get it's distance which is signed (+ or -) based on the direction. Multiply by 0.5f (or divide by 2) to get half the distance in the correct direction

    This is an example of moving your camera to a specific target point.  Add a Z axis for 3D if you wish, it's the same formula.  Of course, the best approach would be to set a boolean to true when you want to move, then do an IF statement to see if the position after the math is equal to (or close to) the destination, then set the boolean to false to bypass the math.  Then go about building your matrix using your new position vector.

Page 1 of 1 (10 items) Previous Next