I want to know how Camera works in game of Celeste. enter image description here

Currently what I have is, camera follows the player using interpolation:

cameraPosition = cameraPosition + (playerPosition - cameraPosition) * 0.1;

and I clamp the camera position to the edge of the world size:

cameraPosition = mu.clamp(cameraPosition - [160, 90], 0, worldSize);

I subtract [160, 90] to center the camera.

This works OK. But is that all there is to it.

Specifically, how does the camera work between room transitions.

I might drop room transitions, and just do a black screen transition between levels, but I've heard there is camera triggers that offset the camera relative to player position, and what other tricks are used?


1 Answer 1


Start with a simple refactor: the camera does not follow the player. The camera follows a target. Make the target the player. The game should behave exactly as it does right now.

You will want to use interpolation, which you already do.

Instead of doing player.Position - camera.Position you do target.Position - camera.Position. And target happens to be equal to player.

Next refactor: Take target.Position - camera.Position into a separate variable. We want to know when the camera is close enough, and when it is far from the target. That will be useful later. Taking that into separate variable should leave the game with exactly the same behavior.

Next, we want to define rooms. You will probably want some structure to hold your rooms (unless they are all the same size). How do you define the rooms is of little importance, as long as we can keep track of the room in which a position is. Naive approach will be a list of rects, more involved solutions usually use tree structures (see Space Partioning).

So, we will not only have the target.Position, but also a targetRoom. Why is this important? Because we will clamp the camera to the targetRoom. And the game should behave exactly the same way as it does now.

Now, for the grand reveal: When the target.Position is close enough to the edge of the targetRoom, you want to set a global flag that indicates we are in a transition (we will not clamp while that flag is set. User input will be disabled. Also halt enemies or any other thing you deem pertinent). Next, change the target to a temp object on the next room, and change the targetRoom to that other room. Remember we have interpolation? Ta-da! the camera interpolates to the position on the next room.

Once the variable we extracted (target.Position - camera.Position) is small enough (for some definition of small), you can set the target to player again. targetRoom was already updated, and clamping will be done for the new room.

Offset the camera relative to player position? Sure. For example, if the player holds down for two seconds we can give the camera a target below the player. Now the camera interpolates to that target, and the result is that the player can see further down. When the player releases down, we set the target to the player again.

Furthermore, if you want to do a flyby of a room, or you want to take control of the camera for a cut-scene… Well, you can move the target of the camera following a predefined path. The movement does not have to be relative to the player.

You probably want a slightly different strategy hide loading scenarios. A battle tested solution is to have a small corridor (Variants of this include elevators, tunnels, bridges), so you can dynamically load the next scenario and unload the prior one while in the corridor. It is also good for pacing, creating anticipation for the next level, and a small moment of respite after a challenging scenario. Having camera transitions from room to room, and not only from and out the loading corridor, will further hide when loading will happen.

And who says that the corridor has to be empty or that nothing happens there? Some games use it as an opportunity for character moments or exposition. Or you can put some health pickups, so healing when starting a new scenario is a little more diegetic. Stuff like that.


You must log in to answer this question.

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