Sinais com argumentos
Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 38 de 65.
Um sinal pode transportar valores. Liste-os na declaração, como os parâmetros de uma função:
signal damaged(amount: int, hp_left: int)
signal diedPasse os valores para emit() na mesma ordem:
func take_damage(amount: int) -> void:
hp = maxi(hp - amount, 0)
damaged.emit(amount, hp)
if hp == 0:
died.emit()Uma função conectada recebe os valores como parâmetros, então ela precisa de um parâmetro para cada valor:
hero.damaged.connect(_on_hero_damaged)
func _on_hero_damaged(amount: int, hp_left: int) -> void:
print("-%d HP, %d left" % [amount, hp_left])Os tipos na declaração documentam os valores: o GDScript não os verifica quando você emite. Uma incompatibilidade aparece na função que recebe o sinal. Uma função com o número errado de parâmetros, ou um parâmetro tipado que não pode conter o valor, gera um erro na linha emit(), e essa função não é executada.
bind() adiciona os próprios valores depois dos emitidos. Assim, um método pode escutar vários heróis e ainda saber qual deles foi atingido:
ada.damaged.connect(_on_damaged.bind("Ada"))
bo.damaged.connect(_on_damaged.bind("Bo"))
func _on_damaged(amount: int, hp_left: int, who: String) -> void:
print(who, " lost ", amount, " HP")Os argumentos fornecem ao ouvinte os dados de que ele precisa, para que não tenha de obtê-los do emissor. Nunca conecte uma lambda que use o próprio objeto emissor, como hero.died.connect(func(): print(hero.hp)): a lambda mantém hero vivo, hero mantém a lambda, nenhum dos dois é liberado, e o Godot informa instâncias não liberadas quando o programa termina.
Desafio
FácilUma carteira relata cada alteração por meio de sinais que carregam os números. Em Wallet, adicione os parâmetros aos dois sinais e escreva os dois métodos:
balance_changed(old_balance: int, new_balance: int)epurchase_failed(price: int, missing: int)add(amount)adiciona moedas e emitebalance_changedcom o saldo antes e depois.buy(price): quando o saldo é suficiente, subtraia o preço e emitabalance_changed. Caso contrário, não altere nada e emitapurchase_failedcom o preço e quantas moedas estão faltando.
O código fornecido conecta uma função a cada sinal, lê quantos comandos vêm a seguir, executa cada comando (add 20, buy 15) e imprime as moedas restantes ao final. Para add 20, buy 15, buy 10, add 5, buy 10, ele imprime:
Balance: 0 -> 20
Balance: 20 -> 5
Cannot buy for 10: 5 coins missing
Balance: 5 -> 10
Balance: 10 -> 0
Coins left: 0Seu código deve ficar em wallet.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 wallet := Wallet.new()
wallet.balance_changed.connect(_on_balance_changed)
wallet.purchase_failed.connect(_on_purchase_failed)
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "add":
wallet.add(int(parts[1]))
else:
wallet.buy(int(parts[1]))
print("Coins left: ", wallet.balance)
func _on_balance_changed(old_balance: int, new_balance: int) -> void:
print("Balance: %d -> %d" % [old_balance, new_balance])
func _on_purchase_failed(price: int, missing: int) -> void:
print("Cannot buy for %d: %d coins missing" % [price, missing])
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
1Fundamentos da POO
Arquivos externosIntrodução à POOClasses vs. objetosA palavra-chave selfMétodosPropriedadesConstrutor (_init)Revisão - Calculadora simples4Polimorfismo
Revisitando a Sobrescrita de MétodosDuck TypingClasses e Métodos AbstratosDesign de InterfacesRevisão - Calculadora de Formas7Sinais
O que é um sinal?Declarando e emitindoConectando-se a sinaisSinais com argumentosRevisão - Sistema de saúde10Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite2Propriedades de Classe
Variáveis de Instância vs. EstáticasFunções EstáticasMétodos Setters de PropriedadeMétodos Getters de PropriedadePrivado por ConvençãoRecapitulando: Gerenciador de Conta Bancária5Encapsulamento
Membros públicos e privadosValidação com settersOcultação de informaçõesPropriedades somente para leituraRevisão - Sistema de registros de alunos8Conceitos Avançados de POO
Composição vs. HerançaClasses InternasNós como ComponentesRefCounted vs. NodeEnums em Classes3Herança
Herança básicaA palavra-chave superSobrescrita de métodosCadeias de herançaVerificações de tipo com isRevisão - Hierarquia de funcionários6Métodos especiais
Introdução aos métodos virtuaisO método _to_stringIteradores personalizadosRevisão - Lista personalizada9Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão StrategyPratique por conta própria: Compilador de GDScript online