Saturday, November 24, 2018

How to smoothly move camera when the player is climbing a diagonal staircase in 2D tile-based side-scroller?


I am working on a game, which is tile-based, similar to the way Terraria works. My player is 2 x 3 and can move over one-high obstacles, but this creates a very jittery effect, since my camera currently strictly follows the player. I was thinking of either somehow implementing a smoother camera movement or overhauling the player movement itself. I would love some feedback on how one might go about fixing this.



Answer




In the scenario you describe, there are two points that could improve the smoothness of your camera: (1) the position of the camera with respect to the player, and (2) the movement of the camera towards its target position.



You mention your camera is locked to the player. I assume you instantly snap your camera's center of focus to the player position. It is possible to handle this differently by having a small frame around the player, where the camera does not follow the player. As soon as the player moves beyond the frame, the camera is "pushed" back towards the player.


In your case, you mention the jitter being caused by "jumps" in the vertical player position when he climbs a one-tile ledge. You can apply the framing strategy above to the X- and Y-movement of the camera independently. If you do want to keep the player centered on screen horizontally, but want to avoid jitter due to sudden vertical movement, you can apply the strategy to the Y-axis only.


Your current camera strategy might look like this in pseudo-code:


// Update the player position
...

// Update the camera position
camera.x = player.x;

camera.y = player.y;

To apply framing, you could modify your code like this:


// Update the player position
...

// Update the camera position
const float camera_frame_size_hor = 48.f;
const float camera_frame_size_ver = 32.f;
camera.x = min(max(camera.x, player.x - camera_frame_size_hor), player.x + camera_frame_size_hor);

camera.y = min(max(camera.y, player.y - camera_frame_size_ver), player.y + camera_frame_size_ver);

In the above cas,e the camera will only follow the player when he moves more than 48 pixels away from the camera center horizontally, or more than 32 pixels away from the camera center vertically.



You also mention you instantly snap the camera to the player position. Many games apply a form of smoothing to the camera movement. To apply smoothing, you calculate the target camera position as before. However instead of simple setting the camera's actual position to this target position, you gradually move its position towards the target.


Currently, you might simply set your camera position directly as follows:


// Update the player position
...

// Update the camera position

camera.x = player.x;
camera.y = player.y;

You could instead apply a simple low-pass filter as follows:


// Update the player position
...

// Update the camera position
const int camera_smoothing = 10;
float camera_target_x = player.x;

float camera_target_y = player.y;
camera.x = ((camera.x) * (camera_smoothing - 1) + camera_target_x) / camera_smoothing;
camera.y = ((camera.y) * (camera_smoothing - 1) + camera_target_y) / camera_smoothing;


The two techniques above can be applied independently to smooth your camera movement in a more sophisticated way. Your camera code might look like this:


// Update the player position
...

// Update the camera position

const int camera_smoothing = 10;
const float camera_frame_size_hor = 48.f;
const float camera_frame_size_ver = 32.f;

float camera_target_x = min(max(camera.x, player.x - camera_frame_size_hor), player.x + camera_frame_size_hor);
float camera_target_y = min(max(camera.y, player.y - camera_frame_size_ver), player.y + camera_frame_size_ver);
camera.x = ((camera.x) * (camera_smoothing - 1) + camera_target_x) / camera_smoothing;
camera.y = ((camera.y) * (camera_smoothing - 1) + camera_target_y) / camera_smoothing;



I would like to recommend the following excellent article which analyses various camera strategies across many games. The articles has animated graphics to illustrate all strategies. Itay Keren - Scroll Back: The Theory and Practice of Cameras in Side-Scrollers


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...