Build a complete game with the Godot game engine

Firing Bolts

So far you have a bunch of aliens invading but no way to fight back. The next step, then, is to enhance the turret's defense system and actually make it shoot something when the player hits fire.

Create another Area2D-based scene and call it Bolt. Give it an AnimatedSprite node and add two animations: a default animation with an image of a bullet (mine is an orangey oblong). Call this animation bolt. The second animation is another "explosion" from Open Game Art.

When you fire the bolt, it will stop in its tracks and shift to the animation of the explosion when it hits an alien in the same way the turret explodes when it hits an alien. Lines 14 to 21 in Listing 15 show what that would look like.

Listing 15

01 extends Area2D
03 var speed = 400
05 func _process(delta):
06   position.y -= speed * delta
08 func start (bolt_position):
09   position = bolt_position
11 func _on_VisibilityNotifier2D_screen_exited():
12   queue_free()
14 func _on_Bolt_area_shape_entered(area_id, area, area_shape, self_shape):
15   area.destroy()
16   speed = 0
17   $CollisionShape2D.set_deferred("disabled", true)
18   $"explosion")
19   yield($AnimatedSprite, "animation_finished")
20   hide()
21   queue_free()

Use Bolt's area_shape_entered() signal (line 14) to determine which alien the bolt collided with, as it delivers the information you need through its area parameter. You can then call a new method, destroy(), in that removes the blasted enemy from the node tree.

The collision layer the turret is on must be different from the one the bolt is on; otherwise the bolt will collide with the turret. Open the turret scene and select the Turret node. Click to unfold the Collision section in the node's properties in the Inspector dock on the right, and take a look at the Layer grid. There are 20 layers that Area2D nodes can be on, and by default new Area2D nodes start on layer 1. For the turret that is fine, but now do the same for Bolt and deactivate layer 1 by clicking on it and activate layer 2. Like that, collisions for bolt only happen with other nodes on layer 2.

Your enemies will also be on layer 1. Select the Enemy scene and the top Enemy node and again open Collision. As you need to be able to collide with Turret on layer 1 and Bolt on layer 2, leave layer 1 as active, but also activate layer 2.

To instantiate a Bolt scene when a player hits fire, create a custom signal in by adding the line signal fire to the top of the script and then emit the signal with the line emit_signal("fire") underneath the line that checks for the input from the "fire" button (Listing 4, line 19). While you are at it, you may want to add a timer to Turret so that there is a short delay (half a second works well) between each shot (Figure 11).

Figure 11: Unless you add a timer that forces a delay between shots, this game will be very easy.

Back to the fire signal, open the Main scene and connect the fire signal from Turret to Main. You must write the body of the _on_Turret_fire() function Godot creates in, making it do the following:

  1. Preload the Bolt scene.
  2. Add it as a child instanced node to Main.
  3. Call the start() method in (Listing 15, line 8).

Listing 16 will do the trick.

Listing 16

_on_Turret_fire() (

01 func _on_Turret_fire():
02   var bolt = preload("res://Bolt.tscn").instance()
03   add_child(bolt)
04   bolt.start(Vector2($Turret.position.x, $Turret.position.y - 20))

When a player hits fire, a bolt node is created and placed on the tip of the turret's cannon and starts moving upwards (Listing 15, lines 5 and 6) at 400 pixels per second. If it flies off the screen without hitting anything, it is removed in Listing 15 lines 11 and 12. If it hits an alien, you call's destroy() function to remove the alien (line 15), stop the bolt (line 16), and remove the bolt's capacity to collide with anything else (line 17). Then you play the explosion's animation and pause the script until it's finished (lines 18 and 19). Finally, you remove the bolt from the game (lines 20 and 21).


Godot has many other options that this article has not covered. We have not mentioned sound design, exporting your game to work natively on different platforms (Godot supports Linux, Windows, macOS, Android, iOS, and HTML5), or 3D game design.

If you need more ideas, try increasing the difficulty of the Spaced Marauders game by having the aliens fire back and moving quicker as you pick them off. You can also create new levels in which the aliens start lower down, move faster, or fire more. Or you could try adding a scoreboard. If you get stuck, know that I will gradually add all these changes and more to the game, and you can find all the code and assets under a GPL license online [2].

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Introduction

    This month in Linux Voice.

  • FOSSPicks

    This month Graham looks at Godot 4, PostRunner, LeanCreator, lurk, Cubic, SuperStarfighter, and more!

  • FOSSPicks

    This month Graham reviews PeaZip, LibreSprite, NeoChat, Beaker, Giada, Thrive, Kurve, and much more!

  • Animation with OpenToonz

    OpenToonz is a professional animation tool for comic and manga artists.

  • Tutorials – Natron

    Natron gives you the power to apply sophisticated effects to your videos, but its node-based interface can be a bit confusing. This tutorial will help you get a grasp on the basics.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More