Getting the camera right in a classic 2D Platformer is not as easy as it might seem at first. The most simple approach would be to hardwire the camera to the player, so the player is always centered in the screen. This might be ok for prototypes but it has some flaws that can really frustrate the player.
For example if the camera scrolls up with each jump of the player it easily will cause nausea. It's also not very smooth when the player starts running or stops immediately. In our upcoming game Tiny Thor we have experimented with various options and I want to describe which techniques we ended up using.
First of all we handle the X- and Y-Axis separately of each other.
For the X Axis we define a left and right border (Focus Area on the Screenshot).
When the player moves, the camera will calculate the distance between the old camera position and the new player position. Then we know how many pixels we have to scroll. To smooth out this movement, we divide this distance by 32 so that the camera lags behind. We also have a max camera speed that will never be exceeded.
Various camera zones explained
To avoid triggering camera movement on every small motion we only apply this scrolling behaviour if the player walks out of the left or right border of the Focus Zone. The camera will then catch up immediately.
Because of the aforementioned camera lag, we end up with less visible area in the direction the player is heading. This reduces the relevant information on screen that the player requires to react to enemies, obstacles, platforms, etc. To address this problem we move the horizontal Focus Zone based on the player sprite's orientation.
The camera now 'looks' into the same direction as the player.
We move the Focus Zone even more off-center based on the player's x-velocity. This added view distance further helps with reacting to the levels upcoming challenges.
When the player moves to the right, the focus zone moves to the left, which keeps the player on the left side of the screen center. This results in smooth camera movements that adapt to the players next intention, preventing frustration and offering more freedom in level design.
The scrolling on the y-axis follows a similar logic and provides the top and bottom borders for our Focus Zone.
Instead of dividing the difference between player and camera by 32, we use a factor of 16 for the smoothing effect. Furthermore the camera only starts moving when the player is standing on an object, to prevent the camera from following every jump.
Camera starts to scroll on y-axis as soon as player has some ground under his feets. For regular scenarios these rules seems sufficient, but if the player is jumping around the top part of the screen or is falling down a shaft, this camera behaviour would break. To address this we add two further horizontal lines that check the vertical position of the player. We call these panic lines (dark yellow in the images), as crossing these warrants a quick movement of the camera.
Camera doesn’t scroll on y-axis when player jumps.
X and y behaviour in action
So whenever the player is jumping or falling and crosses one of these lines, the camera will quickly follow. All of this worked nicely for most situations in our levels, but for some scenarios in the levels we want a manual override of this behaviour.
This is done with simple rectangles in the level editor that allows locking the camera on one of the axes for as long as the player is within the defined area. This is really useful if you want a player to see if a drop down a ledge is safe.
It can also be used in hectic sections that are mostly oriented in one direction like falling down a long shaft full of gems. We also make use of this logic for locking the player's camera in a bossfight where the player is caged anyways and where the steady camera helps dodging all the attacks and projectiles.
Another use case is to completely change the camera's focus on another part of the level. The logic here is to let the camera pan along a wire between the players position and the specified area, rest there for a second and then pan back again. We use this to show the consequence of a flipped switch for example. All this results in a dynamic camera behaviour that works 95% of the time, while giving you the tools to manually design the camera’s behaviour in those remaining situations for gameplay reason or dramatic effect.