Hey! I'm David Amador,
and I'm a programmer. I do mostly game development. Oh I have a twitter

My latest Game

This is the latest game I developed. Buy it if you want to support me and my work. More info

Latest tweets

    XNA Camera 2d with zoom and rotation

    12 Oct
    2009

    One of the things I keep finding is people asking how to do a simple camera 2d in XNA. Today I decided to contribute with my own solution.

    Most of the time the solution given is to have a class camera with a Vector2 position and when drawing the sprite batch to subtract the camera position to the sprite position itself. Although this work from my point of view it’s not elegant and you can’t have neat features like zooming and rotation.  So for my tutorial I’ll do all transformations using a Matrix.
    Start off by creating the basic class Camera2d

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

    Now that we have the basic setup onto the variables it’s time to create a couple of functions to manipulate the variables

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

    And now for the function that calculates all the transformations

    public Matrix get_transformation(GraphicsDevice graphicsDevice)
            {
                _transform =       // Thanks to o KB o for this solution
                  Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
                                             Matrix.CreateRotationZ(Rotation) *
                                             Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) *
                                             Matrix.CreateTranslation(new Vector3(ViewportWidth * 0.5f, ViewportHeight * 0.5f, 0));
                return _transform;
            }

    So now how can we use it?
    Simple on your sprite batch begin you must add the camera transformation.

    Camera2d cam = new Camera2d();
    cam.Pos = new Vector2(500.0f,200.0f);
    // cam.Zoom = 2.0f // Example of Zoom in
    // cam.Zoom = 0.5f // Example of Zoom out
     
    spriteBatch.Begin(SpriteBlendMode.AlphaBlend,
                            SpriteSortMode.Immediate,
                            SaveStateMode.SaveState,
                            cam.get_transformation(device /*Send the variable that has your graphic device here*/));
     
    // Draw Everything
    // You can draw everything in their positions since the cam matrix has already done the maths for you 
     
    spriteBatch.End(); // Call Sprite Batch End

    Found any errors? Please let me know.

    Related Posts:

    54 Responses to XNA Camera 2d with zoom and rotation

    Avatar

    Mike

    October 23rd, 2009 at 6:00

    This looks great, but I am either too new to understand it, or I am missing something, How do I invoke the changes by either using the keyboard or controller. I am trying to pass a new vector2 to cam.move, trying to set _pos… just cant get it. any help appreciated. Thanks

    Avatar

    Mike

    October 23rd, 2009 at 7:50

    I posted the other response and just wanted to let you know that I got it figured out. I was trying to set the position the wrong way… I still have a problem with get:set: and stuff like that. But thank you so much for the camera option you have here. works great!

    Avatar

    ^DJ_Link^

    October 23rd, 2009 at 7:56

    For using get:set you have to do something like

    Camera2d cam = new Camera2d();
    cam.Pos = Vector2(500.0f,200.0f);

    for using the move

    cam.Move(new Vector2(30,20));

    I hope this helped

    Avatar

    Alexander

    October 23rd, 2009 at 8:40

    Nice camera! how can i make rotation and scaling around cameras center point? not around left top corner?

    Avatar

    william

    November 13th, 2009 at 17:19

    1rst: Great tutorial and really helpfull source code.

    However there are some things i would like to point out to anyone that may be getting a bit confused:

    (alexander: look toward bottom of this post for your answer)

    First (i did not realize this) the camera is separte from what you are rendering, thus whatever you put on the screen should be in real co-ordinates. I ran into a problem with a tilemap because i was setting the tiles to always being drawn starting at 0,0 and was wondering why when i moved the camera it wasnt showing the rest of the rather large map. What i did was draw the sprites as they would be in their world coordinates. This made it accurate as the camera moves around the map not the map moving around the camera!

    Also pay particular attention to this line.

    new Vector3((_zoom * _zoom * _zoom),
                                     (_zoom * _zoom * _zoom), 0))

    See somthing odd here. The code is taking zoom and multiplying it by itself 3x! This was throwing all my calcluations off. The first thing i did was set that line above to:

    new Vector3((_zoom),
                                     (_zoom), 0))

    Now your zoom level is accurate to how much you are actually zooming.

    Now lets concentrate on the last part of code:

     Matrix.CreateTranslation(
                    new Vector3((graphicsDevice.Viewport.Width * 0.5f) - _pos.X,
                                     (graphicsDevice.Viewport.Height * 0.5f) - _pos.Y,
                                      0));
            return _transform;

    This is basically going to adjust for the camera’s movement. (which with normal cameras would just be – posx and – posy right? Well think about what that assumes. It assumes your origin is at the top left of the screen (0,0).

    However this piece of code puts your camera origin at the center of the screen! Think of it with camera position of 0,0 with a screen size of 800width and 600height:

    new Vector3((400) - 0,
                                     (300) - 0,
                                      0));

    Here at no camera movement the origin of the camera is at the center of the screen. This means that if you are drawing your tiles (or whatever it is) starting at position 0,0 then you will see that tile in the upper left part of the screen (rather than in the middle)!

    Also dont forget to account for zooming so:

     Matrix.CreateTranslation(
                    new Vector3((graphicsDevice.Viewport.Width * 0.5f) - (_pos.X *_zoom),
                                     (graphicsDevice.Viewport.Height * 0.5f) - (_pos.Y*_zoom),
                                      0));
            return _transform;

    (That will make sure that when you zoom the camera stays at the center point)

    Here is a note on zooming that took me a bit to figure out that you might find helpful in calculating things.
    Assuming width of tiles are 32, then how large or small is the tile enlarged when zoomed.

    well you can (zoom * 32) this will tell you the size of the current tile if it is expanded or minimized

    For instance

    zoom tile width
    .9 28.8
    1.0 32
    1.1 35.2

    If you are handling camera movement where you want the camera to stop if your character is past a certain point (so that you dont
    see the black areas of the screen) all you need to do is keep track of a seperate x and y value (that is the character movement) and
    when the x passes the center point the appropriate camera value needs to pick up and start updating as well, otherwise it needs to be set at that barrier.

    For instance in my game the barrier is 400 x and 300 y.

    So when my char.x is < 400 then my camera should be stuck at 400. Else update camera x with char.x –(this will effectively pick up the camera when my char passes a certain point).

    Hopefully this will make a little bit of sense. I am still working through the whole camera thing myself.

    Avatar

    2D Camera Issue | Xbox360 News

    November 16th, 2009 at 6:53

    [...] I followed the tutorial on http://www.david-amador.com/2009/10/xna-camera-2d-with-zoom-and-rotation/ to achieve a camera that follows my player sprite with zoom in/out [...]

    Avatar

    2D Camera Issue | Xbox360 News

    November 16th, 2009 at 6:53

    [...] I followed the tutorial on http://www.david-amador.com/2009/10/xna-camera-2d-with-zoom-and-rotation/ to achieve a camera that follows my player sprite with zoom in/out [...]

    Avatar

    Adam

    November 22nd, 2009 at 14:35

    Hi,

    Very nice solution! Congrat.

    Avatar

    Alain

    November 25th, 2009 at 10:21

    How would you apply this when you would want to have 2 camera’s to follow 2 separate players?

    Avatar

    Alain

    November 25th, 2009 at 10:32

    Nevermind I already figured it out. You can just draw the “scene” twice and place the second camera where you want it.

    Avatar

    ^DJ_Link^

    November 25th, 2009 at 11:49

    Exactly. If you want to do a splitscreen for instance just draw the scene twice on different viewports.
    I got this result using the camera with viewports http://www.youtube.com/watch?v=w0bELIEC0Q8

    Avatar

    Anonymous Coward

    December 7th, 2009 at 9:12

    Now I got it! You just made my day. Thanks.

    Avatar

    Ko9

    December 14th, 2009 at 19:49

    Very nice, saved me a bit of time implementing this myself.. There are a few errors that I needed to fix first, but all of them very superficial. Thanks!

    Avatar

    André

    December 29th, 2009 at 22:34

    Hi, David! Nice tutorial. But can you correct the first block of code?

    Use

    _pos = Vector2.Zero;

    Instead

    _pos = new Vector2.Zero;

    Thanks!!!! =)

    Avatar

    ^DJ_Link^

    December 29th, 2009 at 22:50

    Hi André. Thanks for the tip, you are right Vector2.Zero is static, no need for new before.

    Regards =)

    Avatar

    Zms

    January 12th, 2010 at 22:29

    Nice solution!

    How do i get the world co-ordinates from the mouse cursor when using the camera?

    Avatar

    ^DJ_Link^

    January 13th, 2010 at 18:14

    Just add the camera position to the mouse position, do a function like this

     public Vector2 get_mouse_vpos()
      {
                Vector2 mp = new Vector2(Mouse.GetState().X,Mouse.GetState().Y);
                return (mp  + _camera.pos); // Camera is a member of the class in this example
      }

    Let me know if you run into any trouble.

    Avatar

    Zms

    January 14th, 2010 at 2:22

    Thank you! Works great…

    Avatar

    Craig

    February 11th, 2010 at 21:29

    Hey man!

    I’ve been trying for hours to get a working camera. But I’m really lost and really new to programming ^^

    Just wondering why when I copy the code in there’s instantly errors. Is this too advanced for me or what? :D

    thanks.

    The errors are “Rotation” Viewportwidth & Viewportheight, and
    if (_zoom < 0.1f) _zoom = 0.1f;

    Avatar

    ^DJ_Link^

    February 11th, 2010 at 21:44

    Actually you are right, there is something wrong with that function. try replacing the get_transform function with something like this instead

    public Matrix get_transformation(GraphicsDevice graphicsDevice)
            {
                _transform =       // Thanks to o KB o for this solution
                  Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
                                             Matrix.CreateRotationZ(_rotation) *
                                             Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) *
                                             Matrix.CreateTranslation(new Vector3(graphicsDevice.Viewport.Width * 0.5f, graphicsDevice.Viewport.Height * 0.5f, 0));
                return _transform;
            }

    Tell me how it went

    Avatar

    Craig

    February 12th, 2010 at 17:37

    Okay, I changed that function and ran the program with no problems(no errors :D )

    But whenever I move my little sprite he still runs off the screen and I can’t move the screen across the x-axis.

    Is there a way to make this camera code follow my Sprite?
    or move the camera.

    thanks.

    Avatar

    Craig

    February 12th, 2010 at 17:49

    Going to rewrite.

    Getting myself confused.

    When I try to put this above spritebatch begin I get errors

    Camera2d cam = new Camera2d();
    cam.Pos = Vector2(500.0f,200.0f);

    I changed the Camera2d to Camera2D and it changed colour, but the there was errors with the spritebatch below it.

    spriteBatch.Begin(SpriteBlendMode.AlphaBlend,
    SpriteSortMode.Immediate,
    SaveStateMode.SaveState,
    cam.get_transformation);

    Also there is an error with Vector2, really confused lol :)

    any ideas?

    Avatar

    ^DJ_Link^

    February 12th, 2010 at 18:30

    Yes there is. You can move the camera by changing the variable
    cam.Pos to your character position.
    Each time you move your character update the camera as well

    Avatar

    ^DJ_Link^

    February 12th, 2010 at 18:32

    My bad again,

    cam.Pos = Vector2(500.0f,200.0f);

    should be

    cam.Pos = new Vector2(500.0f,200.0f);

    Avatar

    Craig

    February 13th, 2010 at 17:39

    could you give an example :( of how I update the camera to my sprites position.

    i know how to move the camera from its current location, which is center screen thanks to previous feedback.

    my sprite is called mMainCharacterSprite

    thanks, and sorry for my lack of knowledge :P

    Avatar

    ^DJ_Link^

    February 13th, 2010 at 17:42

    Does your Sprite has a member Vector2 to save it’s position? Where are you saving the mMainCharacterSprite position?
    just equal the camera.pos to that vector2

    Avatar

    schnabel

    February 14th, 2010 at 13:20

    the get_mouse_vpos() method doesn’t work with zooming. Any idea how to fix this? I just can’t get it to work.

    Avatar

    ^DJ_Link^

    February 14th, 2010 at 15:16

    I’m not interely sure if this will work but maybe multiplying the mouse position with Zoom before adding the camera position

     public Vector2 get_mouse_vpos()
      {
                Vector2 mp = new Vector2(Mouse.GetState().X,Mouse.GetState().Y);
     
                return ((mp * _camera.Zoom)  + _camera.pos); // Camera is a member of the class in this example
      }

    I’ve only considered Zoom when clicking a rectangle for testing if is inside and I simply multiply it’s size per Zoom so I’m guessing it should work with the mouse position as well. Let me know

    Avatar

    Medic

    February 14th, 2010 at 17:19

    Craing something like

    cam.pos = player.body.positin

    in your update method

    Avatar

    Craig

    February 14th, 2010 at 17:19

    ok thanks, got it working. Thanks for your help dude. I

    Avatar

    schnabel

    February 15th, 2010 at 11:37

    Thank you for your help still doesnt work. How did you do the “clickinsiderectangle” method? i create a rectangle from the virtual position of the mouse and ask if it intersects another rectangle. I also always have to add the middle of my screen as a Vector2(for example 800,600 in my case) to the x,y position of the rectangle I want to click to get valid coordinates. Maybe I have to multiply the zoom with this offset? Tried it…doesn’t do it.
    Pretty confused why this isn’t working.

    Avatar

    Erik

    February 21st, 2010 at 11:28

    This camera works fine for me :) except this camera moves in the world : )) Is there any option that camera position will be fixed and world will be moving around it ? : )

    For example i got object in middle of the screen with fixed position (viewPort.Width/2, viewPort.Height/2) and the rest of the world is moving around this object, depending on keyboard input :) )

    This camera changes the position of my object in world : )

    Avatar

    ^DJ_Link^

    February 21st, 2010 at 14:35

    The camera being fixed and the rest moves is kind of the point that I wanted to avoid when I built this class. What makes sense is to move a camera in in world. Not translate everything to be on the camera. The camera itself does not change the position of anything except for itself. The Transformation Matrix simply moves the world to that specific position, draws it and that’s it. Your objects still keep their positions.
    If you want to make Fix objects and still move the rest of the stuff you can, let’s take GUI objects for instance, they are always fixed you simply draw it in two batches. One of them with the camera transformation draws everything that moves, the other one, the gui stuff is drawn without that transformation

    spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState, cam.get_transformation());
     // Draw Moveble Objects 
    spriteBatch.End(); // Call Sprite Batch End
    spriteBatch.Begin();
    // Draw Gui Stuff
    spriteBatch.End(); // Call Sprite Batch End

    Hope this helps

    Avatar

    Erik

    February 21st, 2010 at 14:54

    :) ) Misunderstand :) Its not for gui.

    I used to check object.IsVisible with if object.position.x >viewPortRect.Width return false …. because my camera i used before was still keeping the followed “sprite” (my spaceship for instance) in its initializated Position : ) and moving were all the objects around :)
    Now i had to check trough object.position.X> viewPortRect.Width + cam.pos.X – viewPortRect.Width/2.

    The only problem was i had to repair my code on .. lots of places.. not very good solution though. :)
    I already extended my math functions so it works fine with the camera :) )
    Thanks for help and swift answer :)

    Avatar

    Drej

    March 3rd, 2010 at 15:01

    Hi there,
    Thank you very much for this great tutorial, it helped me a great deal and got me working on my project again. I just have a short question which may be too general to ask here but I’ll do it anyway: How would I go about making the screen rotate smoothly? If I just set the _rotation variable to a certain value the screen instantly snaps to the new position, and something like

    for(float i=0f; i < rotation_amount; i += 0.0001f)
    { _rotation += 0.0001f }

    doesn't work either as it is too fast, no matter how small the increments are. Can anyone point me in the right direction?

    Avatar

    ^DJ_Link^

    March 3rd, 2010 at 15:15

    You could update the rotation on the Update pump, something like camera._rotation+=0.001f; on every update until the value is what you want.

    Avatar

    bluehair

    March 10th, 2010 at 19:07

    Hey, great tutorial I found it very handy.

    Though I have a problem, I am not sure how to solve, to determine if a sprite is displayed within the 2D viewport, when the camera has been rotated. Bascially I want an indicator to show the angle of an object only when the object moves offscreen.

    Avatar

    David Tomaž

    March 10th, 2010 at 20:38

    If anyone has a problem getting World – mouse coordinates, use the following way of transforming your matrix and calculating the right coordinates (it works with zooming).

    Transformation :

            public Matrix get_transformation(GraphicsDevice graphicsDevice)
            {
                _transform = Matrix.CreateTranslation(new Vector3(-graphicsDevice.Viewport.Width * 0.5f - _pos.X, -graphicsDevice.Viewport.Height * 0.5f - _pos.Y, 0)) * Matrix.CreateScale(
                    new Vector3((_zoom * _zoom * _zoom),
                    (_zoom * _zoom * _zoom), 0))
                * Matrix.CreateRotationZ(_rotation)
    	           * Matrix.CreateTranslation(new Vector3(
                    graphicsDevice.Viewport.Width * 0.5f, graphicsDevice.Viewport.Height * 0.5f, 0));
     
                return _transform;          
            }
     
     
    Calculating Mouse (world) coordinates :
     
       public Vector2 get_mouse_vpos()
            {
                float MouseWorldX = (Mouse.GetState().X - m_gDevice.Viewport.Width* 0.5f + ( m_gDevice.Viewport.Width * 0.5f+cam2d.Pos.X)*(float)Math.Pow(cam2d.Zoom,3)) /
                      (float)Math.Pow(cam2d.Zoom, 3);
     
                float MouseWorldY = ((Mouse.GetState().Y - m_gDevice.Viewport.Height * 0.5f + (m_gDevice.Viewport.Height * 0.5f+cam2d.Pos.Y )*(float)Math.Pow(cam2d.Zoom, 3))) /
                        (float)Math.Pow(cam2d.Zoom, 3);
     
                return new Vector2(MouseWorldX, MouseWorldY);
            }

    I hope this helps you.

    Avatar

    Timing Problems and Solutions « Varcade

    March 14th, 2010 at 13:50

    [...] added a 2D Camera to the game. This allows zooming, panning, and rotation of everything in the game word.  I'm not [...]

    Avatar

    Ratboy

    March 17th, 2010 at 12:47

    Hey I was wondering why this doesn’t work:

    using System;
    using System.Collections.Generic;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using Microsoft.Xna.Framework.Net;
    using Microsoft.Xna.Framework.Storage;
     
    namespace Debug1
    {
        public class Game1 : Microsoft.Xna.Framework.Game
        {
            GraphicsDeviceManager graphics;
            SpriteBatch spriteBatch;
     
            public Game1()
            {
                graphics = new GraphicsDeviceManager(this);
                graphics.PreferredBackBufferWidth = 500;
                graphics.PreferredBackBufferHeight = 500;
                Content.RootDirectory = "Content";
            }
            protected override void Initialize()
            {
                base.Initialize();
            }
            protected override void LoadContent()
            {
                spriteBatch = new SpriteBatch(GraphicsDevice);
            }
            protected override void UnloadContent()
            {
            }
     
            protected override void Update(GameTime gameTime)
            {
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();
                base.Update(gameTime);
            }
     
            float zoom = 1.0F;
            float rotation = 45.0F;
            float offset = 0.0F;
            protected override void Draw(GameTime gameTime)
            {
                //zoom += 0.01F;
                //rotation += 0.1F;
                offset += 1.0F;
                float x = graphics.GraphicsDevice.Viewport.Width * 0.5F + offset;
                float y = graphics.GraphicsDevice.Viewport.Height * 0.5F + offset;
                Matrix matrice =
                    Matrix.CreateTranslation(new Vector3(-16 + offset, -16 + offset, 0)) *
                    Matrix.CreateRotationZ(MathHelper.ToRadians(rotation)) *
                    Matrix.CreateScale(new Vector3(zoom, zoom, 0)) *
                    Matrix.CreateTranslation(new Vector3(x, y, 0));
     
                spriteBatch.Begin(
                    SpriteBlendMode.AlphaBlend,
                    SpriteSortMode.Immediate,
                    SaveStateMode.SaveState,
                    matrice);
                GraphicsDevice.Clear(Color.CornflowerBlue);
                spriteBatch.Draw(this.Content.Load("test1"),
                    new Vector2(0, 0),
                    Color.White);
                spriteBatch.End();
                base.Draw(gameTime);
            }
        }
    }

    Basically there is an offset which is the camera XY but I’ve dumbed it down for testing.

    Avatar

    ^DJ_Link^

    March 17th, 2010 at 13:02

    First of all, don’t ever ever do this spriteBatch.Draw(this.Content.Load(“test1″),
    Load it to a Texture2D and pass that variable to the spriteBatch
    Second, what are you trying with Matrix.CreateTranslation(new Vector3(-16 + offset, -16 + offset, 0)) ??
    What exactly is not working?

    Avatar

    Craig

    March 26th, 2010 at 0:08

    Hey David, I have everything working to a good standard now.

    I have to Zoom function working to a certain degree, I can put a fixed floating point number on it – But I was wondering if I could create it zooming in/out by keypress

    I thought it was something like this

    if (s.IsKeyDown(Keys.P))
    {
    _zoom++;
    }

    But im not entirely sure where I would put this, doesnt seem to working in my main game code . Any Ideas, maybe even a simpler way because on your youtube video I see that you zoom in and out.

    Avatar

    ^DJ_Link^

    March 26th, 2010 at 0:47

    Add this function to the Camera Zoom Class

    function void IncrementZoom(float amount)
    {
       Zoom = Zoom + amount;
    }

    Then, iside your Update(Gametime gametime) on the Game class do something like this:

     
    public override void Update(Gametime gametime) 
    {
    // Get Keyboard State
     KeyboardState kbState = Keyboard.GetState();
    // Detect if Key Up is Down
    // camera is an instance of the Camera2D
    if(kbState.IsKeyDown(Keys.Up)) camera.IncrementZoom(0.5f);
    // Detect if Key Down is Down
    if(kbState.IsKeyDown(Keys.Down)) camera.IncrementZoom(-0.5f);
    }

    Hope it helps. Let me know if you run into any issue. I’m writing this from memory and I can be wrong on some syntax. Cheers

    Avatar

    Craig

    March 27th, 2010 at 19:02

    function void IncrementZoom(float amount)
    {
    Zoom = Zoom + amount;
    }

    im getting an error with the void saying its not valid.

    the rest seems fine.

    ive never used function before either.

    thanks :)

    Avatar

    ^DJ_Link^

    March 27th, 2010 at 19:45

    Ups, mistyped, just write

    public void IncrementZoom(float amount)

    Avatar

    DennisBenson

    April 20th, 2010 at 3:46

    Hey David
    Thanks for this tutorial!
    I have some comments:

    1) public class Camera2d : Object2d
    I assume that you extend it because it is essentially a 2d object.. are there any special properties to Object2d?

    2) I assume the rest of the scripts go into the same class (except for the last one).
    What’s up with this line? set { _zoom = value; if (_zoom < 0.1f) _zoom = 0.1f; }
    I’m trying to understand this, but judging from the comment, I guess ‘%lt;’ somehow translates into <

    3) Rotation does not exist in current context.. of course, use get and set.
    Would you need to do _rotation%=360? Or will it appropriate that automatically?

    4) ViewportWidth ViewportHeight: I'm still kinda new to XNA. It doesn't exist in the current context.
    Am I supposed to initialize a Viewport in Game1.cs?

    Avatar

    David Amador

    April 20th, 2010 at 9:15

    Hi there Dennis.
    1) Yes it’s basically an Object2D, no need to extend it though. It was a mistake of mine copying it from my engine where Object2D is the class that has the Vector2 Position, Rotation and Scale since, but I moved them to Camera2D in this example. Just remove that inheritance.

    2) That line is to prevent zooms smaller than 0.1f (you can change to another value. The symbol is

     <

    but wordpress bust have replaced it with weird stuff. It’s fixed now.

    3) I’ve added the Get Set for Rotation property. Should work properly. Oh and on a side note, rotations in XNA are measured in Radians, not degrees, so if you want a 180º you should do Rotation = Math.PI, use the function MathHelper.ToRadians() to convert. Something like
    Rotation = MathHelp.ToRadians(90); MathHelper is part of XNA Framework

    4)In my example I’m abstracting from here you can get Viewport properties, but you can get it by accessing GraphicsDevice.Viewport.Width and GraphicsDevice.Viewport.Height inside your Game1 class.

    Avatar

    Someone

    April 25th, 2010 at 20:07

    Thanks a lot.
    I was looking for something like this for a whole day.

    Avatar

    Mike

    April 28th, 2010 at 23:45

    Great tutorial, it was very helpful!

    I have one question if anyone could answer it, I’m trying to figure out a way to translate the sprites world co-ordinates into co-ordinates related to my viewport. My goal is to have the camera start to zoom out as the player approachs the edge of the screen.

    Any suggestions? thanks !

    Avatar

    David Amador

    April 29th, 2010 at 0:39

    if you need to know the sprite position relative to the camera just subtract the camera position to the sprite position. Something like

    Vector2 relativepos = sprite.pos - Camera.pos;

    Avatar

    Mike

    April 29th, 2010 at 3:07

    Wow, I was way over complicating things ! Thanks !

    The code that I ended up needed was

    (playerPosition – cameraPosition) * cameraZoom

    Avatar

    Nab

    May 7th, 2010 at 8:18

    when I rotate the camera then change the position of the camera (e.g. Position.X) then the camera will NOT go to the right only. instead it will go the World’s right (e.g. when rotating clock wise that will be Bottom right).

    how can I make it go to the camera’s right while still keeping the rotation around the camera’s center ?
    ( I noticed that if i multiply the rotation Matrix first it will move to the camera’s right, but that will make the rotation around the Origin of the world, instead the center of the camera.)

    and Thank you for the great article.

    Avatar

    DMitsuki

    May 16th, 2010 at 7:05

    Let’s say you have 50 to the right of whatever you are doing. So that would mean to move to the right 50 you would have to do x += 50. This works, but if you rotate everything it will no longer go 50 to the right, instead it will go 50 to the old right, or original right. To fix this you have to apply the rotation to the x as well. If you have 50, imagine that the new hypotenuse of a triangle. Now, the center of the screen is the pivot point, and you need to apply the math according to the x position. Let’s say you rotated the screen 25 degree’s. That means that in your right triangle of rotation you have the angle 25 degree’s, 90, and whatever is left.

    Now, all you have to do is simply soh cah toa, in this case you have to do soh and cah, so y -= sin(25)/50, and x += cos(25)/50, or something around that.

    Avatar

    Eric

    July 6th, 2010 at 22:06

    Excellent tutorial :) Worked first time :)

    Comment Form

    top

    Bad Behavior has blocked 45 access attempts in the last 7 days.