In the first part of this series, we created a chest with an area that detects when a body enters or leaves it. The chest’s only reaction was to open and close.
In this lesson and the next, we will use the same technique to create a turret that shoots rockets!
The turret will shoot every second, using a
. It will also rotate to aim at the last mob that enters its range.Note: a “mob” is a common shorthand for “mobile.” We use it to designate enemies or critters that move. In this project, the mobs are cars.
We need four scenes to make this work:
You will only create the turret. We prepared the rocket and the mob for you.
We will take look at them, though, to understand what they do and how they work.
Then, we’ll start creating the turret.
Let’s start by studying the structure and code of the scenes we provide you.
Open the file TowerDefense/common/Rocket.tscn
.
The rocket has a structure similar to the chest you created before. It should start to be familiar now, with its
, , and .The rocket also has a
to make it explode if it flies for too long without hitting a target. This prevents the rocket from flying forever.Finally, the rocket has a
that leaves a smoke trail on its path.Notice how we aligned the rocket’s reactor with the scene’s origin point (where the green and red axes cross). This allows us to rotate the rocket around this point.
Let’s have a look at the script.
We check for bodies entering the rocket’s area. We also check for the
running out.extends Area2D
onready var timer := $Timer
func _ready() -> void:
connect("body_entered", self, "_on_body_entered")
connect("timeout", self, "explode") timer.
Let’s look at the _on_body_entered()
function:
export var damage := 10.0
func _on_body_entered(body: PhysicsBody2D) -> void:
if body.has_method("take_damage"):
take_damage(damage)
body.explode()
The _on_body_entered()
function calls the
take_damage()
function on a colliding body if the colliding
body has that function. It also calls explode()
, which
destroys the rocket.
We move the rocket by updating its position
in the
_physics_process()
function.
export var speed := 350.0
func _physics_process(delta: float) -> void:
# The transform.x holds the direction in which the rocket is facing. We
# multiply that direction by `speed` to calculate the rocket's velocity.
+= transform.x * speed * delta position
The transform
property is of type
Transform2D
. It bundles position
,
rotation
, and scale
in one place.
In 2D games, we often use the position
,
rotation
, and scale
properties individually.
Under the hood, game engines work with these transform types to boost
performance and productivity.
Transforms rely on a mathematical concept called matrices. They are small grids of numbers.
Finally, the explode()
function deletes the rocket and
instantiates an explosion scene at the point of impact.
func explode() -> void:
# We load the explosion scene and instantiate it.
var explosion := preload("Explosion.tscn").instance()
# Then, we place the explosion where the rocket is.
= global_position
explosion.global_position # We append the explosion to the main scene's children.
get_tree().root.add_child(explosion)
# And delete the rocket itself.
queue_free()
Open the scene TowerDefense/common/DraggableCar.tscn
,
which is our mob.
The DraggableCar is similar to the gems we created in the previous project. It has the following nodes:
GDQuestDebugDraggable
so we can drag it mobs
around.It has no unique script attached to it.
Let’s now create our turret, to have a base to aim and shoot!
The turret will once again use an
, , and a . However, there are a few additions:Also, in this scene, the collision shape will control the turret’s range.
Create a new scene with an
named Turret at its root. Add a , a , and a as children.Then, save the scene in the TowerDefense/
directory.
Find the image cannon.png
and set it as a texture.
Add a
as a child of the and align it with the cannon’s mouth.We use the
node to represent spawning points or to create pivot points.Like position
, rotation
, and scale
. On
top of that, it draws a reticle in the viewport only.
To snap it to the horizontal axis, you can either press the left and right arrow keys to nudge the node or hold down the Shift key as you move it with the mouse.
Turn on the
’s Autostart property in the Inspector. You can also change the Wait Time for the turret to shoot more or less frequently.Finally, select the Shape
property.
The collision shape controls the turret’s targeting range. Mobs that enter the area will become potential targets.
Click and drag the shape’s resize handle and increase its radius to
your liking. We made ours 256
pixels large.
The exact size doesn’t matter too much, though. It’s something you typically adjust when testing your complete game.
Let’s bring the turret and mobs together into a new scene to later test our turret.
Create a new scene and instantiate the turret and a few mobs (DraggableCar). The scene should look something like this:
Like before, save it in the TowerDefense/
directory.
We’re now ready to write the turret’s code. We’ll do that in the next lesson.