I'm working on a 2D sprite-based strategy-type game (ok, full disclosure: it's a tower defense game), and I'm having a problem getting the actors to behave correctly when I move the camera.

I've got a Camera class, which contains data and methods for moving the camera and exposing its' current position. When I draw the background, I offset the background thusly (and it works great):

var backPos = new Vector2(background_bounds.X - camera.CameraPositionX, 
                          background_bounds.Y - camera.CameraPositionY);
spriteBatch.Draw(background_texture, backPos, Color.White);

My sprites each have a GraphicsComponent that directs the rendering. I've been playing around with different combinations, but none seems to give the proper (expected behavior); I lose collision detection (done via my CollisionComponent object), or the physics misbehave, etc, because actor's position is different than what the other components expected. Here's the GraphicsComponent.Draw(...Camera camera):

 var adjustedPosition = new Vector2(actor.Position.X - drawOffsetX, 
                                    actor.Position.Y - drawOffsetY);
 //Uncommenting this line doesn't work either - just makes things seem worse
 //actor.Position = adjustedPosition; 
 DrawContext.Draw(actor.Texture, adjustedPosition, 
                  actor.SpriteBounds, DrawColor);

How do you folks approach applying camera offsets to sprites in a way that avoids exposing the camera to every component? Do you offset the actual position by the camera's position, or do you simply render the position with the offset, and compensate elsewhere?

  • \$\begingroup\$ It appears that my problem, as usual was between the chair and the keyboard. The defect was actually in my collision detection - I was culling inactive collisions too aggressively from the collision list. \$\endgroup\$
    – Josh E
    Commented Aug 12, 2010 at 18:45

2 Answers 2


I just offset the drawing position like you've done there. Logically speaking, the actor's positions aren't changing just because the camera is changing. Positions should be relative to the map, the camera shouldn't come into play with the actual positions.

As to your question about exposing the camera to every element, I tend to set things up a little differently. I have a class that is in charge of graphics. This class contains the camera class, or at least a reference to it, as well as a draw method. Sprites are then drawn by this method, which offsets the position automatically, so you don't have to think about the camera at all while rendering. Sure, it necessitates an extra function call per draw, but since this is a linear time algorithm, unless your bottleneck is in drawing tons and tons of sprites, you shouldn't have an issue with this.

  • \$\begingroup\$ the primary problem I'm having (which I think is a symptom of other things too...) is that collision detection no longer works, since I'm checking to see if the actual position is a collision, rather than the rendered position. I don't want to have to have collision code compensate for the camera offset \$\endgroup\$
    – Josh E
    Commented Aug 12, 2010 at 17:16

I know this is an old post, but for future reference, you should not implement a camera like this, i.e.a by offsetting all the objects in the world manually. That makes your life much harder than it has to be. That remains true for both 2D and 3D games.

Implementing a camera should be done using a view matrix instead. You simply calculate a view matrix based on the camera's position and orientation in the world, and pass that matrix as a parameter to SpriteBatch.Begin. XNA automatically applies that transformation to everything it draws, which gives the impression you're "watching the scene" from the camera's point of view.

Here's a writeup I did on the subject with a few extra catches:


  • \$\begingroup\$ yes indeed it is much less painful. I adopted the view matrix approach a while ago and haven't looked back since my first stumbling steps. \$\endgroup\$
    – Josh E
    Commented Feb 7, 2012 at 23:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .