Learn Godot 4 by Making a 2D Platformer — Part 10: Game Camera
Tags: gamedev, beginners, programming, tutorial
Published: 2023-07-27 03:01:00

**You can find the links to the previous parts at the bottom of this tutorial.*

So far, just like Donkey Kong, our game uses the default camera that captures the entire game map. This means we can see everything at once. Every 2D platformer has a different type of camera. Some follow the player, and others scroll across the screen.

The type of camera that you end up choosing for your game depends on the experience that you are trying to build for your player base. Cameras that move quickly and capture small areas work well in games or levels where you are trying to build intensity, whereas slower cameras that capture larger areas build a more relaxed gameplay experience. The size, focal point, and speed of the camera depend on your end goal.

Since we are building our game off of inspiration from Donkey Kong, we don’t need to change our camera, but because we also want to be unique, we will go through three different ways to create cameras in Godot.

---

***WHAT YOU WILL LEARN IN THIS PART:***

* *How to work with a Camera2D node.*
* *How to animate a Camera’s offset values.*
* *How to estimate and define camera limits.*

---

## **FIXED CAMERA**

With a fixed camera, the camera captures either the entire screen or large chunks of the game map. The player can then be seen and moved inside this chunk. The camera will follow the player linearly until the player reaches the end of the screen or the chunk. In our game, our entire game map — or chunk — is being captured.

**One example is Donkey Kong:**

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/5120/1*nLkwmawM6IxfU6UQ3D-jPA.png)

The game is already capturing the entire window of our Main scenes — and therefore we won’t need to add a camera to our scene to serve as our fixed camera.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/3840/1*HuIQsZq8fBB0mjtl2V5rAQ.png)

## **PLAYER FIXED CAMERA**

With a player-fixed camera, the camera is set to follow the player’s centered position. This means that the camera’s relative position depends on the position of the player

**One example is Mega Man:**

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/5120/1*232F0NwNmyQc_m334oRfYg.png)

To add a fixed camera to our player, we need to add a [Camera2D](https://docs.godotengine.org/en/stable/classes/class_camera2d.html) node to our Player scene. This node forces the screen (current layer) to scroll following the Player scene. This makes it easier (and faster) to program scrollable scenes than manually changing the position of [CanvasItem](https://docs.godotengine.org/en/stable/classes/class_canvasitem.html#class-canvasitem)-based nodes.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2548/1*0Ns0ft_XqZgUQKbtJ3oW-Q.png)

If you run your scene now, and your player runs around the map, the camera should be focused on them.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/3840/1*f9tMbAFPgO2yFsDZ0pgBSw.png)

We can move the camera “closer” to the player by changing its Zoom value in the inspector panel.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*RfuuAbMfJWAd9urMtJM0gw.png)

If you run your scene now, your camera should be zoomed in on the player!

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/3840/1*UBPpY_JzIBGQ5j4Txse0zQ.png)

If you ran around your map, you would’ve noticed that the camera captures the grey background that is beyond our game’s border. We don’t want our camera to capture those areas, instead, we want the camera to stop when it reaches the outer limits of our map. To do this, we will need to change our Camera2D node’s [limits](https://docs.godotengine.org/en/stable/classes/class_camera2d.html#class-camera2d-property-limit-bottom). This will limit the left, right, top, and bottom scroll limit in pixels. You can change your limits in your Inspector panel underneath “Limit”.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/5120/1*F0UfHCkM0r6fRlDEg9Dr6A.png)

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*RfuuAbMfJWAd9urMtJM0gw.png)

To get the value of these limits, you can drag off of the left and right ruler in your Main scene to get the coordinate values of the edges of your game’s border.

**Left Limit**

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*r0LoG_4vVDYYoksT3EIipQ.png)

**Right Limit**

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*Qb5BdAJjTC9B33tkYwBUmw.png)

**Top Limit**

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2008/1*YZAfcokXu0TPXOKmckM_Qg.png)

**Bottom Limit**

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2004/1*XoxDIQsOQsPDEukEkJdiGQ.png)

**This is what I ended up with:**

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*trmSoBhzLsD_9ixK8pKOAA.png)

Now if you run your scene, your camera should follow your player and it should stop when reaching the outer edges of your game borders!

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/3840/1*IyKmGSNti873oLzpGt94Zg.png)

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/3840/1*IlgiBHSyEcr51LqL9D6oQQ.png)

## **OFFSET FIXED CAMERA**

Sometimes we want our camera to only follow the player after exceeding a certain window as opposed to always snapping at the player. This will give the player some space before scrolling the camera back in focus, which allows us to see things that are in front of us. We can do this by changing our camera’s [offset ](https://docs.godotengine.org/en/stable/classes/class_camera2d.html#class-camera2d-property-offset)value. This is the camera’s relative offset which will allow us to look around.

**One example is Mario Bros:**

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/5120/1*GNZt5Kfze8gSgYFzANDwkQ.png)

If you already have a Camera2D node, disable it in the Inspector panel by de-selecting the Enabled property.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*s9cEFMpSiwgu526AMQ7dwA.png)

Add a new Camera2D node. We also want to animate our camera to slowly move left or right depending on our player’s direction, so also add an AnimationPlayer node.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*XP3slAepNXDnfiNult4iWQ.png)

Create two new animations in your Animations panel, call them “move_left” and “move_right”.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*Cw2036Sk-MkqE6VblgX5ng.png)

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*l1nUKDqmALvqdenYq6b9FA.png)

For both, add a new Property Track animation.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*dkk893MrNXfFk2WDRBxRwA.png)

Connect it to your Camera2D (your new camera, not the disabled one).

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*ttgbXDiNI-7w4Esmf2AAJA.png)

Select the offset property, since we want to have our camera in a position that isn’t centered on our player.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2048/1*EKp7rGdYCPOH_tSij3jTWA.png)

Change the length of your animation to how quickly you want your camera to move sides (transition). I’m going with a test value of 0.5. Then insert a keyframe at the start and end of your animations.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2004/1*QQkouS9RR_CelvxGBpJECA.png)

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*H8pcNEGOpZec_6PjtranPA.png)

Now, at the first value of your *move_left* keyframe (0), we need to change our offset values. I want my camera offset to be 100 pixels to the right, and -50 pixels up.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*H8pcNEGOpZec_6PjtranPA.png)

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*uThi_bCzB7RJXkmq4IcGVw.png)

Then at the second value of your *move_left* keyframe (0.5), we need to change our offset values to the starting values of our *move_right* animation. I want my camera offset to be -100 pixels to the left, and -50 pixels up.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*-6zTaz18bhpkKwdhHdQp2A.png)

At the first value of your *move_right* keyframe (0), we need to change our offset values. I want my camera offset to be -100 pixels to the right, and -50 pixels up.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2004/1*QQkouS9RR_CelvxGBpJECA.png)

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*WR9qleyWa5kjtrzNZwuzdg.png)

Then at the second value of your *move_right* keyframe (0.5), we need to change our offset values to the starting values of our *move_left* animation. I want my camera offset to be 100 pixels to the left, and -50 pixels up.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*sjkTrfTGNYtnJXkF3RtXhg.png)

I also want our camera to be a bit zoomed in, so change the Zoom value to a larger value such as “2” (this is optional). We’ll have to change the limits of our camera in our code since the limits will depend on the offset of our camera — since the camera’s position will be different in each direction.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*myI65tWt-H9Vdwwf6t2Unw.png)

We also want our camera to transition smoothly, so enable the camera’s “Position Smoothing” property which will smoothly move the camera towards its target position at [position_smoothing_speed](https://docs.godotengine.org/en/stable/classes/class_camera2d.html#class-camera2d-property-position-smoothing-speed). You can change this speed to how quickly you want the camera to transition or follow your player.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/1*7gD8Y3Vxrv3wFI01DC1tDg.png)

We also want our transition snapping to be smoother in our animation. We can do this by changing the interpolation mode in our animations. [Interpolation ](https://docs.godotengine.org/en/stable/tutorials/animation/introduction.html)tells Godot how to calculate the frame values between keyframes.

**These interpolation modes are supported:**

* Nearest: Set the nearest keyframe value.

* Linear: Set the value based on a linear function calculation between the two keyframes

* Cubic: Set the value based on a cubic function calculation between the two keyframes

We want to change our interpolation mode from Linear to Cubic for both *move_left* and *move_right* animations.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2010/1*q1YdcVYhhmCsHpYo67QQOA.png)

In our Player script, we need to create new variables that will capture our player’s current and last directions. We will use these directions to determine whether or not our *move_left* or *move_right* animation should play.
```python
    ### Player.gd
    
    extends CharacterBody2D
    
    #player movement variables
    @export var speed = 100
    @export var gravity = 200
    @export var jump_height = -110
    
    # Keep track of the last direction (1 for right, -1 for left, 0 for none)
    var last_direction = 0
    # Check the direction of the player's movement
    var current_direction = 0
```
If our player’s *current_direction* is 1, they will be facing right, and if it is -1, they will be facing left. Our player will be facing right at the start of the game, so we have to set the *current_direction* to be facing right at the start of the game.
```python
    ### Player.gd
    
    #older code
    
    func _ready():
        current_direction = -1
```
Now we’ll need to update this current_direction value continuously throughout our game loop depending on our player’s x velocity value. In a 2D game, when the x component of velocity is positive, it typically indicates movement to the right, and vice-versa to the left. We’ll update this variable in our *process()* function.
```python
    ### Player.gd
    
    #older code
    
    func _process(delta):
        if velocity.x > 0: # Moving right
            current_direction = 1
        elif velocity.x < 0: # Moving left
            current_direction = -1
```
If our *current_direction* is different from our last direction, we will play our animation based on our direction value (1 or -1). We also need to update our last direction to be the same as our current direction. This eliminates duplicate transitions, so if we are facing right and we are pressing our right input the *move_right* animation won’t play again until we change direction.
```python
    ### Player.gd
    
    #older code
    
    func _process(delta):
        if velocity.x > 0: # Moving right
            current_direction = 1
        elif velocity.x < 0: # Moving left
            current_direction = -1
    
        # If the direction has changed, play the appropriate animation
        if current_direction != last_direction:
            if current_direction == 1:
                # Play the right animation
                $AnimationPlayer.play("move_right")
                
            elif current_direction == -1:
                # Play the left animation
                $AnimationPlayer.play("move_left")
                
            # Update the last_direction variable
            last_direction = current_direction
```
We also need to set our limits depending on our direction. You’ll need to test this out for each limit (top, bottom, left, and right) when you’re facing both left and right.
```python
    ### Player.gd
    
    #older code
    
    func _process(delta):
        if velocity.x > 0: # Moving right
            current_direction = 1
        elif velocity.x < 0: # Moving left
            current_direction = -1
    
    # If the direction has changed, play the appropriate animation
        if current_direction != last_direction:
            if current_direction == 1:
                # Play the right animation
                $AnimationPlayer.play("move_right")
                #limits
                $Camera2D.limit_left = -110
                $Camera2D.limit_bottom = 705
                $Camera2D.limit_top = 40
                $Camera2D.limit_right = 1068
                
            elif current_direction == -1:
                # Play the left animation
                $AnimationPlayer.play("move_left")
                    
                #limits
                $Camera2D.limit_left = 90
                $Camera2D.limit_bottom = 705
                $Camera2D.limit_top = 40
                $Camera2D.limit_right = 1268
                
            # Update the last_direction variable
            last_direction = current_direction
```
Your code should look like [this](https://github.com/christinec-dev/CastleClimbersParts/tree/main/Part10/Scripts).

Now if you run your scene, your camera should follow your player, change direction, and it should stop when reaching the outer edges of your game borders! If your transition is still too sharp, then make your animation length a bit longer to allow for a smoother transition.

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/3840/1*2zY3WpEZJ6QgQO7saASmig.png)

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/3840/1*tWzQiICU6VHIkyVIePZXnQ.png)

Congratulations on creating your game camera (if you opted to go for a camera that isn’t fixed to your main scene)! In the next part, we’ll be setting up our secondary enemies who will throw and spawn boxes at us on our platform levels.

Now would be a good time to save your project and make a backup of your project so that you can revert to this part if any game-breaking errors occur. Go back and revise what you’ve learned before you continue with the series, and once you’re ready, I’ll see you in the next part!

---

## Next Part to the Tutorial Series

The tutorial series has 24 chapters. I’ll be posting all of the chapters in sectional daily parts over the next couple of weeks. You can find the updated list of the tutorial links for all 24 parts of this series on my [GitBook](https://oops-i-devd.gitbook.io/christinedevs/godot-tutorials/castle-climbers/tutorial). If you don’t see a link added to a part yet, then that means that it hasn’t been posted yet. Also, if there are any future [updates ](https://oops-i-devd.gitbook.io/christinedevs/communication/updates-and-notifications)to the series, my GitBook would be the place where you can keep up-to-date with everything!

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/0*TLFhoNqnjMYLWAGA.png)

---

## Support the Series & Gain Early Access!

If you like this series and would like to support me, you could [donate](https://ko-fi.com/christinedevs) any amount to my KoFi shop or you could [purchase the offline PDF](https://ko-fi.com/s/75433f1d4b) that has the entire series in one on-the-go booklet!

The booklet gives you lifelong access to the full, offline version of the “**Learn Godot 4 by Making a 2D Platformer**” PDF booklet. This is a 451-page document that contains all the tutorials of this series in a sequenced format, plus you get dedicated help from me if you ever get stuck or need advice. This means you don’t have to wait for me to release the next part of the tutorial series on Dev.to or Medium. You can just move on and continue the tutorial at your own pace — anytime and anywhere!

![Godot 2D Platformer](https://cdn-images-1.medium.com/max/2000/0*S6n1i41QDrVlLJUy.png)

*This book will be updated continuously to fix newly discovered bugs, or to fix compatibility issues with newer versions of Godot 4.*