The XNA2dCamera class provides a clean, simple interface to camera functionality in 2-D games.
To use it, call ViewTransformationMatrix() and pass the resulting matrix to a SpriteBatch.Begin() call.
The full contents of the XNA2dCamera class are on the last page.
Fields and Properties
public Vector2 Position
{
get { return position; }
set
{
position = value;
visibleArea.Left = position.X + offset.X - visibleArea.Width / 2;
visibleArea.Top = position.Y + offset.Y - visibleArea.Height / 2;
}
}
protected Vector2 offset = Vector2.Zero;
public Vector2 Offset
{
get { return offset; }
set
{
offset = value;
visibleArea.Left = position.X + offset.X - visibleArea.Width / 2;
visibleArea.Top = position.Y + offset.Y - visibleArea.Height / 2;
}
}
public Vector2 ScreenPosition
{
get { return new Vector2(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2); }
}
The Position property accesses the camera’s game-world position in Vector2 format. The Position property isn’t dependent on the game engine (unless you’re using polar coordinates), so it can be used with isometric/2.5-D games.
The Offset property accesses the offset between the camera’s actual in-world position and the position used for drawing. The Offset property also provides a way to change the viewing position without mucking around with the camera’s actual position.
Example:
{
// from the MovesInACircleXNA2dCamera class
// camera will move in a circle of size Radius around its Position
Offset = new Vector2(cos angle, sin angle) * Radius;
}
The ScreenPosition property returns a Vector2 representing the camera’s position in screen/viewport coordinates. In the base XNA2dCamera class, the camera is always located at center of the current screen/viewport.
NOTE: “Screen coordinates”, as used above, actually refers to viewport coordinates. Viewports represent drawable areas of the screen. By default, the viewport is the same size as the screen, but you can change the size and top-left position of the viewport. If the viewport is not located at (0,0), all coordinates passed to XNA drawing functions are first offset by the viewport’s top-left position. Drawing is restricted to the viewport’s area; anything outside of the viewport’s area is clipped. I’ll post a class encapsulating viewports in August.
protected RectangleF visibleArea;
public RectangleF VisibleArea
{
get { return visibleArea; }
}
The VisibleArea property returns the camera’s visible area in world coordinates, centered at the camera’s current position. VisibleArea is used to cull objects from a scene graph before data is passed to the GPU for rendering. By default, the VisibleArea is set to the size of the current viewport.
NOTE: RectangleF is simply a float-based Rectangle. Position-wise, floats are more precise than integers. Plus, most XNA math objects, like the Vector2 or Matrix, are float-based, so using the RectangleF class eliminates the need for numerous unnecessary casts.
View Transformation
{
Vector3 matrixRotOrigin = new Vector3(Position + Offset, 0);
Vector3 matrixScreenPos = new Vector3(ScreenPosition, 0.0f);
// Translate back to the origin based on the camera’s offset position, since we’re rotating around the camera
// Then, we scale and rotate around the origin
// Finally, we translate to SCREEN coordinates, so translation is based on the ScreenCenter
return Matrix.CreateTranslation(-matrixRotOrigin) *
Matrix.CreateScale(ActiveCamera.Zoom.X, ActiveCamera.Zoom.Y, 1.0f) *
Matrix.CreateRotationZ(ActiveCamera.Rotation) *
Matrix.CreateTranslation(matrixScreenPos);
}
The ViewTransformationMatrix represents the heart of the XNA2dCamera class. It returns a transformation matrix based on the camera’s offset-position, rotation, and zoom. The transformation matrix is passed to a SpriteBatch’s Begin() method, and is forwarded on to all SpriteBatch Draw() calls made until the SpriteBatch’s End() method is called.
First, we create two Vector3s representing the camera’s offset-position and it’s screen position. Then we create a translation matrix (matrixRotOrigin) to translate coordinates to an origin based on the camera’s offset-position because scaling and rotation transformation is origin-based. We multiply this matrix by scale and rotation matrices.
Note: while the order of transformation matrices is usually important, for scaling and rotation, it doesn’t really matter what order you use: you’ll get the same result either way.
Finally, we multiply our current transformation matrix by a translation matrix that translates positions by the camera’s screen position. A translation matrix must be concatenated in the last step of producing a transformation matrix. Concatenating a translation matrix to a transformation matrix before a rotation or scale matrix is concatenated will radically change the results of applying the rotation or scale matrix.
Pages: 1 2




August 12th, 2008 at 2:57 am
Thank you very much. This is exactly what I was looking for.
September 14th, 2008 at 9:19 pm
Thanks for posting this. I’ve been wondering how to create a 2D camera and this has taught me everything I needed!