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\$
2
  • \$\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
    Commented Feb 14, 2014 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
    Commented Feb 14, 2014 at 1:44

1 Answer 1

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\$
2
  • \$\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
    Commented Feb 14, 2014 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
    Commented Feb 14, 2014 at 10:24

You must log in to answer this question.

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