Menu
CoddyTech

O que é um sinal?

Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 35 de 65.

As coisas acontecem com os objetos enquanto um jogo está em execução: uma moeda é coletada, uma porta se abre, o hp do herói cai para 0. Outras partes do programa reagem a esses eventos: a pontuação aumenta, um som toca, a tela de fim de jogo aparece.

Um sinal é uma mensagem que um objeto envia quando algo acontece com ele. O objeto emite o sinal, e todas as funções conectadas a esse sinal são executadas:

# coin.gd
class_name Coin
extends RefCounted

signal collected

func collect() -> void:
	print("Coin picked up")
	collected.emit()

signal collected declara o sinal e collected.emit() o envia. A moeda não sabe quem está ouvindo. O código que se importa com as moedas conecta uma de suas próprias funções ao sinal:

# main.gd
func _ready():
	var coin := Coin.new()
	coin.collected.connect(_on_coin_collected)
	coin.collect()
	print("Done")

func _on_coin_collected() -> void:
	print("Score +1")

A saída é Coin picked up, Score +1, Done. A emissão executa as funções conectadas imediatamente, antes da linha após emit(). Um sinal sem funções conectadas não faz nada quando é emitido.

Sem um sinal, collect() teria que chamar o código da pontuação por conta própria, então cada moeda precisaria de uma referência ao placar. Com um sinal, a moeda apenas anuncia o evento, e qualquer número de ouvintes, ou nenhum, pode reagir a ele.

Os próprios nós do Godot funcionam da mesma forma: um Button emite pressed quando é clicado, e um Timer emite timeout quando o tempo se esgota.

challenge icon

Desafio

Fácil

Uma caixa de correio anuncia novas cartas com um sinal. Mailbox já declara signal mail_arrived e tem um contador letters. Escreva deliver(kind):

  • Quando kind for "letter", adicione 1 a letters e emita mail_arrived.
  • Qualquer outro tipo (um anúncio, um panfleto) é descartado: nada muda e nada é emitido.

O código fornecido conecta uma função que imprime You've got mail!, depois lê quantas linhas vêm a seguir e entrega cada uma delas. A linha away desconecta essa função e home a conecta novamente, então uma carta que chega enquanto você está fora é contabilizada, mas não anunciada. Para as linhas letter, ad, away, letter, ele imprime:

Delivering: letter
You've got mail!
Delivering: ad
Delivering: letter
Letters: 2

Seu código deve ficar em mailbox.gd. main.gd contém o código de entrada/saída fornecido e não pode ser editado.

Experimente você mesmo

extends Node

func _ready():
	# Código de entrada/saída fornecido: mantenha-o como está
	var mailbox := Mailbox.new()
	mailbox.mail_arrived.connect(_on_mail_arrived)
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var line := OS.read_string_from_stdin()
		if line == "away":
			mailbox.mail_arrived.disconnect(_on_mail_arrived)
		elif line == "home":
			mailbox.mail_arrived.connect(_on_mail_arrived)
		else:
			print("Delivering: ", line)
			mailbox.deliver(line)
	print("Letters: ", mailbox.letters)

func _on_mail_arrived() -> void:
	print("You've got mail!")
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação orientada a objetos

Pratique por conta própria: Compilador de GDScript online