Menu
CoddyTech

Déclarer et émettre

Fait partie de la section Programmation orientée objet du Journey GDScript de Coddy. Leçon 36 sur 65.

Déclare un signal avec le mot-clé signal et un nom, en haut de la classe, à côté de ses variables. Le nom d’un signal décrit un événement qui s’est déjà produit, en snake_case : died, door_opened, leveled_up. Une classe déclare autant de signaux qu’elle en a besoin :

# 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()

Émettez un signal au moment où l’événement correspondant se produit, et uniquement à ce moment-là. add_xp(50) sur un nouveau joueur n’émet rien. add_xp(250) après que cela a porté xp à 300 : leveled_up est émis deux fois, une fois par niveau gagné, et max_level_reached une fois, lors de la montée de niveau qui atteint le niveau 3.

Un accesseur de propriété est un bon endroit pour émettre un signal, car celui-ci se déclenche alors quel que soit le code qui modifie la valeur :

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 empêche died d’être émis à nouveau lorsqu’un héros ayant 0 PV est touché une fois de plus.

On peut aussi accéder à un signal par son nom sous forme de texte : emit_signal("died") l’émet, hero.connect("died", _on_hero_died) s’y connecte, et hero.has_signal("died") renvoie true. Se connecter à un nom que l’objet ne déclare pas provoque une erreur lorsque cette ligne s’exécute.

challenge icon

Défi

Facile

Écris une Bomb qui effectue un compte à rebours et annonce chaque étape avec des signaux.

  • Déclare deux signaux : beeped et exploded.
  • tick() diminue fuse de 1. Si le fusible est toujours supérieur à 0, émets beeped ; s’il a atteint 0, émets exploded.
  • Une fois que le fusible est à 0, la bombe a explosé : les ticks suivants ne font rien et n’émettent aucun signal.

Le code fourni lit la valeur initiale du fusible et le nombre de ticks à effectuer, se connecte aux deux signaux par leur nom et affiche Beep et BOOM! depuis les fonctions connectées, puis le fusible restant. Pour un fusible de 3 et 5 ticks, il affiche :

Beep
Beep
BOOM!
Fuse: 0

Écris ton code dans bomb.gd. main.gd contient le code fourni pour les entrées et sorties et ne peut pas être modifié.

Essayez vous-même

extends Node

func _ready():
	# Code d'entrée/sortie fourni : conservez-le tel quel
	var bomb := Bomb.new(int(OS.read_string_from_stdin()))
	# connect() avec le nom du signal sous forme de texte
	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!")
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Compilateur GDScript en ligne