c# XNA 4.0 Camera zoom and sprite resizing

2.6k views Asked by At

Inside my project, I have a sprite being draw of a box. I have the camera zoom out when clicking a key. When I zoom out, I want my box to scale it's dimensions so it stays consistent even though the camera has zoomed out and "shrunk" it.

I have tried multiplying the object's dimensions by 10% which seems to be the viewpoint's adjustment when zooming out, but that doesn't seem to work. Now this may sound dumb, but would scaling the sprite in the draw function also change the sprite's dimensions?

Let's say the box is 64x64 pixels. I zoom out 10% and scale the sprite. Does the sprite still have the boundaries as 64x64 or is the up-scaling also changing it's dimensions?

2

There are 2 answers

3
Gabriel Davidian On BEST ANSWER

To change sprite dimensions you need to change Rectangle parameter for SpriteBatch.Draw. To calculate zoom on rectange:

Rectangle scaledRect = new Rectangle(originalRectangle.X, originalRectangle.Y, (int)(originalRectangle.Width*zoom), (int)(originalRectangle.Height*zoom)); // where zoom default is 1.0f

When drawing use:

spriteBatch.Draw(Texture, scaledRect, Color.White);

Now I'm sorry to assume it, but without knowing why you doing what you doing - I think you doing something wrong.

You should use camera transformation to zoom out/in. It is done like that:

var transform = Matrix.CreateTranslation(new Vector3(-Position.X, -Position.Y, 0))* // camera position
                         Matrix.CreateRotationZ(_rotation)* // camera rotation, default 0
                         Matrix.CreateScale(new Vector3(Zoom, Zoom, 1))* // Zoom default 1
                         Matrix.CreateTranslation(
                             new Vector3(
                                 Device.Viewport.Width*0.5f,
                                 Device.Viewport.Height*0.5f, 0)); // Device from DeviceManager, center camera to given position
SpriteBatch.Begin( // SpriteBatch variable
            SpriteSortMode.BackToFront, // Sprite sort mode - not related
            BlendState.NonPremultiplied, // BelndState - not related
            null,
            null,
            null,
            null,
            transformation); // set camera tranformation

It will change how sprites are displayed inside sprite batch, however - now you also must account for different mouse coordinates (if you using mouse input). To do that you must transform mouse position to transformed world matrix:

// mouse position, your tranformation matrix 
public Vector2 ViewToWorld(Vector2 pos, Matrix transform) 
{
    return Vector2.Transform(pos, Matrix.Invert(transform));
}

I used the code without direct access to test it, so if something will not work - feel free to ask.

This is not answer to your question directly, if you could provide reason why you want re-size sprite when zooming instead of zooming camera - maybe I could better answer your question, also you should fallow markmnl link to understand world transformations and why you seem to need it in this situation.

0
markmnl On

Scaling using SpriteBatch.Draw()s scale argument will just draw the sprite smaller/bigger, i.e. a 64x64 one will appear as 7x7 pixels (the outer pixels being alpha blended if enabled). However there are no size properties on the sprite, if you have your own rectangle, position variables for the sprite SpriteBatch.Draw() of course will not change those.

An alternative is draw the sprite in 3D space then everything is scaled when you move your camera, so the sprite will appear smaller though it will still be a 64x64 sprite.

How to draw a sprite in 3D space? Here is a good tutorial http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2/Point_sprites.php. (You will need to take time to learn about using 3D viewports, camera's etc, see here: http://msdn.microsoft.com/en-us/library/bb197901.aspx)/