Tutorial: Uso de Señales en Godot 4

2 min read

1. Player recoge monedas → HUD suma puntaje
Escena:
Player
(CharacterBody2D)Coin
(Area2D con CollisionShape2D)HUD
(Control con LabelScoreLabel
)
Código de la moneda (coin.gd
)
extends Area2D
signal coin_collected(points: int)
@export var points: int = 10
func _on_body_entered(body: Node) -> void:
if body.is_in_group("player"):
coin_collected.emit(points)
queue_free() # destruye la moneda
Código en el HUD (hud.gd
)
extends Control
var score: int = 0
@onready var score_label: Label = $ScoreLabel
func add_points(points: int) -> void:
score += points
score_label.text = str(score)
Conexión de la señal (en Player
o LevelManager
)
func _ready():
for coin in get_tree().get_nodes_in_group("coins"):
coin.coin_collected.connect($HUD.add_points)
2. Player ataca → enemigo recibe daño
Escena:
Player
con unaSword
(Area2D)Enemy
(CharacterBody2D con scriptenemy.gd
)
Código en la espada (sword.gd
)
extends Area2D
signal hit_enemy(damage: int)
@export var damage: int = 25
func _on_body_entered(body: Node) -> void:
if body.is_in_group("enemy"):
hit_enemy.emit(damage)
Código en el enemigo (enemy.gd
)
extends CharacterBody2D
var health: int = 100
func take_damage(amount: int) -> void:
health -= amount
print("Enemy HP:", health)
if health <= 0:
queue_free() # enemigo muere
Conexión
func _ready():
$Player/Sword.hit_enemy.connect($Enemy.take_damage)
3. Player recibe daño → HUD actualiza vida
Escena:
Player
(CharacterBody2D con vida)EnemyAttack
(Area2D)HUD
(Control con barra de vidaHealthBar
)
Código del player (player.gd
)
extends CharacterBody2D
signal health_changed(new_health: int)
var max_health: int = 100
var health: int = 100
func take_damage(amount: int) -> void:
health -= amount
health = max(health, 0)
health_changed.emit(health)
if health <= 0:
print("Game Over")
Código del HUD (hud.gd
)
extends Control
@onready var health_bar: ProgressBar = $HealthBar
func update_health(value: int) -> void:
health_bar.value = value
Conexión
func _ready():
$Player.health_changed.connect($HUD.update_health)
Código del ataque enemigo (enemy_
attack.gd
)
extends Area2D
@export var damage: int = 20
func _on_body_entered(body: Node) -> void:
if body.is_in_group("player"):
body.take_damage(damage)
4. Player cruza puerta → cambiar de escena
Escena:
Door
(Area2D con CollisionShape2D)Player
Código en la puerta (door.gd
)
extends Area2D
signal player_entered
@export var next_scene: String = "res://scenes/room2.tscn"
func _on_body_entered(body: Node) -> void:
if body.is_in_group("player"):
player_entered.emit()
Conexión para cambiar escena (ejemplo en LevelManager.gd
)
extends Node
func _ready():
$Door.player_entered.connect(change_scene)
func change_scene():
var new_scene = load($Door.next_scene)
get_tree().change_scene_to_packed(new_scene)
Conclusiones
Emitir señal:
signal nombre(parametros)
y luegoemit(parametros)
.Conectar señal:
nodo.signal.connect(función_receptora)
.Beneficio: Se evita acoplar directamente Player ↔ HUD, Enemy ↔ Player, etc.
0
Subscribe to my newsletter
Read articles from Jorge Leonardo Cespedes Tapia directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Jorge Leonardo Cespedes Tapia
Jorge Leonardo Cespedes Tapia
I software engineer. Developer Python. I read books. I watch movies. I writer fiction. I am a black cat. And You?