Gamecamera implementation

After reading the excellent article on Gamasutra: The Theory and Practice of Camera’s in 2D Sidescrollers by Itay Keren, I thought of showing the code I use in my 2D game camera.

The camera I use is of the type ‘Camera window’ with ‘LERP Smoothing’. It meams the camera follows the player, if the player pushes the boundaries of a window inside the camera viewport:

The blue area (1) is the gameworld. This area is bigger than the part shown on the player’s screen. The yellowish area (2) is the actual viewport that is rendered to the player screen. The reddish (3) part is the ‘camera window’: the player controlled character will always be inside that part. Only when the player actually pushes the boundaries of that inside section the view will move. Imagine the character moves to the right edge- the camera gets moved until the player is back inside the reddish area and will nog move again until  the player reaches the edge again.

LERP smoothing means the camera ‘lags’ a bit and moves smoothly instead of immediate.

On to some code…

This code is the base of the camera class.

If you look at the constructor the camera initializes two rectangles:

  • the viewport– the dimension of the camera (the yellowish rectangle in the picture above)
  • the bounds of the gameworld, the camera needs to know the dimensions of the gameworld; so it knows not to scroll outside the actual gameworld. This is the equivalent to the blue area in the picture.

The variables should speak for themselves- note the ‘_trackingBounds’ variable is equivalent to the reddish area in the picture.

The trackingbounds are calculated in a function like this:

Here we calculate the trackingbounds based on the current viewport location and the dimensions are a relative portion of the viewport size (using the const BOUNDSPERCENT).

Another function we need is to keep the camera within the boundaries of the gameworld. This function keeps the camera within the bounds:

It is a simple check, the code should be self explanatory.

Now we have the basic operations done, We’re going to actually track an object:

Let’s have a closer look: the function takes a Vector2 position in the gameworld. We check how the position is outside the tracking boundaries. if the position is outside the boundaries of the tracking window; the top left position of the camera rectangle is calculated that puts the object back inside that window.

The top left location is stored in a Vector2 targetposition variable. So the camera itself is not yet moved- instead we set the position we want the camera to move towards.

So far we have the functions to initialize the camera, calculate the boundaries of the tracking window and set the target position of the camera in relation of an object. Let’s put these things together and move the camera!

Every frame the camera is updated. I use the Vector2.Lerp function to smooth the movement. Every frame it gets a percentage closer to the target. If the distance between the current and target position is big, the camera will move quick until the distance becomes so tiny (subpixel effectively) so the camera has reached the destination. One can play with the magic number in there (the 5f) so make the camera respond quicker or slower. The speed should depend on how fast objects in the game move, so the camera can keep up.

Then the camera viewport rectangle is moved and is checked against the bounds.  Once all movement is done- the tracking window is recalculated.

The main game loop now needs to know what the camera is showing so:

The result is we have everything required to make a smooth moving, windowtracked game camera!

To use it, in the main gameloop:

In one of my games, the gameworld is just slightly bigger than the viewport (a sports game where the camera only has to pan up, if the ball is tossed really high- or when a point is scored) so I draw the entire gameworld to a rendertarget. Then I use the _camera.View rentangle as sourcerectangle in a spritebatch like this:

I hope this gave some inpiration and insight to how a simple game camera can be made!

2 responses on “Gamecamera implementation

  1. mareinsula

    Hi, you saved my day!. At the moment for testing I implemented a basic camera, that moved all the time, with your implementation it only happens when we touch the viewport!.

    I’ve tried to make it more like the Thimbleweed camera where the _targetPosition is centering (when KeepCameraWithinBounds) the actor but I do not get it right. I think it has to go in TrackObject with the half of the game screen (320/2) but cannot make it work. Any clue? thank you for posting the camera!

  2. Felsir Post author

    I’m happy to hear this code helped out!

    One thing you could try, is increase the boundary percentage;
    private const float BOUNDSPERCENT = 0.30f;

    If you increase the value to for example 0.60f, the tracking window becomes smaller so the camera focusses more on the character.

    Another value you can play with is the multiplication factor in the Lerp function. Try a few different values for the 5f in there and see what works best for your game. This controls the speed of the camera movement.

    Good luck!

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *