2
\$\begingroup\$

I have tried implementing a basic 2D sidescroller camera in XNA, but I don't want it to be able to scroll past the edges of my tile map!

I tried to fix it, but when I get the left side working, the right stops working...

How do I do this right?

EDIT: After Anko

public Matrix transform;    
Viewport view; 
Vector2 center; 

public void Update(GameTime gameTime, Player player) {
    center = new Vector2(player.Position.X + (player.Bounds.Width / 2) - (960 / 2), 0);

    float cameraX = center.X;
    float cameraWidth = view.Width;

    float worldWidth = 1760;

    if (cameraX < 0) 
        cameraX = 0;
    else if  ( cameraX + cameraWidth > worldWidth)
        cameraX = worldWidth - cameraWidth;

    transform = Matrix.CreateTranslation(new Vector3(-cameraX, 0, 0)); 
\$\endgroup\$
  • \$\begingroup\$ Just checking: Roughly how are you implementing a camera? Are you applying a translation to the view when your game is rendered or are you moving all objects around? \$\endgroup\$ – Anko Feb 14 '14 at 1:23
  • \$\begingroup\$ I tried applying a translation using a view matrix. And hey, you were the one who helped me with the guns! Got that working quite nicely. \$\endgroup\$ – atkayla Feb 14 '14 at 1:44
4
\$\begingroup\$

Let's draw it! (Again ;3)

game world, with camera

Imagine all the grassy and skyey bits are your game world. That lighter coloured rectangle framed in red is the region the camera is looking at. A player would only actually see what's in the camera. We want the camera to always stay in the game world.

(x,y) is the camera position
w and h are the camera's width and height

Let's also say your game world has width world_w and height world_h.

To take care of left, we want to ensure x > 0
To take care of right, we want to ensure x + w < world_w

To take care of the top, we want to ensure y > 0
To take care of bottom, we want to ensure y + h < world_h

So, before you apply a transformation matrix to translate by x, y, check that our assumptions indeed are true, and if not, correct them so they just about are:

if x < 0 then
    x = 0
elseif x + w > world_w
    x = world_w - w

if y < 0 then
    y = 0
elseif y + h > world_h
    y = world_h - h

No more escaping camera!

Note that you might want to build in a special case to detect if your world is smaller than your camera, if such a tiny world might happen in your game.

\$\endgroup\$
  • \$\begingroup\$ It works! There's something I'm confused about though, so maybe you can catch where something is off. I assumed view.Width is getting the camera width, but I'm not sure what it actually does. :P So my worldWidth should actually be 64px tiles * 30 columns = 1920. When I tried this value for worldWidth, it actually went off the right edge. I just kept lowering the value until I found that 1760 worked perfectly. Is there any explanation for this? \$\endgroup\$ – atkayla Feb 14 '14 at 3:53
  • \$\begingroup\$ @Tidus Yey! :D I don't know what view.Width exactly means in your code, so I can't really help with that. (Also, debugging questions are off-topic here.) To debug a C# program, you could call Trace.WriteLine inside those ifs to write the variables' values to the console and see for yourself what they are and if they're making sense. \$\endgroup\$ – Anko Feb 14 '14 at 10:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.