Learn Godot 4 by Making a 2D Platformer — Part 9: Cannon Handler
Tags: beginners, tutorial, programming, gamedev
Published: 2023-07-26 03:01:00

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

In the previous parts, we created the cannon (bomb spawner) and bomb. Now it’s time to create our cannon handler, which is an arrogant green pig who will shout random speech bubbles at us and “light” the cannon. This cannon handler has no special purpose in our game other than to give our player someone to dislike (like the donkey from Donkey Kong). Our game could work perfectly without this handler, but what fun would it be if the cannon just fired off by itself?

---

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

* *How to work with RandomNumberGenerator methods.*
* *How to change the Timer wait_time.*

---

Let’s create a new scene with a Node2D node as its root node. Rename this node to “CannonHandler” and save the scene underneath your Scenes folder.

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

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

Now in this scene, we want our CannonHandler to have two AnimatedSprite2D nodes. The first AnimatedSprite2D will serve as the *body* for our pig, and the second AnimatedSprite2D will serve as the *speech bubble* for our pig.

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

Rename them to “Body” and “SpeechBubble”.

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

We’ll also need to add a Timer node to our scene, which will randomize our returned speech bubble animation after the timer times out. We’ll do this by randomizing our timer’s [wait_time](https://docs.godotengine.org/en/stable/classes/class_timer.html#class-timer-property-wait-time), which is the time in seconds that it takes to countdown from x to 0. Simply put, every x seconds our timer will timeout(), and return a new speech bubble!

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

We want this timer to start randomizing our speech bubbles as soon as the game start, so enable the Autostart property in the Inspector panel.

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

Select your Body node and add two new animations to it: “idle” and “matching”.

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

For your *idle* animation, navigate to “res://Assets/Kings and Pigs/Sprites/07-Pig With a Match/Match On (26x18).png” and crop out all three animation frames. Leave the looping value to be enabled and change its FPS value to 3.

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

For your *matching* animation, navigate to “res://Assets/Kings and Pigs/Sprites/07-Pig With a Match/Lighting the Match (26x18).png” and crop out all three animation frames. Turn the looping value off and change its FPS value to 3.

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

In your Inspector panel, also enable your “Flip H” property underneath the Offset option — since we want our pig to also be turned left towards our cannon.

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

Select your SpeechBubble node and add three new animations to it: “boom”, “loser”, and “swearing”.

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

For your *boom* animation, navigate to “res://Assets/Kings and Pigs/Sprites/13-Dialogue Boxes/Boom In (24x8).png” and crop out all three animation frames. Turn the looping value off and change its FPS value to 3.

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

For your *loser* animation, navigate to “res://Assets/Kings and Pigs/Sprites/13-Dialogue Boxes/Loser In (24x8).png” and crop out all three animation frames. Turn the looping value off and change its FPS value to 3.

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

For your *swearing* animation, navigate to “res://Assets/Kings and Pigs/Sprites/13-Dialogue Boxes/WTF In (24x8).png” and crop out all three animation frames. Turn the looping value off and change its FPS value to 3.

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

Now, attach a new script to your CannonHandler scene root and save it underneath your Scripts folder.

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

Also, connect your Timer node’s *timeout()* signal to your script.

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

Since our cannon will fire off a bomb as soon as the game starts, we need our cannon handler’s first animation to be our *matching* animation — since the pig will light the cannon as soon as the game starts to spawn a bomb. We will set this animation in our *ready()* function.
```python
    ### CannonHandler.gd
    
    extends Node2D
    
    #when it's loaded into the scene
    func _ready():
        #play cannon lighting animation on start
        $Body.play("matching")
```
Next, we want our *idle* animation to play if our bomb is moving — and we also want our pig to shout random things at us. We can accomplish this by running a conditional to see if our Global *is_bomb_moving* variable is set to true, and if it returns as true, we will make our SpeechBubble node visible (to show our speech bubbles). We will run this conditional in our built-in *[processing() ](https://docs.godotengine.org/en/stable/tutorials/scripting/idle_and_physics_processing.html)*function, which will check the state of our bomb’s movement at each frame. This will allow us to run code that updates a node every frame, and hence update our cannon handlers’ actions as often as possible.
```python
    ### CannonHandler.gd
    
    #older code
    
    func _process(delta):
        #idle animation
        if Global.is_bomb_moving == true:
            $Body.play("idle")  
            #show speech bubble
            $SpeechBubble.visible = true
```
We want our *matching* animation to play if our bomb is not moving since this means our bomb is being spawned. We want our pig to stop shouting random things at us and instead match the cannon. We can accomplish this by running a conditional to see if our Global *is_bomb_moving* variable is set to false, and if true, we will make our SpeechBubble node invisible.
```python
    ### CannonHandler.gd
    
    #older code
    
    func _process(delta):
        #idle animation
        if Global.is_bomb_moving == true:
            $Body.play("idle")  
            #show speech bubble
            $SpeechBubble.visible = true    
        #matching animation
        if Global.is_bomb_moving == false:
            $Body.play("matching")
            #hide speech bubble
            $SpeechBubble.visible = false
```
We need to play the animations that we set up for our SpeechBubble node when it is made visible. We will do this by randomizing our speech value via the [randi()](https://docs.godotengine.org/en/stable/classes/class_randomnumbergenerator.html#class-randomnumbergenerator-method-randi) method, which will generate a random integer. This random integer will then be divided by the number of animations that we have for our SpeechBubble node (which in our case, is 3). This means that the result can only be 0, 1, or 2 — and we can use these values to randomly play an animation based on this returned value.
```python
    ### CannonHandler.gd
    
    #older code
    
    func _on_timer_timeout():
            #randomizes speech
            var random_speech = randi() % 3 #will return 0, 2, or 2
            match random_speech:
                0:
                    $SpeechBubble.play("boom")
                1:
                    $SpeechBubble.play("loser")
                2:
                    $SpeechBubble.play("swearing")
```
Finally, we will need to randomize the wait_time for our Timer’s *timeout()*. This will ensure that our speech bubble regenerates after random amounts of time, and not every x-set seconds. We will do this via the [randi_range()](https://docs.godotengine.org/en/stable/classes/class_randomnumbergenerator.html#class-randomnumbergenerator-method-randi) method, which will allow us to generate a pseudo-random 32-bit signed integer between from and to (inclusive). We will randomize our speech bubble after any second from 1 to 10.
```python
    ### CannonHandler.gd
    
    #older code
    
    func _process(delta):
        #randomizes speech bubble randomize time
        $Timer.wait_time = randi_range(1, 10)
    
        #idle animation
        if Global.is_bomb_moving == true:
            $Body.play("idle")  
            #show speech bubble
            $SpeechBubble.visible = true
        
        #matching animation
        if Global.is_bomb_moving == false:
            $Body.play("matching")
            #hide speech bubble
            $SpeechBubble.visible = false
```
Your code should look like [this](https://github.com/christinec-dev/CastleClimbersParts/tree/main/Part9/Scripts).

Now, let’s fix our Body node to be a little bit bigger. Change its Scale property underneath its Transform option to a value such as “1.5”. You can change this value to make your pig as big or small as you want it to be.

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

Then change your SpeechBubble node to also be a little bit bigger. Change its Scale property underneath its Transform option to a value such as “2.5”. We also want to move this speech bubble to be above the pig’s head.

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

Save your Scene, and instance it in your BombSpawner scene. We want to move the pig to be in front of our cannon.

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

Now if you run your Main scene, your cannon handler should “match” the cannon to spawn the bomb, as well as change its speech every x randomized seconds.

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

Congratulations on creating your cannon handler! This change in our game might have been purely visual, but it did add some life to our cannon spawner. In the next part, we will have a look at adding a camera to our game.

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.*