Préambule

Qu’est ce qu’un signal : C’est tout simplement une technique qui permet à un script de retourner une information sous certaines conditions.

Un signal peut être reçu par un autre script qui peut traiter cette information et émettre en retour un nouveau signal à destination d’un autre script.

Ce mets alors en place une communication entre les scripts.

En un mot les signaux sont donc la base de la communication entre les scripts au sein de Godot.

Méthodologie

Avant toute chose, il existe deux grandes techniques pour gérer les signaux :

  • Un script parent peut écouter les écouter les signaux d’enfants individuellement.
  • Les scripts enfants peuvent envoyer des signaux à leur parent. Les parents réceptionnent « optionnellement » ces signaux.

La première technique présente les gros désavantage de ne pas être « procédurale ». En effet, pour qu’un script parent écoute des enfants, il va falloir spécifier en dur le chemin de chaque enfant. Si le nom change le script n’est plus valides. Si on ajoute un nouvel enfant il faut ajouter des lignes de code dans le script parent. Possible, mais la maintenance et la clarté du code ne sont pas optimal.

Nous allons donc nous concentrer sur la seconde techniques qui consiste à faire en sorte que l’enfant émette un signal qui sera récupérer par le parent.

La méthodologie est donc la suivante :

  • création de la fonction « d’écoute » dans le script parent.
  • création du signal dans le script enfant.
  • connection entre le signal enfant et le script du parent.
  • création de l’évènement qui va déclencher l’émission du signal.
  • émission du signal.

Exemple de mise en place d’un signal

Dans cette exemple nous allons créer un jeu de ce type :

On veut donc que les item enfant envoi un signal pour donner leur nom et optionnellement pour donner un score.

On commence par créer une scène 2D, on y attache un script puis on crée notre fonction « d’écoute »:

extends Node2D

func hit_item(my_signal):
	print("Je suis une " + str(my_signal))
	pass

Ensuite, on crée une scène « Player » qui sera instanciée dans la main scène. Cette scène contient un node Collision2D pour la détection de collision et un script pour les commandes clavier :

extends KinematicBody2D

var speed = 5

func _ready():
	pass

func _process(delta):
	if Input.is_key_pressed(KEY_LEFT):
		self.position.x -= speed
	if Input.is_key_pressed(KEY_RIGHT):
		self.position.x += speed
	if Input.is_key_pressed(KEY_UP):
		self.position.y -= speed
	if Input.is_key_pressed(KEY_DOWN):
		self.position.y += speed

On crée ensuite une dernière scène « item », cette item pourra accueillir différente type d’item (via une variable de type enum exporté dans l’Inspector de l’Area2D parent qui le compose). Elle contient également un node Collision2D toujours pour la détection de collision et un script qui va gérer le type d’item et bien entendu l’émission du signal :

Avant d’attaquer le code du signal, nous allons créer un événement de type collision sur le node parent Area2D et le connecter au script en cours :

Toujours dans le script de l’item, on crée l’export du type d’objet :

tool
extends Area2D

enum type_item {APPLE = 16, GEM = 26, SWORD = 39, KEY = 59}
export(type_item) var item_type
var my_name

func _ready():
		match item_type:
			type_item.APPLE :
				$Sprite.frame = 16
				my_name = "une Pomme yeahh !!!"
			type_item.GEM :
				$Sprite.frame = 26
				my_name = "une Gemme yeahh !!!"

func _process(delta):
	pass

func _on_Area2D_body_entered(body):
	pass # Replace with function body.

Bien sûr ici la texture du Sprite est un Tileset que voila :

Ainsi que les réglages « d’animation » de la texture :

Puis finalement, nous mettons en place le signal dans le script de notre item :

  1. On initialise le signal, un peu à la manière d’une variable. On lui donne un nom « hit » et pour le moment, pas d’argument.
  2. Dans la fonction _ready() on connecte le signal grace à la méthode .connect().
    En premier argument cette méthode requiert le nom du signal que l’on souhaite passer (attention, cette argument doit être un string. En second argument, la methode attend la destination de la connection, dans notre cas un get_parent() garanti le procéduralisme du script.
    Le troisième argument est la fonction de destination, celle qui va réceptionner le signal dans le script parent.
  3. On emet le signal grace à la méthode .emit_signal().
    Le premier argument est le signal que l’on souhaite émettre, toujours sous forme de string.
    Les arguments suivant sont ce que l’on veut émettre dans ce signal. Ici je choisi d’émettre le nom de chaque item.

Tout est prêt, reste à assembler la scène en instanciant les scènes Player et Item puis voir ce qui se passe :

Passer plusieurs informations.

Il est tout a fait possible de passer plusieurs informations dans un même signal. Pour se faire, il faut créer plus d’argument lors de la création du signal, puis le envoyer via la methode .emit_signal() et pour finir les traiter dans la fonction réceptrice :

Puis dans le script de la scène principale :


0 commentaire

Laisser un commentaire