How to get the camera to follow the player

Hey there,

Been using sdl 2 for a while making some small games and i wanted the camera to maybe follow the the player because as it is when i go past 0 x, 0 y, screenWidth, and screenHeight the player is not visible anymore but can continue to move in those directions. I looked everywhere and the solutions glitched the game window making the player to get stuck.

Start by adjusting your drawing code to allow drawing things at an offset. Instead of drawing an object at position (x; y) on the screen, draw it at (x - camera.x; y - camera.y). Test with different camera coordinates to see that it works properly.

When you have the camera working you could try making it follow the player. The simplest way is to just set the camera position equal to the player position (possibly with some offset to make the player appear in the middle) each frame. To make it more smooth and avoid moving the camera all the time you might want to experiment with camera acceleration and only moving the camera when the player is close enough to the edge of the screen.

Thank you for the reply. Which sdl function do i apply this camera sdl_rect data type to because i tried something similar with sdl_rendercopy and it did not follow the player, nor did it work, it actually glitched my player movement.

Apply the camera offset on the dstrect because that’s what decides the position on the screen.

I’m guessing you’re doing something like this right now:

SDL_Rect dstrect = {x, y, w, h};
SDL_RenderCopy(renderer, texture, NULL, &dstrect);

What I mean is that your code should look more like this:

SDL_Rect dstrect = {x - camera.x, y - camera.y, w, h};
SDL_RenderCopy(renderer, texture, NULL, &dstrect);

I wasn’t able to get the window to scroll when the player moved after subtracting camera x,y components even after setting it up correctly (according to what i found online) so i used speed.x and speed.y subtracted from all objects as i moved in their direction and it created something similar enough. thanks for the replies.

Sure, instead of moving the player you could move everything else but I think that will just complicate things. I recommend you keep the “logical coordinates” and “screen coordinates” separate. Do all your game logic with your logical coordinates and only translate to screen coordinates in your drawing code.

Subtracting the camera position when drawing is only meant to make things show up at the correct position on the screen (assuming the camera coordinates represent the top-left corner of the screen). Note that you need to do this for all calls to SDL_RenderCopy (and also for all other render functions like SDL_RenderFillRect and SDL_RenderGeometry if you use any).

You need to actually move the camera too if you want it to follow the player. Something like:

camera.x = player.x - (screen.w - player.w) / 2;
camera.y = player.y - (screen.h - player.h) / 2;

(assuming you want the player in the middle of the screen, and that all coordinates represent top-left corner, and that player.w and player.h are the same as the texture size).

You don’t need to do it exactly like I have showed above. There are many slightly different ways that accomplish the same thing. For example, you might want your logical coordinates to represent the centre (or the middle-bottom) of the game objects and the camera coordinates to represent the middle of the screen (there might be certain advantages of doing so) but it also means that the code that translates the logical coordinates to screen coordinates would also have to be different. The important thing is that you understand so that you can adjust it make it work the way you want it for your game.

My short answer is, don’t think of SDL as an engine. You DO NOT draw a world and tell it where to look. Instead you figure out what you’re looking at and figure out and draw it on screen with top left being 0, 0. Peter87 is essentially saying the same thing

If you think of the original super mario bros, you figure out whats on screen to the left of mario then draw a screen worth of world. Maybe it’d be easier to understand if you render a 2048x2048 image as a texture then use the keyboard to scroll through that