Menu
CoddyTech

Conectarse a las señales

Parte de la sección Programación orientada a objetos del Journey de GDScript de Coddy. Lección 37 de 65.

connect() recibe la función que debe ejecutar, como un Callable. Escribe el nombre de un método sin paréntesis, o escribe una lambda:

chest.opened.connect(_on_chest_opened)          # un método de este script
chest.opened.connect(quest_log.add_entry)       # un método de otro objeto
chest.opened.connect(func(): print("Creak!"))   # una función lambda

Godot nombra un método receptor _on_, después el emisor y, después, la señal: _on_chest_opened. Una señal puede tener muchas funciones conectadas, y se ejecutan en el orden en que se conectaron.

Un objeto que escucha suele conectarse a sí mismo, en un método que recibe el emisor:

# quest_log.gd
class_name QuestLog
extends RefCounted

var chests_opened := 0

func track(chest: Chest) -> void:
	if not chest.opened.is_connected(_on_chest_opened):
		chest.opened.connect(_on_chest_opened)

func untrack(chest: Chest) -> void:
	if chest.opened.is_connected(_on_chest_opened):
		chest.opened.disconnect(_on_chest_opened)

func _on_chest_opened() -> void:
	chests_opened += 1

Conectar la misma función a la misma señal dos veces es un error, al igual que desconectar una función que no está conectada. is_connected() lo comprueba primero. disconnect() deja de escuchar, y la siguiente emisión ya no ejecuta esa función.

Pasa CONNECT_ONE_SHOT como segundo argumento y la conexión se elimina después de su primera llamada: chest.opened.connect(_on_first_open, CONNECT_ONE_SHOT).

Una lambda conserva el valor que tenía una variable local cuando se creó la lambda. count += 1 dentro de una lambda conectada cambia esa copia, y count en _ready() sigue siendo 0. Mantén un contador en una variable miembro de un objeto listener, como hace QuestLog.

challenge icon

Desafío

Fácil

Un campo de tiro tiene objetivos que emiten hit cuando reciben un disparo. Escribe el ScoreBoard que los escucha:

  • watch(target) conecta la señal hit del objetivo con _on_target_hit. Observar un objetivo que ya se está observando no cambia nada.
  • ignore(target) desconecta la señal. Ignorar un objetivo que no se está observando no cambia nada.
  • _on_target_hit() suma 10 a points e imprime Hit! Score: N.

Observar dos veces o ignorar un objetivo que no se está observando no debe provocar un error, porque cualquier error hace que la prueba falle. target.gd está completo.

El código proporcionado lee el número de objetivos, luego comandos como watch 0, ignore 0 y shoot 0, e imprime la puntuación final. Para dos objetivos y los comandos watch 0, shoot 0, shoot 1, watch 1, watch 1, shoot 1, ignore 0, shoot 0, imprime:

Shot target 0
Hit! Score: 10
Shot target 1
Shot target 1
Hit! Score: 20
Shot target 0
Final score: 20

Tu código va en score_board.gd y target.gd. main.gd contiene el código proporcionado de entrada/salida y no se puede editar.

Pruébalo tú mismo

extends Node

func _ready():
	# Código de entrada/salida proporcionado: déjalo tal como está
	var board := ScoreBoard.new()
	var targets: Array[Target] = []
	for i in int(OS.read_string_from_stdin()):
		targets.append(Target.new())
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		var target := targets[int(parts[1])]
		if parts[0] == "watch":
			board.watch(target)
		elif parts[0] == "ignore":
			board.ignore(target)
		else:
			print("Shot target ", parts[1])
			target.shoot()
	print("Final score: ", board.points)
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación orientada a objetos

Practica por tu cuenta: Compilador de GDScript online