Making the camera follow the character


Code for this tutorial is on this git branch:

git clone -b sticky_camera https://dglencross@bitbucket.org/dglencross/zombiegametutorial.git

Have a look here for help setting it up


Keeping the camera centred on the player – intelligently

This tutorial can be used independently to the ongoing series, as this is probably a useful bit of code for a lot of top-down 2D games.

In previous tutorials, the camera has been following the player around the screen, always keeping the camera centred over the player. However, when the player moves towards the edge of the game world, the edge of the map and beyond is visible. This looks pretty awful.

What we want is for the camera to follow the player around, but never get to the edge of the map. So when they player gets within a certain distance of the edge of the map, the camera stops following.

Code

float x = getPlayer().getX();
float y = getPlayer().getY();
// We divide the viewPort sizes by 2, because the player
// is always in the middle of the screen - with half of the
// screen above it, half below, half to the left side of it,
// half to the right

// You can extract these out (as they are in the full project)
// These are always the same, so only need to be calculated once
float halfViewPortWidth = camera.viewportWidth / 2;
float halfViewPortHeight = camera.viewportHeight / 2;

if (x < halfViewPortWidth) {
    camera.position.x = halfViewPortWidth;
} else if (x > ZombieGame.getWorldWidth() - halfViewPortWidth) {
    camera.position.x = ZombieGame.getWorldWidth() - halfViewPortWidth;
} else {
    camera.position.x = x;
}

if (y < halfViewPortHeight) {
    camera.position.y = halfViewPortHeight;
} else if (y > ZombieGame.getWorldHeight() - halfViewPortHeight) {
    camera.position.y = ZombieGame.getWorldHeight() - halfViewPortHeight;
} else {
    camera.position.y = y;
}

When the player is in the middle of the map, the camera will track normally. However, if the player steps outside the artificial boundaries then the camera will stay in a position in which it can never see off the map.

In the above code, we check if the player is too far to the left of the map, or too far to the right. If so, we limit where the camera can be on the X-axis. Otherwise, we just set the camera’s X parameter to match that of the player.

Similarly, we check if the player is too far towards the top or bottom of the map, and do the same.

In this way, the camera can track along one axis but not the other, or both at the same time – which will happen when the player is in a corner.



If you like these tutorials, or want to see a game that was written in much the same way, please download Dinowar from the Google Play Store. It costs nothing and is ad-free.

One thought on “Making the camera follow the character”

  1. This is another way of achieving the same thing, without using a lot of conditional statements:

    gameCam.position.x = MathUtils.clamp(gameCam.position.x, camViewportHalfX, mapWidthMinusCamViewportHalfX);

    gameCam.position.y = MathUtils.clamp(gameCam.position.y, camViewportHalfY, mapHeightMinusCamViewportHalfY);

    MathUtils.clamp is a convenience method that comes with libGDX.
    Precalculating mapWidthMinusCamViewportHalfX and mapWidthMinusCamViewportHalfY also saves some floating point calculation time as well.

    What I am curious to find out is how to limit the camera if the player is in certain areas. For example, don’t pan the camera around if the player is inside a boss room, or prevent the camera from showing secrets, such as upgrades, until the player discovers the secret entrance.

Leave a Reply

Your email address will not be published. Required fields are marked *