Declaring and Emitting
Part of the Object Oriented Programming section of Coddy's GDScript journey. Lesson 36 of 65.
Declare a signal with the keyword signal and a name, at the top of the class next to its variables. A signal name describes an event that already happened, in snake_case: died, door_opened, leveled_up. A class declares as many signals as it needs:
# player.gd
class_name Player
extends RefCounted
signal leveled_up
signal max_level_reached
const MAX_LEVEL := 3
var level := 1
var xp := 0
func add_xp(amount: int) -> void:
xp += amount
while xp >= 100 and level < MAX_LEVEL:
xp -= 100
level += 1
leveled_up.emit()
if level == MAX_LEVEL:
max_level_reached.emit()Emit a signal at the moment its event happens, and only then. add_xp(50) on a new player emits nothing. add_xp(250) after it brings xp to 300: leveled_up is emitted twice, once per level gained, and max_level_reached once, on the level-up that reaches level 3.
A property setter is a good place to emit, because the signal then fires whatever code changes the value:
signal died
var hp: int = 10:
set(value):
var was_alive := hp > 0
hp = maxi(value, 0)
if was_alive and hp == 0:
died.emit()was_alive keeps died from being emitted again when a hero with 0 HP is hit once more.
A signal can also be reached through its name as text: emit_signal("died") emits it, hero.connect("died", _on_hero_died) connects to it, and hero.has_signal("died") returns true. Connecting to a name the object does not declare is an error when that line runs.
Challenge
EasyWrite a Bomb that counts down and announces each step with signals.
- Declare two signals:
beepedandexploded. tick()lowersfuseby1. If the fuse is still above0, emitbeeped; if it has reached0, emitexploded.- Once the fuse is
0, the bomb has exploded: further ticks do nothing and emit nothing.
The supplied code reads the starting fuse and how many ticks to run, connects to both signals by name and prints Beep and BOOM! from the connected functions, then the remaining fuse. For a fuse of 3 and 5 ticks it prints:
Beep
Beep
BOOM!
Fuse: 0Your code goes in bomb.gd. main.gd holds the supplied input/output code and cannot be edited.
Try it yourself
extends Node
func _ready():
# Supplied input/output code: keep it as it is
var bomb := Bomb.new(int(OS.read_string_from_stdin()))
# connect() with the signal's name as text
bomb.connect("beeped", _on_beeped)
bomb.connect("exploded", _on_exploded)
var ticks := int(OS.read_string_from_stdin())
for i in ticks:
bomb.tick()
print("Fuse: ", bomb.fuse)
func _on_beeped() -> void:
print("Beep")
func _on_exploded() -> void:
print("BOOM!")
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe self KeywordMethodsPropertiesConstructor (_init)Recap - Simple Calculator4Polymorphism
Method Overriding RevisitedDuck TypingAbstract Classes and MethodsInterface DesignRecap - Shape Calculator7Signals
What is a Signal?Declaring and EmittingConnecting to SignalsSignals with ArgumentsRecap - Health System2Class Properties
Instance vs Static VariablesStatic FunctionsProperty SettersProperty GettersPrivate by ConventionRecap - Bank Account Manager5Encapsulation
Public and Private MembersValidation with SettersInformation HidingRead-Only PropertiesRecap - Student Records System8Advanced OOP Concepts
Composition vs InheritanceInner ClassesNodes as ComponentsRefCounted vs NodeEnums in Classes11Project: Library Management
Project OverviewBook and User Classes3Inheritance
Basic InheritanceThe super KeywordMethod OverridingInheritance ChainsType Checks with isRecap - Employee Hierarchy6Special Methods
Virtual Methods IntroductionThe _to_string MethodCustom IteratorsRecap - Custom List9Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy PatternPractice on your own: Online GDScript compiler