Guide de l'atelier
==================

### Le jeu

- [Le dépôt git](https://gogs.jovian-hersemeule.eu/DricomDragon/RaquetteFracassante)
- [Alpha Raquette sur Itch.io](https://dricomdragon.itch.io/alpha-raquette)

### Outils

- [Site officiel Godot](https://godotengine.org/)
- [Documentation officielle Godot](https://docs.godotengine.org/en/stable/)

## Introduction

### Principe de l'atelier

Vous avez à disposition un **projet starter** en Godot. C'est un casse-brique en 2D que vous aurez la liberté d'améliorer selon vos envies.

Le projet sera disponible en deux versions permettant aux personnes
présentes lors de l'atelier d'orienter leur découverte du Godot Engine
:

- Version **architecte** : Parcours conception de niveaux (le jeu est
    complet, il faut juste ajouter de nouveaux niveaux)
    - Cela permet de découvrir l'interface du Godot Engine en douceur
        et d'utiliser des fonctionnalités simples. Cela permet de se familiariser
		à Godot sans avoir à écrire de code.
- Version **artisan** : Parcours construction du jeu (le jeu contient
    uniquement des fonctionnalités minimales et tout le reste est à
    faire soi-même)
    - On va pouvoir ainsi ajouter divers types de fonctionnalités
        (interface, visuels, audio ou gameplay) et appréhender la façon
        dont les fonctionnalités dépendent les unes des autres. Par
        exemple pour ajouter un écran de victoire ou de défaite (élément
        d'interface), il faut d'abord que le jeu sache quand est-ce
        qu'on gagne ou qu'on perd (fonctionnalité de gameplay).
	- Le début de l'atelier est linéaire pour pouvoir prendre en main l'éditeur ;
    - À partir d'un certain point,
		vous serez libres de faire les étapes dans l'ordre que vous
        voulez, mais attention aux dépendances ! Repérez vous grâce à la
        carte fournie.

<figure>
![Carte représentant les différentes étapes du tutoriel](img/carte_des_etapes.png)
</figure>

Légende de la carte :

- Couleurs des cases
	- Blanc : logique du jeu
	- Vert : interface utilisateur
	- Bleu : graphisme ou effets visuels
	- Jaune : sons ou musique
	- Gris : exporter son jeu
- Couleurs des flèches
	- Vert : parcours architecte
	- Bleu : artisan débutant
	- Jaune : artisan novice
	- Rouge : expert B-)
- Le nombre de triangles sur chaque case de la carte indique la difficulté. 1 étant facile, et 4 difficile.


#### Dé-commenter le code

Il y aura du code déjà présent à dé-commenter dans les scripts. Essayez
de comprendre chaque bout de code vous-même.

Les commentaires en Godot commencent avec `#`. Raccourci pour dé-commenter
les lignes sélectionnées : `Ctrl` + `K`.

> Note : les commentaires doubles `##` sont des commentaires spéciaux dits
de documentation (docstrings). Il ne faut pas les dé-commenter ! Le texte
associé est visible dans l'éditeur.


### Description de Godot

Partie théorique pour avoir un peu de contexte.


- Définition d'un moteur de jeu
    - Un **moteur de jeu** est un ensemble de composants logiciels qui
        effectuent des calculs de géométrie et de physique utilisés dans
        les jeux vidéo. L'ensemble forme un simulateur en temps réel
        souple qui reproduit les caractéristiques des mondes imaginaires
        dans lesquels se déroulent les jeux. Le but visé par un moteur
        de jeu est de permettre à une équipe de développement de se
        concentrer sur le contenu et le déroulement du jeu plutôt que la
        résolution de problèmes informatiques. (Wikipédia)



- Avantages  de Godot
    - Rapidité et facilités de création et de prototypage (idéal pour
        faire des game jam) ;
    - Beaucoup d'outils accessibles sans code ;
    - GDScript (langage interne) facile à lire pour les débutants et
        débutantes ;
    - Possibilité de coder en C++ pour les développeur·euses (ou
        d'autres langages via des addons) ;
    - Bibliothèque d'addons disponible dans le moteur directement ;
    - Aide accessible directement dans le moteur ;
    - Espace de travail modulaire pour s'adapter aux préférences de
        chacun et chacune ;
    - Moteur complet au niveau des fonctionnalités de base (2D, 3D,
        réseau, audio, UI).
- et inconvénients...
    - Pas encore au niveau sur certains aspects très pointus (3D et
        gestion audio notamment).



### Éditeur Godot

[Documentation officielle sur l'éditeur](https://docs.godotengine.org/fr/4.x/tutorials/editor/index.html#editor-s-interface)


### Concepts Godot




- Nœuds
    - Les nœuds sont les briques de construction de bases de Godot.
        Ils sont agencés sous forme d'arbres dont un nœud est la racine
        dont part ensuite des nœuds enfants, des nœuds petits-enfants et
        ainsi de suite. On peut regrouper les nœuds dans des
        **scènes**.
	- Les scènes peuvent être réutilisées dans d'autres scènes.
		Par exemple, si vous faites une scène "brique", vous
		pouvez faire une scène niveau qui contient plusieurs briques.
    - Les scènes sont sauvegardées dans les
        fichiers du projet sous la forme de fichiers terminant par
        l'extension `.tscn`.
	- On doit indiquer à Godot une scène à lancer au démarrage du jeu :
		on appelle cette scène la scène principale.
- Scripts
    - Permet de décrire les règles et comportements que doivent suivrent
        les nœuds. Par exemple déplacer la balle à chaque image, éclater
        une brique quand elle n'a plus de vie, ou changer de musique au
        chargement d'un niveau. Les scripts sont écrits via l'éditeur
        de code intégré, et permettent de décrire comment réagir aux
        événements du jeu. Godot étant un moteur riche, il n'y a pas
        besoin d'écrire beaucoup de texte pour faire fonctionner notre
        jeu. Pour qu'un script soit interprété par Godot, il faut
        l'attacher à un nœud, via l'éditeur.
    - Définition **variable** : valeur qui peut changer en cours du
        temps, que nous pouvons lire ou écrire depuis un script via son
        nom (exemple : boolean a_perdu_vie ; Vector2
        direction_rebond).
        - Une variable attachée au nœud s'appelle **propriété** ou
            attribut (exemple : Vector2 position pour un Node2D).
        - Une variable qui est une entrée d'une fonction s'appelle
            un **argument**
    - Définition **fonction** : bout de script associé à un nom qui
        est exécuté quand on l'appelle.
        - Une fonction attachée à un nœud s'appelle aussi **méthode**
        - Le nom d'une fonction doit contenir un verbe, car appeler
            une fonction c'est faire quelque chose.
    - Pas à pas :
        <https://docs.godotengine.org/fr/4.x/tutorials/scripting/gdscript/gdscript_basics.html>
    - Bonnes pratiques
        - Style :
            <https://docs.godotengine.org/fr/4.x/tutorials/scripting/gdscript/gdscript_styleguide.html>
        - Typage (pour ceux qui savent coder) :
            <https://docs.godotengine.org/fr/4.x/tutorials/scripting/gdscript/static_typing.html>
- Héritage
    - Des scripts internes existent dans Godot, afin de coder les
        comportements des nœuds existants. Au début d'un script, on
        désigne de quel autre script on souhaite hériter, via le
        mot-clef `extends`. Le cas le plus commun est d'hériter d'un
        script interne à Godot, mais on peut aussi hériter d'un de nos
        scripts déjà existants. Lorsque nous héritons d'un script, nous
        pouvons appeler toutes ses méthodes et accéder à ses propriétés.
        Par exemple, un script qui hérite de Node2D peut modifier la
        propriété position, et ainsi déplacer l'objet !
        - Classe : une classe est un script qui a nom : `class_name
            Balle`. Quand on écrit un script, on ne peut hériter que
            d'une classe. Heureusement, tous les scripts internes de
            Godot sont aussi des classes. :-)
        - Bonjour grand-père : l'héritage peut être cumulatif. Si
            vous héritez de Sprite2D, qui hérite lui-même de Node2D,
            votre script possède à la fois les propriétés de Sprite2D
            (comme texture par exemple) et de Node2D (position).

- Espace / géométrie
    - Les objets 2D sont positionnés dans l'espace via deux
        coordonnés : x et y. Très souvent utilisées ensemble, ces
        coordonnées sont regroupées dans un même objet : un vecteur.
        Dans Godot, les coordonnées 2D sont exprimées en pixels. Ici, l'écran
        est un carré de 420 pixels de côté. Si un nœud est positionné en
        x=0, y=0, il sera en haut à gauche. S'il est en x=210, y=420,
        il sera au milieu tout en bas de l'écran.
    - Image : voir l'illustration des axes de l'écran
    - Comprendre les vecteurs :
        <https://docs.godotengine.org/fr/4.x/tutorials/math/vector_math.html>
    - Référence : Vector2
        <https://docs.godotengine.org/fr/4.x/classes/class_vector2.html>


![Illustration des axes](img/vector_xy1.png)

## Lancer le jeu depuis l'éditeur

- Prérequis
	- Avoir installé [Godot 4.3](https://godotengine.org/download/archive/4.3-stable/)
	- Avoir téléchargé et décompréssé [un projet de l'atelier](https://www.jovian-hersemeule.eu/cdl/raquette/projets/)

- Actions
    - Démarrer l'exécutable de Godot : La fenêtre de gestion des projets s'ouvre (importation, création de nouveau projet, lancement de l'éditeur, etc).
    - Importer l'un des projets de casse-brique fournis ; l'éditeur s'ouvre automatiquement, sinon sélectionner le projet dans la liste et cliquer sur "Éditer".
    - Pour démarrer le jeu via l'éditeur, cliquer sur le bouton "lecture" situé en haut à droite de l'écran (à côté du bouton "stop" notamment).
        - Une nouvelle fenêtre s'ouvre et le jeu démarre.


- Notion de scène principale
    - Lorsqu'on démarre le jeu (via l'éditeur ou un exécutable), ce qui est démarré est une scène dite "principale", définie dans l'éditeur. Et
c'est de cette scène que vont ensuite être démarrées toutes les autres
scènes qui composent le jeu.
- Les dossiers des deux projets sont organisés de la manière suivante  :
	- "Composants", contient tous les composants qui une fois
		assemblés forment le jeu. On y trouve donc les scènes,
		script, visuels et sons pour : les interfaces, les objets
		(balle, brique, capsule, arène, raquette, etc) et enfin les
		pouvoirs (balle de feu par exemple).
	- "Effets", qui contient les phénomènes éphémères qui peuvent
		survenir en jeu. Au début de l'atelier le seul présent dans
		la version artisan est l'effet d'une brique qui éclate.
	- "Exec", qui contient les principales scènes du jeu qui
		vont "s'exécuter". On y trouve la scène principale du jeu
		("game"), une scène de gestion de la musique et deux
		dossiers. Le dossier "choix" contient les éléments
		relatifs à l'écran de choix de niveau et à son
		fonctionnement et le dossier "niveaux" qui contient des
		scènes correspondant chacune à un niveau du jeu.
	- "Ressources", qui contient les musiques du jeu, ainsi que
		les textures utilisées.
- Concernant les fichiers hors dossiers :
	- Nous avons les fichiers terminant par ".svg", qui sont des
		images servant d'icônes pour l'exécutable du projet, ces
		fichiers ne sont pas utilisé dans le jeu lui-même.
	- "project.godot" est le fichier principal du projet pour
		l'éditeur. C'est à partir de ce fichier que l'éditeur
		charge le projet pour qu'on puisse ensuite travailler
		dessus.
	- Les fichiers se terminant par ".import" sont des fichiers
		de configuration d'importation des visuels et sont créés
		par le Godot Engine.
	- Les fichiers se terminant par ".tres" sont des fichiers
		textes qui permettent au Godot Engine de gérer différents
		types de données pour différents usages. Ici par exemple,
		"default_bus_layout.tres" sert à gérer les flux audio
		dans le projet.


> Note : L'ensemble de ses fichiers et dossiers doivent être édités dans
l'éditeur de Godot et non directement via le navigateur de fichiers.

- [ ] J'ai fait cette étape.
- Suite
	- Continuer l'initiation : [Modifier le niveau existant](#modifier-le-niveau-existant)



## Modifier le niveau existant



Niv. 1

- Prérequis
	- [Lancer le jeu depuis l’éditeur](#lancer-le-jeu-depuis-léditeur)
- Actions
    - Dans la vue 2D, configurer la grille (bouton "Option
        d'aimantation") avec les valeurs suivantes :
        - Décalage : x = 30, y = 0.
        - Pas : x = 30 px, y = 16 px (taille d'une brique).
        - Ligne primaire tous les : x = 4 pas, et y = 8 pas.
    - Dupliquer les nœuds Brique pour en créer de nouveaux et
        placer-les dans le niveau.
    - Changer les paramètres de chaque brique indépendamment dans
        l'Inspecteur.

Image : Capture de la configuration de la grille
![Capture de la configuration de la grille](img/editor_gd4_raquette_config_grille.png)

- [ ] J'ai modifié un niveau existant !
- Suite
	- Parcours architecte : [Créer un autre niveau](#créer-un-autre-niveau)
	- Parcours artisan : [Changer l’image de la raquette](#changer-limage-de-la-raquette)


## Créer un autre niveau


Niv. 1

- Prérequis
	- [Modifier le niveau existant](#modifier-le-niveau-existant)

- Actions
    - Dupliquer la scène d'un niveau.
    - Modifier le niveau existant.
    - Ajouter un niveau au menu :
        - Aller dans la scène "choix_niveau".
        - Dupliquer un nœud planète.
        - Placer la nouvelle planète dans un endroit vide du ciel
            étoilé dans la vue 2D.
        - Modifier le champ "Niveau" de la planète dans
            l'Inspecteur pour choisir votre niveau.
        - Modifier le champs "Normal" de la section "Texture" pour
            changer l'image de la planète.
- [ ] J'ai fait cette étape.
- Suite
	- Refaire la même étape en créant un autre niveau !
	- Pour avoir plus de place pour mettre des niveaux : [Pouvoir scroller les planètes](#pouvoir-scroller-les-planètes)
	- Continuer le parcours artisan : [Changer l’image de la raquette](#changer-limage-de-la-raquette)
	- Pour les expert·es : [Passer au niveau suivant une fois un niveau terminé](#passer-au-niveau-suivant-une-fois-un-niveau-terminé)

## Pouvoir scroller les planètes



Niv. 1


- Actions
    - Ajouter un nœud ScrollContainer dans la scène
        "choix_niveau.tscn"
    - Mettre le SystemeSolaire en tant qu'enfant de ce nœud.
    - Redimensionner le ScrollContainer pour qu'il prenne l'espace
        visible.
        - Soit à la main dans la vue 2D.
        - Soit dans l'Inspecteur, section "Transform", champs
            "Size", mettre les valeurs de X et Y à 420.

- [ ] J'ai activé le scrolling dans le choix du niveau !
- Suite
	- Remplir l'espace : [Créer un autre niveau](#créer-un-autre-niveau)
	- Continuer le parcours artisan : [Changer l’image de la raquette](#changer-limage-de-la-raquette)
	- Pour les expert·es : [Passer au niveau suivant une fois un niveau terminé](#passer-au-niveau-suivant-une-fois-un-niveau-terminé)


## Changer l'image de la raquette


Niv. 1

La raquette est un composant, on va donc trouver la scène qui lui est
dédiée dans le dossier "composants/objets/raquette".
La scène est le fichier ".tscn" dans le dossier.

- Prérequis
	- Aucun

- Actions
    - Double-cliquer sur le fichier "raquette.tscn" pour ouvrir la
        scène de la raquette.


La scène de la raquette est composée de 3 nœuds :
- Un nœud StaticBody2D,
- Un nœud Sprite2D,
- Un nœud CollisionShape2D.
C'est le nœud Sprite2D, dénommé "image", qui va permettre
l'affichage de l'image de la raquette.


- Actions
    - Cliquer sur le nœud "image".


Dans l'Inspecteur, on peut voir le champs "Texture". C'est le
contenu de ce champ qu'il faut modifier pour changer l'image de la
raquette dans le jeu.

La belle image pour votre raquette est disponible dans `composants/objets/raquette/sprite.png`.


- Actions
    - Pour modifier l'image, cliquer sur la flèche qui pointe vers le
        bas dans le champs "Texture" et choisir "Charger" pour
        pouvoir importer votre image.

- [ ] J'ai changé l'image de la raquette !
- Suite
	- [Changer la couleur de la raquette](#changer-la-couleur-de-la-raquette)


## Changer la couleur de la raquette



Niv. 1

- Prérequis
	- [Changer l’image de la raquette](#changer-limage-de-la-raquette)

- Actions
    - Double-cliquer sur le fichier "raquette.tscn" pour ouvrir la
        scène de la raquette.


C'est le nœud Sprite2D, dénommé "image", qui va permettre de changer
la couleur de la raquette.


- Actions
    - Cliquer sur le nœud "image".


Dans l'Inspecteur, dans la section "Visibility", on peut voir le
champs "Self-Modulate". C'est le contenu de ce champ qu'il faut
modifier pour changer la couleur de la raquette dans le jeu.


- Actions
    - Cliquer sur le rectangle blanc pour accéder à la palette de
        couleurs.
    - Choisir une couleur.
    - Cliquer en dehors de la fenêtre du nuancier pour la faire
        disparaître et valider la couleur choisie.


> Note : vous pouvez aussi changer la valeur du champ "Modulate" du
nœud racine `StaticBody2D`, ce qui change la couleur de tous les
enfants, y compris l'image.

- [ ] J'ai fait cette étape.
- Suite
	- Continuer l'initiation : [Avoir un nombre limité de balles](#avoir-un-nombre-limité-de-balles)


## Avoir un nombre limité de balles



Niv. 2

Ne plus avoir de balles, c'est comme ne plus avoir de vies :
si ça arrive, la partie est perdue !


- Actions
    - Ouvrir le script du lanceur.
    - Dé-commenter le code qui permet de configurer le nombre de balles
        via l'éditeur :
		- `@export_range(1, 10) var nombre_de_balles: int = 3`
    - Compléter la fonction "_decrementer_nombre_de_balles() ->
        void".
        - Qui soustrait 1 au nombre de balles.
    - Modifier la fonction "lancer_balle".
        - Rajouter un test, s'il n'y a plus de balle, arrêter la
            fonction avec le mot-clef "return".

> Attention ! Pour faire une comparaison d'égalité, il faut
utiliser l'opérateur `==` ! L'opérateur `=` permet d'assigner
une valeur à une variable.

> Note : "return" interrompt une fonction.

> Astuce : afficher le nombre de balles après chaque
	décrémentation avec une fonction `print()`

- [ ] J'ai fait cette étape.
- Suite
	- Continuer l'initiation : [Afficher le compteur de balles](#afficher-le-compteur-de-balles)


## Afficher le compteur de balles



Niv. 2

N'hésitez pas à lire l'explication sur les signaux si besoin !


- Actions
    - Dé-commenter la déclaration du signal `nb_balles_change` dans la scène du lanceur.
        - Émettez le signal dans l'appel `_decrementer_nombre_de_balles()`.
    - Ajouter la scène `Stock` dans un niveau, qui se trouve dans `composants/interface`
    - Brancher le signal du  lanceur du niveau vers le compteur/label.
        - Répéter le branchement pour chaque niveau.

> Note : Le signal possède une méthode `emit`, qui permet d'émettre le signal.

> Attention : Si le label renvoie une erreur : "Cannot convert argument 1 from int to String.", cela veut juste dire qu'il faut convertir la valeur de `nombre_de_balles` en String avant d'émettre le signal.

- [ ] J'ai fait cette étape.
- Suite
	- Continuer l'initiation : [Afficher un écran de game over](#afficher-un-écran-de-game-over)
	- Pour les expert·es : [Afficher une jauge de balles](#afficher-une-jauge-de-balles)

### Explications : les signaux

Mécanique idéale pour faire communiquer des nœuds entre eux. Les signaux
permettent d'envoyer des messages à zéro, un ou plusieurs destinataires
en même temps. À chaque émission de signal correspond l'exécution
d'une fonction pour tous les nœuds connectés à ce signal. Les nœuds de
la bibliothèque offrent des signaux et des fonctions déjà utilisables,
et il est possible d'en créer dans nos scripts.

Il est recommandé d'utiliser le plus possible les signaux, afin de minimiser
les dépendances entre vos nœuds et scripts. Cela facilitera l'organisation
de votre code. Vos collègues ou le futur vous-même vous remerciera !

- Pas à pas :
        <https://docs.godotengine.org/fr/4.x/getting_started/step_by_step/signals.html>
    - Utiliser un signal dans un script :
        <https://docs.godotengine.org/fr/4.x/tutorials/scripting/gdscript/gdscript_basics.html#signals>
    - Référence :
        <https://docs.godotengine.org/fr/4.x/classes/class_signal.html>


## Afficher un écran de game over



Niv. 1


- Action
    - Ajouter un signal "partie_perdu" dans la scène du
        lanceur. Ce sera un signal brut, sans argument.
    - L'émettre quand il n'y a plus de balle (fonction
        `lancer_balle()`).
    - Brancher dans chaque niveau :
        - Le signal partie_perdue du lanceur vers le nœud "Message"
            et sa fonction `show()`. C'est une fonction Godot, vous
			devez décocher "Scripts Methods Only" pour voir cette méthode.
        - Le signal partie_perdue du lanceur vers le nœud
            "Message/Perdu" et sa fonction `show()`.

![Brancher un signal a une methode Godot](img/editor_signal_decocher_methodes_script_seulement.png).

- [ ] J'ai fait cette étape.
- Suite
	- Étape bonus : [Afficher un écran de victoire](#afficher-un-écran-de-victoire)
	- Continuer l'initiation : [Faire accélérer la balle](#faire-accélérer-la-balle)


## Afficher un écran de victoire

Niv. 3 : beaucoup d'étapes


- Actions
    - S'inspirer de la scène game over `perdu.tscn` pour créer la scène de
        victoire.
    - Comprendre la logique de comptage des briques -> code à
        dé-commenter dans `conteneur_briques.gd`
    - Afficher le message dans chaque niveau
        - Ajouter votre nouvelle scène en tant que nœud enfant de
            Message
        - Brancher le signal aux bonnes fonctions (montrer écran +
            détruire lanceur).


> Note : comme les balles créées par le lanceur sont des nœuds enfants,
détruire le lanceur détruit aussi toutes les balles.

- [ ] J'ai fait cette étape.
- Suite
	- Continuer l'initiation : [Faire accélérer la balle](#faire-accélérer-la-balle)


## Faire accélérer la balle


Niv. 2


- Prérequis
	- [Avoir un nombre limité de balles](#avoir-un-nombre-limité-de-balles)
- Actions
    - Créer, dans le script de la balle, une constante :
        "acceleration_par_touche: float = 50.0 # px / sec / touche"
    - Modifier la fonction "_accelerer" qui augmente la vitesse de
        la balle quand elle est appelée.
        - Utiliser la constante précédente pour modifier la propriété
            vitesse de la balle.
        - Pour appliquer la nouvelle vitesse, vous devez aussi appeler
            la fonction "_mettre_mouvement".
    - Alternative 1 : accélérer à chaque touche de raquette.
        - Dans "_physics_process" : Appeler "_accelerer" après
            chaque rebond sur une raquette.
        - Note : 50 px / sec / touche c'est bien pour avoir un bon
            challenge.
    - Alternative 2 : accélérer à chaque rebond.
        - Dans "_physics_process" : Appeler "_accelerer" après
            chaque rebond.
        - Note : 10 px / sec / touche c'est bien pour avoir un bon
            challenge.

> Conventions : les fonctions et variables considérées internes à votre
votre script sont préfixées par un trait bas `_`. Elles sont dites *privées*.
Cela donne une indication de qui a le droit d'utiliser cette donnée, facilitant
la lecture et la maintenance du code.
Par exemple, `_vitesse` est une variable privée ; seule la balle elle-même
a le droit de la modifier, car c'est sa responsabilité.

- [ ] J'ai fait cette étape.
- Suite
	- [Le carrefour Godot](#le-carrefour-godot)

### Explications : les fonctions virtuelles Godot

Certaines méthodes préfixées par `_` sont des fonctions que Godot connaît
et qu'il peut appeler pour vous donner le contrôle à certains moments.

La méthode `_ready()` est appelée après que votre nœud soit entré en scène,
et dès tous ses enfants sont prêts (c'est à dire que la fonction _ready() a
été appelée pour chaque enfant). Cette méthode est présente dans de nombreux scripts pour
préparer un nœud.


La méthode `_process` est appelée avant le rendu de chaque image. Cette méthode
peut être utilisée pour coder la logique de votre jeu (gagner des points ou de la vie
par exemple) ou pour modifier l'apparence de votre nœud (changer la couleur de votre objet au fil du temps).
Par défaut, cette fonction est appelée 60 fois par seconde, mais dépend de la fréquence de rafraîchissement
de votre écran.

La méthode `_physics_process` est appelée à chaque fois que Godot résoud
les calculs physiques permettant de déplacer vos objets. Cette fonction est importante
pour appliquer des forces ou déplacer vos objets.
Par défaut, cette fonction est appelée 50 fois par seconde, mais cela peut se paramétrer.

> Note : les fonctions `_process` et `_physics_process` reçoivent un nombre à virgules, `delta: float`,
qui représente le nombre de secondes depuis la dernière fois ou la fonction est appelée. Dans l'idéal,
ce nombre est très souvent fixe, mais il peut varier selon la performance de l'appareil. Il faut donc le prendre en compte
pour vos calculs liés au temps. Par exemple, si un objet se déplace à 40 pixels par seconde, on écrira :

```gd
func _physics_process(delta: float) -> void:
	position.x += 40.0 * delta
```

Enfin, la méthode `_unhandled_input()` est appelée quand un périphérique est actionné :
quand une touche de clavier est enfoncée, quand la souris a bougé, un joystick de manette s'est déplacé,
quand un bouton de manette est relâché. Elle prend un argument qui décrit l'événement qui a eu lieu.

> Note : la fonction `_input()` existe aussi, mais préférez `_unhandled_input` qui appelée seulement si
l'événement n'a pas déjà été consommé par un autre nœud.

Il existe d'autres méthodes virtuelles exposées par Godot, mais vous connaissez maintenant les plus
utiles.

## Le carrefour Godot

Bravo pour avoir terminé votre parcours initiatique !

Bienvenue au carrefour où attendent Vladimir et Estragon. N'attendez pas Godot, partez à sa recherche !

- [ ] Parcours [artisan artiste](#insérer-une-musique-dans-un-niveau)
- [ ] Parcours [artisan maçon](#pouvoir-configurer-le-nombre-de-vies-dune-brique)
- [ ] Parcours [super artisan](#pouvoir-de-ralentissement)
- [ ] Parcours [artisan facteur](#exporter-le-jeu-au-format-linux)

> Note : vous repasserez probablement par ici plus tard ; n'hésitez pas à cocher les parcours que vous avez déjà faits !


## Insérer une musique dans un niveau



Niv. 1

Les AudioStreamPlayer sont les nœuds permettant de jouer des sons, on
peut les intégrer dans tout types de scènes et les manipuler avec des
fonctions simples comme play() ou stop() par exemple. Il existe 3
AudioStreamPlayer, le simple (stéréo), l'AudioStreamPlayer2D (qui gère
l'audio positionnel en 2 dimensions) et l'AudioStreamPlayer3D (audio
positionnel en 3 dimensions).


- Actions
    - Ajouter un nœud AudioStreamplayer dans la scène de niveau.
    - Charger la musique voulue dans le champs "Stream" de
        l'AudioStreamPlayer dans l'inspecteur. Des musiques
		sont disponibles dans le dossier `ressources/musiques`.
    - Bien penser à cocher `loop` pour les musiques importées !
    - Dans le champs Bus dans l'inspecteur, sélectionner : Musique
    - Cocher le champs "Autoplay".
    - Enfin dans la section "Process" changer le champs "Mode"
        pour la valeur "Always" (sinon la musique se mettra en pause
        lors de l'affichage du menu pause.)
- Référence
    - Le nœud AudioStreamPlayer :
        <https://docs.godotengine.org/fr/4.x/classes/class_audiostreamplayer.html>
- [ ] J'ai fait cette étape.
- Suite
	- Continuer : [Faire un bruit au game over](#faire-un-bruit-au-game-over)
	- Étape bonus : [Faire un bruit au clic sur bouton début](#faire-un-bruit-au-clic-sur-bouton-début)

## Faire un bruit au clic sur bouton début



Niv. 2


- Actions
    - Ajout du son de clic bouton dans le Menu Pause :
        - Ajouter un AudioStreamPlayer dans la scène
            "pause_menu.tscn"
        - Nommer l'AudioStreamPlayer : *SonClic*.
        - Charger le son de clic dans le champs "Stream" de
            l'AudioStreamPlayer : `composants/interface/clic_sfx.wav`
        - Dans le champs Bus dans l'inspecteur, sélectionner : Bruits
		- Choix 1 : Brancher les signaux `pressed` de chaque bouton à la fonction
			interne `play` de l'AudioStreamPlayer.
        - Choix 2 : Ajouter `$SonClic.play()` dans les
            fonctions `_quand_bouton_reprendre_est_presse()`,
            `_quand_bouton_retour_titre_est_presse()` et
            `_quand_bouton_quitter_est_presse()` du script
            `pause_menu.gd`.
    - Ajout du son de clic bouton sur les planètes du Menu Principal :
        - Ajouter un AudioStreamPlayer dans la scène
            `choix_niveau.tscn` en enfant du nœud
            *DefilementNiveaux*.
        - Nommer l'AudioStreamPlayer : *SonClic*.
        - Charger le son de clic dans le champs "Stream" de
            l'AudioStreamPlayer.
        - Dans le champs Bus dans l'inspecteur, sélectionner : Bruits
		- Choix 1 : Brancher les signaux `pressed` de chaque bouton planète
			à la fonction `play` de *SonClic*
        - Choix 2 : Clic droit sur le nœud *SonClic* puis "% Access as Unique Name".
			Puis ajouter `%SonClic.play()`
            dans la fonction `_quand_planete_est_cliquee()` dans
            le script `planete.gd`.
- [ ] J'ai fait cette étape.
- Suite
	- Continuer : [Faire un bruit au game over](#faire-un-bruit-au-game-over)



## Faire un bruit au game over



Niv. 1


- Prérequis
    - Scène de partie perdu : "perdu.tscn".
- Actions
    - Ajouter un nœud AudioStreamPlayer dans la scène "perdu.tscn".
    - Charger le son de partie perdu (game over) dans le champs
        "Stream" de l'AudioStreamPlayer.
    - Dans le champs Bus dans l'inspecteur, sélectionner : Bruits
    - Brancher le signal "visibility_changed()" du nœud "OhNon" ou du nœud "CommandeRetour" sur la fonction play() de l'AudioStreamPlayer.
		- Note : si vous ne voyez pas la fonction play, ecrivez son nom.
- [ ] J'ai fait cette étape.
- Suite
	- [Faire un bruit à l’impact d’une balle](#faire-un-bruit-à-limpact-dune-balle)


## Faire un bruit à l'impact d'une balle



Niv 1


- Prérequis
    - La brique fait un bruit en explosant
    - La balle avec un signal rebondi
- Actions
    - Ajouter le nœud AudioStreamPlayer dans la scene balle.
    - Charger le son "collision_sfx.wav" dans le champs "Stream"
        de l'AudioStreamPlayer dans l'inspecteur.
    - Brancher le signal  "rebondi" de la balle à la fonction play()
        de l'AudioStreamPlayer.
    - Dans l'inspecteur de l'AudioStreamPlayer affecter le champs
        "Bus" au bus : Bruits

- [ ] J'ai fait cette étape.
- Suite
	- Parcours [artisan artiste graphique](#faire-une-trainée-à-la-balle)
	- Parcours [artisan artiste audio](#effet-audio-dynamique-sur-le-menu-pause)


## Faire une trainée à la balle



Niv. 3


- Actions
    - Trouvez le composant balle, ouvrez la scène qui se trouve dans
        le dossier.
    - Ajouter un GPUParticle2D dans la scène.
    - Dans l'inspecteur, remplir le champs "Texture" avec le png
        fournie dans le dossier "effets/trainee".
    - Toujours dans l'inspecteur, ajouter un nouveau "Particule
        Process Material" dans le champs "Process Material".
- Ressources
    - Texture de particule dans le dossier balle.
- Doc
    - Pas à pas :
        <https://docs.godotengine.org/fr/4.x/tutorials/2d/particle_systems_2d.html>
    - Référence (documentation brute) :
        <https://docs.godotengine.org/fr/4.x/classes/class_gpuparticles2d.html>


> Note : GPU signifie Graphical Process Unit, cela signifie que les
particules sont calculées avec le processeur graphique. Il est
préférable de l'utiliser car plus performant ; cependant ça ne marche
pas sur toutes les machines. Auquel cas, on utilisera CPUParticles2D
(<https://docs.godotengine.org/fr/4.x/classes/class_cpuparticles2d.html#class-cpuparticles2d)>.

- [ ] J'ai fait cette étape.
- Suite
	- [Effet impact d’une balle](#effet-impact-dune-balle)

## Effet impact d'une balle



Niv. 3


- Image : capture paramétrage effet de particule dans Kace
- Actions
    - Créer un nouvel effet
        - Dans le dossier "effet/impact", créer une nouvelle scène.
        - Racine : Node2D / Enfant : GPUParticles2D.
        - Configurer l'effet de particules en one shot dans
            l'Inspecteur.
        - Supprimer le nœud une fois que l'effet de particule est
            terminer via un signal.
    - Créer l'effet
        - S'inspirer de l'effet d'éclatement de la brique pour
            l'invocation de la scène d'impact dans le script
            "brique.gd".
            - const EclatementScene: PackedScene =
                preload("res://effets/eclatement_brique/eclatement_effet.tscn").
        - Instancier la scène et l'ajouter à l'arbre au moment du
            rebond dans le script de la balle.

- [ ] J'ai fait cette étape.
- Suite
	- Parcours [artisan artiste audio](#effet-audio-dynamique-sur-le-menu-pause)
	- Retour au [carrefour Godot](#le-carrefour-godot)


## Effet audio dynamique sur le menu pause



Niv. 3

Il faut ici passer par un peu de script pour piloter le bus "Musique"
et activer l'un de ses effets.


- Actions
    - Ajouter un effet "LowPassFilter" sur le bus "Musique" et
        laisser ses réglages par défaut.
    - Désactiver l'effet dans le bus (case à décocher) pour que
        l'effet soit éteint au démarrage du jeu.
    - Ouvrir la scène "pause_menu.tscn" et passer la vue en mode
        script.
    - Repérer dans le script "pause_menu.gd" la fonction
        "_unhandled_input(event: InputEvent)" et ajouter dans le
        "else" de l'embranchement :
        "AudioServer.set_bus_effect_enabled(2,1, true)"  pour
        activer le "LowPassFilter" à l'apparition du menu pause.
    - Repérer dans le script "pause_menu.gd" la fonction
        "reprendre()" et ajouter
        "AudioServer.set_bus_effect_enabled(2,1, false)" pour
        désactiver l'effet quand le menu pause se ferme.
- Documentation
    - [Manipuler les bus audio avec la classe AudioServer](https://docs.godotengine.org/fr/4.x/classes/class_audioserver.html#class-audioserver-method-set-bus-effect-enabled)
- [ ] J'ai fait cette étape.
- Suite
	- [Effet audio dynamique : diminuer l’importance de la musique quand un effet sonore joue](#effet-audio-dynamique-diminuer-limportance-de-la-musique-quand-un-effet-sonore-joue)





## Effet audio dynamique : diminuer l'importance de la musique quand un effet sonore joue



Niv. 2

Les bus audio sont des "tubes virtuels" dans lesquels on fait passer
les flux audio. Ils sont visibles dans l'onglet "Audio" du panneau
inférieur de l'éditeur. Par défaut il n'existe qu'un bus dit
"Master" à l'intérieur duquel le son circule de haut en bas, passant
du contrôleur de volume, aux effets éventuels pour finir par sortir via
vos hauts-parleurs. De nouveaux bus peuvent être ajoutés facilement pour
contenir les musiques, les effets sonores, les voix, etc et leur
appliquer des traitements dédiés.

Le compresseur est un effet audio complexe a utilisé qui sert à établir
un plancher au-dela duquel le volume sonore du son augmentera moins ou
plus du tout. Cela va permettre ici de faire perdre en définition la
musique quand les effets sonores sont joués afin que le joueur/la
joueuse dispose toujours des informations audio nécessaires pour jouer
dans de bonnes conditions et que la musique ne couvre jamais les effets
sonores.


- Prérequis
    - Avoir deux bus, un bus "Bruits" pour les effets sonores et un
        bus "Musique" pour la musique.
- Actions
    - Ajouter un effet "Compressor" (compresseur) dans le bus
        "Musique".
    - Régler les paramètres du compresseur dans l'Inspecteur comme
        suit :
        - "Threshold" (seuil de décibel à partir duquel l'effet
            s'active) : -17.
        - "Ratio" (ratio de diminution du volume du son quand le
            compresseur est actif) : 1.8.
        - "Release" (temps pendant lequel le compresseur reste actif
            une fois le volume du son revenu sous le seuil) : 50 ms.

En l'état le compresseur s'active et agit quand le contenu du bus
"Musique" voit son volume passer au-dessus du "Treshold". Il faut
changer cela, car on veut que le compresseur s'active quand les effets
sonores joues (contenu du bus "Bruits").

- Dans le champs "Sidechain" sélectionner le bus "Bruits",
    cela va permettre au compresseur de s'activer quand le
    contenu du bus Bruits dépassera le seuil, cependant le
    compresseur agira toujours sur le contenu du bus
    "Musique". Ainsi la musique passera légèrement en fond
    quand les effets sonores seront joués.


- [ ] J'ai fait cette étape.
- Suite
	- Parcours [artisan artiste graphique](#faire-une-trainée-à-la-balle) (si vous ne l'avez pas déjà fait)
	- Retour au [carrefour Godot](#le-carrefour-godot)


## Pouvoir configurer le nombre de vies d'une brique



Niv. 3


- Actions
    - Modifier "brique.gd" comme suit :
        - Dé-commenter la constante "NOMBRE_DE_VIES_MAX".
        - Dé-commenter la variable "nombre_de_vies".
        - Modifier la fonction "frapper" pour réduire les points de
            vie, et ne mourir que s'il n'en reste plus.
        - Dé-commenter "_montrer_nombre_de_vies" et la fonction
            qui l'appelle.
    - Modifier les niveaux pour ajuster la vie.
        - Ouvrir le niveau carré simple.
            - Mettre 4 vies au bloc central.
                - Astuce : vous pouvez sélectionner plusieurs briques
                    en les sélectionnant.
                - La propriété nombre de vies est visible dans
                    l'éditeur grâce au préfixe "@export".


> Note : quand vous modifiez la vie dans l'éditeur, sa couleur change en
direct ! Cela est possible grâce à l'annotation "@tool" en haut du
script, qui permet de faire fonctionner le script dans l'éditeur (à
utiliser avec précaution) ; et la méthode "set_nombre_de_vies",
utilisée pour modifier le nombre de vie (set = set_nombre_de_vies),
qui rafraichit la couleur de la brique dès que le nombre de points de
vie est modifié.

- [ ] J'ai fait cette étape.
- Suite
	- [Changer la couleur de la brique en fonction de sa vie](#changer-la-couleur-de-la-brique-en-fonction-de-sa-vie)


## Changer la couleur de la brique en fonction de sa vie



Niv. 2

Il y a déjà un dégradé de noir grâce à l'étape précédente.

Alternatif : Essayer de modifier la fonction "_montrer_nombre_vies"
le script "brique.gd" de la scène "brique.tscn" pour faire un
dégradé vers le rouge à la place.


- Prérequis
    - La brique a des vies
- Actions
    - Chercher le dossier contenant les composants de la brique.
    - Dé-commenter le code en rapport avec la vie de la brique dans le
        script "brique.gd".


> Note : Le script a comme première instruction @tool : cela signifie
qu'il s'exécute aussi dans l'éditeur. Cela permet de voir le
changement de couleur aussi dans l'éditeur lorsque vous fabriquez un
niveau.

- [ ] J'ai fait cette étape.
- Suite
	- [Faire descendre les briques au fil du temps](#faire-descendre-les-briques-au-fil-du-temps)

## Faire descendre les briques au fil du temps



Niv. 2

Complètement facultatif.


- Actions
    - Créer un script qui hérite de "ConteneurDeBriques".
    - Créer une constante vitesse_de_descente := 5.0 # px/sec.
    - Appliquer la descente à chaque image (frame) via la fonction
        "_physics_process".
- [ ] J'ai fait cette étape.
- Suite
	- [Faire perdre la partie si une brique sort du terrain](#faire-perdre-la-partie-si-une-brique-sort-du-terrain)



## Faire perdre la partie si une brique sort du terrain



Niv. 4


- Prérequis
    - Les briques descendent au fil du temps.
- Actions
    - Modifier l'arène pour que la zone du bas, appelée
        ZoneExterieure, détecte les collisions avec les briques
        (collision_layer: mask)
    - Faire en sorte que l'arène envoie un signal quand une brique
        est détectée par la zone extérieure
    - Relier ce signal au même signal que le game over classique

- [ ] J'ai fait cette étape.
- Suite
	- Retour [au carrefour Godot](#le-carrefour-godot)
	- Pour les expert·es : [Faire un obstacle avec une nouvelle forme](#faire-un-obstacle-avec-une-nouvelle-forme)



## Pouvoir de ralentissement



Niv. 3


- Prérequis
    - Capsule qui permet de libérer un pouvoir contenu dans une
        brique.
- Actions
    - Ajouter un frein sur la balle.
        - Ajouter la balle dans le "groupe_des_balles".
            - Voir : Avoir un nombre de vies limité.
        - Dé-commenter la méthode "ralentir".
    - Créer un nouveau pouvoir.
        - Copier le script "bonjour_pouvoir.gd" et le renommer en
            "pouvoir_ralentir.gd".
            - Changer le nom de la classe en "RalentirPouvoir".
        - Choisir la couleur en modifiant la valeur retournée par
            "couleur_principale" (exemple : Color.WEB_GREEN).
        - Dans "association_pouvoirs.gd" :
            - Ajouter le type de pouvoir dans l'énumération "Type".
            - Associer votre script dans la fonction statique
                "fabriquer".
        - Facultatif : associer une texture de brique pour un type de
            pouvoir :
            - les textures possibles sont dans le dossier
                "composants/objets/brique/images/".
            - L'association est faite dans la méthode
                "_associe_texture_brique" dans "brique.gd".
        - Associer votre nouveau pouvoir à une brique dans un niveau.
        - Écrire l'effet du pouvoir dans "declencher_pouvoir".
    - Écrire l'effet du pouvoir dans "declencher_pouvoir" :
        - Renommer l'argument "_arbre_scene" en "arbre_scene".
        - Pour toutes les balles, appeler la méthode
            "ralentir(3.0)".
            - À l'intérieur écrire une boucle "for", comme suit :
                "for balle in
                arbre_scene.get_nodes_in_group("groupe_des_balles"):"
- Note : le pouvoir est fabriqué au moment où la capsule est libérée,
    quand la brique est détruite.
- Note : préfixer un argument par "_" permet de dire à Godot que
    c'est normal que l'argument ne soit pas utilisé.
- Documentation
    - Un vecteur normalisé a une longueur de 1 :
        <https://docs.godotengine.org/fr/4.x/classes/class_vector2.html#class-vector2-method-normalized>
    - Référence arbre des nœuds :
        <https://docs.godotengine.org/fr/4.x/classes/class_scenetree.html>
    - Explication détaillée du fonctionnement de l'arbre des nœuds :
        <https://docs.godotengine.org/fr/4.x/tutorials/scripting/scene_tree.html>


- [ ] J'ai fait cette étape.
- Suite
	- Continuer parcours [super artisan](#pouvoir-de-vieballes-supplémentaires)
	- Parcours bonus [pour rendre la récup de pouvoir plus juteuse](#bruit-lorsquun-pouvoir-est-récupéré) 
	- Pour les expert·es : [Compter et afficher le score](#compter-et-afficher-le-score)


## Bruit lorsqu'un pouvoir est récupéré



Niv. 1


- Prérequis
    - Capsule implémentée
- Actions
    - Possibilité 1 : signal
        - Ajouter un signal "capsule_recuperee"
        - Émettre le signal
        - Ajouter nœud AudioStreamPlayer
        - Brancher le signal sur la fonction play() de
            l'AudioStreamPlayer
    - Alternative 2 : son spatialisé -> effet graphique de récupération
        de pouvoir
        - Créer un effet : Créer un nouveau dossier "recup_pouvoir"
            dans le dossier "effets"
        - Instancier un AudioStreamPlayer2D depuis le code (même
            emplacement que le signal possibilité 1)
- [ ] J'ai fait cette étape.
- Suite
	- Continuer parcours [super artisan](#pouvoir-de-vieballes-supplémentaires)
	- Continuer parcours bonus : [Afficher le nom du pouvoir lorsqu’il est récupéré](#afficher-le-nom-du-pouvoir-lorsquil-est-récupéré)


## Afficher le nom du pouvoir lorsqu'il est récupéré


Niv. 3


- Actions
	- Créer une scène UI (cercle vert) `grande_notif.tscn`
		- Ajouter un nœud enfant label
		- Mettre un texte de test "nom pouvoir"
		- Agrandissez le texte
	- Modifier la capsule
		- preload() cette scène dans `capsule.gd`
		- Lorsque le pouvoir est déclenché, instancier votre scène `grande_notif.tscn`, modifier son texte, puis l'ajouter à l'arbre de scène
	- Vous pouvez tester l'apparition du texte (qui est toujours pareil !)
	- Pour faire disparaître le texte au bout d'un moment
		- Créer un script dans le nœud racine de `grande_notif.tscn` et utiliser un timer qui démarre dans la fonction `_ready()` de `grande_notif.gd`
		- Faire en sorte qu'à la fin du timer la méthode `queue_free` soit appelée
	- Pour afficher le nom du pouvoir récupéré
		- Dans `base_pouvoir.gd`, ajouter une méthode `nom_pouvoir()` qui retourne "Pouvoir inconnu"
		- Dans chaque pouvoir qui hérite de `PouvoirBase`, ajouter une méthode `nom_pouvoir()` qui retourne le nom de ce pouvoir en particulier
		- Dans le script `grande_notif.gd`, exposez une méthode publique qui permet de modifier la propriété `text` du label
		- Dans `capsule.gd`, modifier le texte de la notif avec le nom du pouvoir avant de l'ajouter à l'arbre de scène

> Note : lorsque l'on appelle la méthode `VieBonus.nom_pouvoir()`, la méthode `PouvoirBase.nom_pouvoir()` n'est pas appelée. Cette mécanique s'appelle la surcharge.

- [ ] J'ai fait cette étape.
- Suite
	- Continuer parcours [super artisan](#pouvoir-de-vieballes-supplémentaires)
	- Continuer parcours bonus : [Effet de récupération de pouvoir](#effet-de-récupération-de-pouvoir)


## Effet de récupération de pouvoir



Niv. 4


- Prérequis
    - Scène pour l'effet de récup : Bruit lors de récupération d'un
        pouvoir, alternative 2
- Ressources
    - Animation de récupération de pouvoir
- Actions
    - Ajouter un nœud AnimatedSprite2D à la scène `recup_pouvoir`
        dans le dossier `effets`
    - Attention : il ne faut détruire la scène avec queue_free quand
        le son et l'animation sont terminées !
- Documentation
    - [Référence AnimatedSprite2D][https://docs.godotengine.org/fr/4.x/classes/class_animatedsprite2d.html]

- [ ] J'ai fait cette étape.
- Suite
	- Continuer parcours [super artisan](#pouvoir-de-vieballes-supplémentaires)



## Pouvoir de vie/balles supplémentaires



Niv. 3


- Prérequis
    - Pouvoir existant.
    - Affichage du nombre de balles restante.
- Actions
    - Ajouter la fonction "incrementer_nombre_de_balles" dans le
        lanceur.
        - N'oubliez pas d'émettre le signal "nb_balles_change" !
    - Cliquer sur le nœud "Lanceur" dans un niveau, puis dans
        l'onglet nœud → groupes, l'ajouter au
        "groupe_des_lanceurs"
        - Voir l'image qui montre comment ajouter au groupe des lanceurs
    - En déclenchant le pouvoir, récupérer le lanceur via son groupe,
        et appeler la fonction "incrementer_nombre_de_balles".
        - Utiliser la fonction "get_first_node_in_group()".
- Documentation
    - Référence pour récupérer un nœud d'un groupe :
        <https://docs.godotengine.org/fr/4.x/classes/class_scenetree.html#class-scenetree-method-get-first-node-in-group>

![Capture de l'ajout du groupe des lanceurs](img/editor_gd4_raquette_ajout_groupe_des_lanceurs.png)


- [ ] J'ai fait cette étape.
- Suite
	- [Pouvoir de feu](#pouvoir-de-feu)


## Pouvoir de feu



Niv. 3

Ici, lorsque le pouvoir sera activé, la (ou les) balle sera transformée
en balle de feu. Cela signifie qu'il y a une scène dédiée à la balle de
feu, qui existe et que vous pouvez regarder.


- Prérequis
	- [Pouvoir configurer le nombre de vies d’une brique](#pouvoir-configurer-le-nombre-de-vies-dune-brique)
- S'inspirer du pouvoir de ralentissement pour faire le pouvoir
    - Nom classe : "PouvoirFeu".
    - Couleur : "Color.RED".
- Actions
    - Déclenchement du pouvoir : comme pour le ralentissement, le
        pouvoir doit être effectué sur toutes les balles.
    - Appeler la méthode statique "BalleDeFeu.transformer(balle)".


> Note : une méthode statique est une fonction qui peut être appelée sans
avoir à créer l'objet associé.

- [ ] J'ai fait cette étape.
- Suite
	- Bonus de style : [Effet de flamme](#effet-de-flamme)
	- [Pouvoir électrique](#pouvoir-électrique)
	- Pour les expert·es : [Pouvoir agrandissement raquette](#pouvoir-agrandissement-raquette)

## Effet de flamme



Niv. 3


- Action : modifier balle_de_feu.tscn
    - Change l'image de la balle
        - 02.png
        - Reset les propriétés modulate et scale
        - Tester
    - Diriger la balle en fonction de la direction
        - Ajouter une fonction "_diriger" qui met à jour
            l'orientation de la balle quand on l'appelle
            - Utiliser la méthode angle_to pour récupérer l'angle,
                par rapport à une constante de Vector2 (Vector2.UP si la
                balle va vers le haut, Vector2.RIGHT si elle va vers la
                droite).
            - Modifier la rotation de l'image (propriété rotation)
        - Appeler la fonction _diriger quand la balle se met en
            mouvement
            - dé-commenter le code
        - Appeler la aussi quand elle rebondit
            - idem pour _rebondir que _mettre_en_mouvement
        - Tester
    - Clignoter : Changer la valeur de flip_h de l'image à
        intervalle régulier
        - Utiliser $Image pour récupérer le nœud qui s'appelle
        - Utiliser une variable globale pour compter le temps (ajouter
            delta à chaque frame)
        - Utiliser une constante pour la durée du clignotement
        - Pour calculer votre clignotement à chaque image, mettez
            votre code dans la fonction _process
- Doc
    - [Réf AnimatedSprite2D#flip_v](https://docs.godotengine.org/fr/4.x/classes/class_sprite2d.html#class-sprite2d-property-flip-v)


> Note pour améliorer la performance : stocker la référence vers le nœud
dans une variable pour éviter de demander à Godot de chercher le nœud à
chaque fois.
`@onready image : Sprite2D = $Image`

- [ ] J'ai fait cette étape.
- Suite
	- [Pouvoir électrique](#pouvoir-électrique)
	


## Pouvoir électrique

Niv. 4

La balle électrique possède une zone d'influence qui détruit les
briques à distance.


- Dépend de laser
- Prérequis
    - Image de la balle électrique (animée dans un autre chapitre)
- Actions
    - Copier la scène balle de feu.
    - Le pouvoir électrique va fonctionner de manière analogue au
        pouvoir de feu : lorsqu'il est déclenché, toutes les balles
        sont transformée
    - La balle électrique contient une Area2D qui va scanner les
        briques, et leur mettre des dégâts
    - Bonus : rajouter un délai entre le moment où la zone électrique
        touche une brique et le moment où celle-ci subit le dégât
- Docs
    - [Référence nœud Timer](https://docs.godotengine.org/fr/4.x/classes/class_timer.html)
    - [Référence timer sans nœud](https://docs.godotengine.org/fr/4.x/classes/class_scenetree.html#class-scenetree-method-create-timer)
- [ ] J'ai fait cette étape.
- Suite
	- Bonus de style : [Effet électrique](#effet-électrique)
	- [Pouvoir laser](#pouvoir-laser)


## Effet électrique



Niv. 4


- Prérequis
    - Pouvoir éclair
- Ressources
    - Texture de balle éclair
- Actions
    - Associer l'image éclair au Sprite2D
    - S'inspirer de l'effet de flamme pour alterner les valeurs de
        frame, flip_h et flip_v à intervalles réguliers.
    - Mode expert : alterner aussi avec une seconde image
- Doc
    - [Référence : AnimatedSprite2D](https://docs.godotengine.org/fr/4.x/classes/class_sprite2d.html)
- [ ] J'ai fait cette étape.
- Suite
	- [Pouvoir laser](#pouvoir-laser)



## Pouvoir laser

Niv. 4


Permet à la raquette de lancer un javelot à haute énergie qui détruit tout sur son passage !


- Prérequis
    - Assets graphiques javelot
- Actions
    - Créer le javelot dans le dossier `javelot`
        - La racine de la scène est un `Node2D`
        - Ajouter l'image du javelot `mcJavelot.png`
        - Utiliser une `Area2D` pour déterminer la zone de destruction
            - Donner lui une forme en ajoutant un enfant `CollisionShape2D`
            - Définir une forme carrée au sommet de la flèche
        - Coder le comportement du javelot
            - Attachez un nouveau script au javelot
                - Monter le javelot à chaque image
                    - Pensez à utiliser l'argument `delta` de `physics_process`
                - Créer une fonction `_quand_corps_entre_dans_zone_destructive`
                    - La fonction prend en argument un `corps: Node2D`
                    - Brancher le signal `body_entered` de la zone de destruction à cette fonction
                    - Si le corps est une brique, frapper là !
    - Auto-détruire le javelot lorsqu'il sort de l'écran
        - Ajouter le nœud `VisibleOnScreenNotifier2D`
        - Brancher le signal `screen_exited` à la méthode `queue_free()` du nœud racine
    - Faire un nouveau pouvoir
    - Déclenchement
        - Créée un nouveau javelot à l'endroit de la raquette
- Débloque : fait un effet d'éruption à la surface de la raquette
- Docs
    - [Comment utiliser les Area2D](https://docs.godotengine.org/fr/4.x/tutorials/physics/using_area_2d.html)
    - [Référence Area2D](https://docs.godotengine.org/fr/4.x/classes/class_area2d.html)
- [ ] J'ai fait cette étape.
- Suite
	- Bonus de style : [Effet d’éruption de la raquette](#effet-déruption-de-la-raquette)
	- [Pouvoir balle spectrale](#pouvoir-balle-spectrale)


## Effet d'éruption de la raquette

- Dépend du pouvoir laser
- Actions
    - Créer une scène effet dans `effets/eruption`
    - Utiliser un `AnimatedSprite2D` pour faire l'effet d'éruption
    - Dans le TileSet
        - Importer les trois images d'éruption
        - Activer la lecture au chargement
        - Désactiver la lecture en boucle
    - Auto-détruire l'effet après l'animation
        - Brancher le signal `animation_finished` à la méthode `queue_free()` du nœud racine
- [ ] J'ai fait cette étape.
- Suite
	- [Pouvoir balle spectrale](#pouvoir-balle-spectrale)



## Pouvoir balle spectrale



Niv. 4

La balle spectrale devient transparente au contact sur la raquette :
elle ne rentre pas en collision avec les briques, jusqu'à son premier
rebond contre un mur.

- Docs
    - [Masques de collision](https://docs.godotengine.org/en/4.2/tutorials/physics/physics_introduction.html#collision-layers-and-masks)
- [ ] J'ai fait cette étape.
- Suite
	- [Le carrefour Godot](#le-carrefour-godot)
	- Vous avez de l'inspiration ? [Faire un nouveau pouvoir de balle](#faire-un-nouveau-pouvoir-de-balle)


## Faire un nouveau pouvoir de balle



Niv. 4

À vous de l'imaginer, et de l'implémenter. :-)

- Exemples : 
	- Balle collante : La balle colle à la raquette, et peut être renvoyée avec un clic ou un
	appui sur espace.
	- Balle magnétique : La balle est attirée par la raquette
- [ ] J'ai fait cette étape.
- Suite
	- [Le carrefour Godot](#le-carrefour-godot)
	- Vous avez encore de l'inspiration ? [Faire un nouveau pouvoir de balle](#faire-un-nouveau-pouvoir-de-balle)


## Exporter le jeu au format linux


- [Documentation](https://docs.godotengine.org/fr/4.x/tutorials/export/exporting_projects.html)
- [ ] J'ai fait cette étape.
- Suite
	- [Exporter le jeu au format Windows](#exporter-le-jeu-au-format-windows)


## Exporter le jeu au format Windows


Pareil que pour Linux.

Vous pouvez utiliser Wine pour contrôler votre export.

- [ ] J'ai fait cette étape.
- Suite
	- [Exporter pour le web](#exporter-pour-le-web)

## Exporter pour le web


Pour itch.io, nommez l'artefact produit `index` afin d'avoir un index.html.

Faites une archive.

- [ ] J'ai fait cette étape.
- Suite
	- [Exporter pour Android](#exporter-pour-android)


## Exporter pour Android

Niv. 4

Pour les plus experts d'entre vous.

Le plus facile est d'utiliser [l'image docker pour CI Godot](https://github.com/abarichello/godot-ci/tree/master).

- [ ] J'ai fait cette étape.
- Suite
	- [Le carrefour Godot](#le-carrefour-godot)


## Faire un obstacle avec une nouvelle forme



Niv. 3


- Actions
    - Nouvelle scène de racine StaticBody2D.
    - Nouvelle forme (sphérique par exemple).
    - Texture que vous voulez (planète par exemple).
    - Configurer les calques de collision.
        - C'est un mur (cochez la case "mur" dans le damier
            "collision_layer").
        - Ça collisionne avec les balles (cochez la case "mur" dans
            le damier "collision_mask").
- Calques de collision.
    - Explications :
        <https://docs.godotengine.org/fr/4.x/tutorials/physics/physics_introduction.html#collision-layers-and-masks>
    - Référence :
        <https://docs.godotengine.org/fr/4.x/classes/class_collisionobject2d.html#class-collisionobject2d-property-collision-layer>
- [ ] J'ai fait cette étape.
- Suite
	- [Faire une brique avec une nouvelle forme](#faire-une-brique-avec-une-nouvelle-forme)
    - Refaire cette étape avec une autre forme.



## Faire une brique avec une nouvelle forme



Niv. 4


- Actions
    - Créer un dossier "brique_spherique" (ou autre forme) dans le
        dossier brique.
    - Copier la scène de brique dans ce dossier et la renommer pour
        obtenir "brique_spherique.tscn".
    - Modifier la forme et la texture pour l'accorder à votre besoin.
    - L'ajouter au niveau de votre choix.


> Note : comme votre nouvelle brique a le même script que la brique de
base, les deux ont le même comportement !

- [ ] J'ai fait cette étape.
- Suite
	- [Le carrefour Godot](#le-carrefour-godot)


## Compter et afficher le score



Niv. 4 : le·a participant·e cherche par lui-même une solution ;-)


On pourra imaginer que le nombre de points dépend du temps. Plus un niveau est terminé rapidement, plus il y a de points ! On peut supposer que le nombre de briques détruites influe aussi sur le nombre de points.

- [ ] J'ai fait cette étape.
- Suite
	- [Collectibles qui donne des points](#collectibles-qui-donne-des-points)

## Collectibles qui donne des points



Niv. 4


- Prérequis
    - Compteur de score.
- Actions
    - Créer un pouvoir "ScoreBonus" (voir ci-dessous).
    - Associer un groupe à votre compteur de score.
    - Incrémenter le score quand le pouvoir est déclenché.
- [ ] J'ai fait cette étape.
- Suite
	- [Choisir la couleur de la raquette](#choisir-la-couleur-de-la-raquette)


## Pouvoir agrandissement raquette



Niv. 4


- Actions
    - Ajouter un pouvoir.
    - Mettre la raquette dans le groupe.
    - Ajouter une méthode publique "changer_taille" pour modifier
        sa taille.
        - /!\ Il faut modifier la taille de l'image et la taille de
            l'enveloppe physique !
    - Dans le déclenchement du pouvoir, appeler la méthode
        "changer_taille" sur toutes les raquettes.
- [ ] J'ai fait cette étape.
- Suite
	- [Malus diminution taille de raquette](#malus-diminution-taille-de-raquette)



## Malus diminution taille de raquette



Niv. 4


- Idem ci-dessus, modulo le facteur de taille.

- [ ] J'ai fait cette étape.
- Suite
	- [Le carrefour Godot](#le-carrefour-godot)



## Choisir la couleur de la raquette

Niv. 4

Permettre au joueur de pouvoir choisir la couleur de sa raquette depuis le menu.

C'est à vous de trouver comment faire !

- [ ] J'ai fait cette étape.
- Suite
	- [Choisir un pseudo](#choisir-un-pseudo)

## Choisir un pseudo

Niv. 4

Permettre au joueur de pouvoir choisir son pseudo depuis le menu.

Bon courage. :-)

- [ ] J'ai fait cette étape.
- Suite
	- Bonus : [Afficher le pseudo en jeu](#afficher-le-pseudo-en-jeu)
	- Faire un [leaderboard](#leaderboard)



## Afficher le pseudo en jeu



Niv. 4 : le·a participant·e cherche par lui-même une solution ;-)

- [ ] J'ai fait cette étape.
- Suite
	- Faire un [leaderboard](#leaderboard)


## Leaderboard


Niv. 4

Afficher la liste meilleurs scores sur l'écran de game-over.

Les scores doivent être sauvegardés dans un fichier.

- [ ] J'ai fait cette étape.
- Suite
	- [Le carrefour Godot](#le-carrefour-godot)

## Passer au niveau suivant une fois un niveau terminé



Niv. 4

Attribut par niveau, script niveau.

- [ ] J'ai fait cette étape.
- Suite
	- [Faire une carte de niveaux interactive](#faire-une-carte-de-niveaux-interactive)


## Faire une carte de niveaux interactive


Niv. 4

Ça peut être ce que vous voulez pour rendre le choix du niveau plus vivant.

- [ ] J'ai fait cette étape.
- Suite
	- [Le carrefour Godot](#le-carrefour-godot)


## Afficher une jauge de balles



Niv. 4 : naviguer la doc et expérimenter


Remplacer le label par une jauge, dont le nombre de points représente le nombre de balles.


- Remplacer un control par un nœud plus avancé fourni par Godot
- [ ] J'ai fait cette étape.
- Suite
	- Continuer initiation avec [Afficher un écran de game over](#afficher-un-écran-de-game-over)
	- [Le carrefour Godot](#le-carrefour-godot)



Pour aller plus loin
====================

Ressources et références
------------------------


### Ressources

- [Game Impact](https://gameimpact.fr/)
	- [Guide sur l'inclusivité](https://gameimpact.fr/wp-content/uploads/2022/05/Representer-la-diversite-Game-Impact-2021-02-Web.pdf)

