Learn Godot 4 by Making a 2D Platformer — Part 19: Pause & Main Menu
Tags: gamedev, beginners, tutorial, programming
Published: 2023-08-07 03:01:00


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

One of the core pieces of any game is a Pause and Main Menu. The Main Menu is the first screen that your player will see when they start the game, and the Pause Menu will pause the game when the player presses a button such as “ESC”. In our game, we want our Main Menu to allow the player to start a new game, load a saved game, or quit the game entirely. In our Pause Menu, we want the player to be able to resume their level, save their current level, reload their current level, and quit to the main menu screen.

## **STEP 1: PAUSE MENU UI**

In our Player scene, let’s add a new CanvasLayer node called “PauseMenu”.

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

Add a ColorRect node to it and call it “Menu”. Change the anchor preset of this menu to be full-rect, and change its color to #834040.

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

Add another ColorRect node to your Menu node, and call it “Container”. Change its color to #964545, its size to (x: 1078, y: 580), and position to (x: 35, y: 25).

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

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

Copy and paste the TileMap, AnimatedKing, and AnimatedPig nodes from your GameOver node into your PauseMenu/Menu node.

![Godot 2D Platform](https://cdn-images-1.medium.com/max/2700/1*n4_1jmST2Y1St_kWWzry3A.png)

Let’s change the AnimatedPig animation to be all the frames from the “res://Assets/Kings and Pigs/Sprites/06-Pig Hide in the Box/Looking Out (26x20).png” spritesheet. Change the FPS to “4”, and leave the looping on.

![Godot 2D Platform](https://cdn-images-1.medium.com/max/2068/1*dBKIkhnG9Urr4WBjgE1pFA.png)

Change the AnimatedKing animation to be all the frames from the “res://Assets/Kings and Pigs/Sprites/01-King Human/Idle (78x58).png” spritesheet. Change the FPS to “11”, and leave the looping on.

![Godot 2D Platform](https://cdn-images-1.medium.com/max/2078/1*9rLKaxNWWLCGPyRZ6fPRRA.png)

Make the TileMap a bit different and move your King and Pig to where you want them to be.

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

Now, to your PauseMenu/Menu/Container node, add four Button nodes and one Label node. Organize and rename them as indicated in the image below.

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

***1.*** ***Label***

Select your Label node and change its text to “Pause Menu”. Its font should be “QuinqueFive”, and the size of the font should be 35. Also change its position to be (x: 299, y: 20).

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

***2.*** ***ButtonResume***

Select your ButtonResume node and change its text to “Resume Level”. Its font should be “QuinqueFive”, and the size of the font should be 25. Change the font color to #d98c8a. Also change its size to (x: 500, y: 80) and its position to (x: 285, y: 100).

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

***3.*** ***ButtonSave***

Select your ButtonSave node and change its text to “Save Level”. Its font should be “QuinqueFive”, and the size of the font should be 25. Change the font color to #d98c8a. Also change its size to (x: 500, y: 80) and its position to (x: 285, y: 200).

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

***4.*** ***ButtonLoad***

Select your ButtonLoad node and change its text to “Load Level”. Its font should be “QuinqueFive”, and the size of the font should be 25. Change the font color to #d98c8a. Also change its size to (x: 500, y: 80) and its position to (x: 285, y: 300).

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

***5.*** ***ButtonQuit***

Select your ButtonQuit node and change its text to “Quit Level”. Its font should be “QuinqueFive”, and the size of the font should be 25. Change the font color to #d98c8a. Also change its size to (x: 500, y: 80) and its position to (x: 285, y: 400).

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

Now, connect all of your four buttons’ *pressed()* signals to your Player script.

![Godot 2D Platform](https://cdn-images-1.medium.com/max/2206/1*M7dQL2G3ktrQqrtsdJUXgQ.png)

Change your PauseMenu node’s visibility to be hidden.

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

Finally, we need to change our PauseMenu node’s Processing Mode to “When Paused”, since we only want it to accept input when the game is paused, and no other nodes need access to it when the game isn’t paused.

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

## **STEP 2: MAIN MENU UI**

Copy your PauseMenu node branch from your Player scene, and create a new scene from the option “Paste From Clipboard”.

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

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

Rename the root node to “MainMenu”, and save your scene as “MainMenu” underneath your Scenes folder.

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

Now, delete one Button node, and rename the remaining three as indicated in the image below.

![Godot 2D Platform](https://cdn-images-1.medium.com/max/3840/1*A7l-3PQR0qyu6V8Ov0Y5Ew.png)

Attach a new script to your MainMenu scene, and save it underneath your Scripts folder.

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

Disconnect and reconnect the *pressed()* signal connections on all three of your buttons so that they are connected to your MainMenu script.

![Godot 2D Platform](https://cdn-images-1.medium.com/max/2226/1*Ivf8NumWUhAgZNGhG4dWjg.png)

Then, change your MainMenu root node’s Processing Mode to “Always”.

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

***1.*** ***Label***

Select your Label node and change its text to “Castle Climber”. Its font should be “QuinqueFive”, and the size of the font should be 35. Also change its position to be (x: 299, y: 20).

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

***2.*** ***ButtonNew***

Select your ButtonNew node and change its text to “New Game”. Its font should be “QuinqueFive”, and the size of the font should be 30. Change the font color to #d98c8a. Also change its size to (x: 500, y: 100) and its position to (x: 285, y: 120).

![Godot 2D Platform](https://cdn-images-1.medium.com/max/3840/1*A7l-3PQR0qyu6V8Ov0Y5Ew.png)

***3.*** ***ButtonLoad***

Select your ButtonLoad node and change its text to “Load Game”. Its font should be “QuinqueFive”, and the size of the font should be 30. Change the font color to #d98c8a. Also change its size to (x: 500, y: 100) and its position to (x: 285, y: 240).

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

***4.*** ***ButtonQuit***

Select your ButtonQuit node and change its text to “Quit”. Its font should be “QuinqueFive”, and the size of the font should be 30. Change the font color to #d98c8a. Also change its size to (x: 500, y: 100) and its position to (x: 285, y: 360).

![Godot 2D Platform](https://cdn-images-1.medium.com/max/3792/1*YI-Pq2h7zoOi3AF5N3KiMg.png)

You can change your AnimatedKing and AnimatedPig animations to be any animation you want. I duplicated my AnimatedPig node to be another pig that stands on our boxed friend. Also, draw the tilemap so that it has a variety from the other screens!

![Godot 2D Platform](https://cdn-images-1.medium.com/max/2074/1*JxtV5jyMJsVXaLjzeigMXg.png)

## **STEP 3: PAUSE MENU FUNCTIONALITY**

To have our pause menu show, we’ll first need to create a new input called *ui_pause* that will open up our menu if we press an input such as “ESC”.

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

In our *input()* function, let’s make our pause menu visible when the player presses our newly created input. We’ll also pause the game to stop our players and spawners from processing.
```python
    ### Player.gd
    
    #older code
    
    #singular input captures
    func _input(event):
        #pause game
        if event.is_action_pressed("ui_pause"):
            #pause scene
            get_tree().paused = true
            #show menu
            $PauseMenu.visible = true
```
Then, in our resume button’s *_on_button_resume_pressed()* function, we’ll unpause our game and hide our menu.
```python
    ### Player.gd
    
    #older code
    
    #resume game
    func _on_button_resume_pressed():
        #unpause scene
        get_tree().paused = false
        #hide menu
        $PauseMenu.visible = false
```
Next, we’ll change our scene back to our MainMenu scene if the player presses our quit button. We’ll do these changes in our *_on_button_quit_pressed()* function.
```python
    ### Player.gd
    
    #older code
    
    #quit to main menu  
    func _on_button_quit_pressed():
        get_tree().change_scene_to_file("res://Scenes/MainMenu.tscn")
```
We’ll add the remaining functionality to our *_load_pressed()* and *_save_pressed()* in the next part when we add a save/load system.

Now if you run your scene, you should be able to pause your game, resume it, as well as quit the MainMenu scene.

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

## **STEP 4: MAIN MENU FUNCTIONALITY**

To quit our game in our *_on_button_quit_pressed()* function, we can simply call the *[quit()](https://docs.godotengine.org/en/stable/tutorials/inputs/handling_quit_requests.html)* method, which will kill and close the application entirely.
```python
    ### MainMenu.gd
    
    #older code
    
    #quit game
    func _on_button_quit_pressed():
        get_tree().quit()
```
Now, in our *_on_button_new_pressed()* function, we will first need to clear our current_scene that our player is in. We need to do this to ensure that our current_scene is properly removed from the application’s memory, and thus we can assign a new *current_scene* which will override the data from the previous *current_scene* value.
```python
    ### MainMenu.gd
    
    #older code
    
    #starts a new game in the Main scene, which is our 1st level
    func _on_button_new_pressed():
        # Get the current scene
        var current_scene = get_tree().current_scene
        # Free the current scene if it exists
        if current_scene:
            current_scene.queue_free()
```
After we’ve removed our current_scene from our memory, we need to create a new instance of our first level — which is our Main.tscn scene.
```python
    ### MainMenu.gd
    
    #older code
    
    #starts a new game in the Main scene, which is our 1st level
    func _on_button_new_pressed():
        # Get the current scene
        var current_scene = get_tree().current_scene
        # Free the current scene if it exists
        if current_scene:
            current_scene.queue_free()
        # Load the new scene
        var new_scene = load("res://Scenes/Main.tscn").instantiate()
```
We then need to add this instanced scene as a child to our new scene, because we want this child to then be the new value of our current_scene variable.
```python
    ### MainMenu.gd
    #older code
    
    #starts a new game in the Main scene, which is our 1st level
    func _on_button_new_pressed():
        # Get the current scene
        var current_scene = get_tree().current_scene
        # Free the current scene if it exists
        if current_scene:
            current_scene.queue_free()
        # Load the new scene
        var new_scene = load("res://Scenes/Main.tscn").instantiate()
        # Add the new scene as a child of the root node
        get_tree().root.add_child(new_scene)
        # Set the new scene as the current scene
        get_tree().set_current_scene(new_scene)
        # Update the global variable with the name of the new scene
        Global.current_scene_name = new_scene.name
```
Finally, we need to unpause the game to ensure that our new game does not start in a paused state.
```python
    ### MainMenu.gd
    #older code
    
    #starts a new game in the Main scene, which is our 1st level
    func _on_button_new_pressed():
        # Get the current scene
        var current_scene = get_tree().current_scene
        # Free the current scene if it exists
        if current_scene:
            current_scene.queue_free()
        # Load the new scene
        var new_scene = load("res://Scenes/Main.tscn").instantiate()
        # Add the new scene as a child of the root node
        get_tree().root.add_child(new_scene)
        # Set the new scene as the current scene
        get_tree().set_current_scene(new_scene)
        # Update the global variable with the name of the new scene
        Global.current_scene_name = new_scene.name
        # Ensures scene isn't paused
        get_tree().paused = false
```
Your code should look like [this](https://github.com/christinec-dev/CastleClimbersParts/tree/main/Part19).

Now if you run your Main scene, you should be able to start a new game as well as quit your game entirely.

![Godot 2D Platform](https://cdn-images-1.medium.com/max/3840/1*iy-7jbf19vB7Fkv0AyiJeA.png)

With our main and pause menu’s bases set up, we can continue on to the next part where we will add the functionality to our player to save and load their game — which will load them into their last saved level.

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 Platform](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 Platform](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.*