Cours de programmation sur les moteurs de jeux

Introduction

Ce cours est la suite du cours d'introduction aux moteurs de jeux du semestre précédent. Maintenant que l'interface de Godot est maîtrisée, il est temps d'approfondir les possibilités de développement disponibles grâce à la rédaction de scripts. Pour l'instant, nous les rédigerons en GDScript.

Nous aurons en fil rouge de déveloper un jeu de stratégie en temps réel (STR ou RTS en anglais pour : real-time strategy). Pour commencer, vous pouvez télécharger la base de projet MyFirstRTS qui contient le minimum pour pouvoir commencer le développement mais pour vous dérouiller un peu, il n'est pas interdit de créer rapidement un environnement équivalent. Je tiens à préciser que les ressources graphiques que j'utilise ne sont pas de moi, elles proviennent de Kenney. J'ai notamment choisi le package Sci-Fi RTS pour les éléments graphiques et UI Pack: Space Expansion pour les éléments d'interface graphique.

Configurer les mouvements de caméra (Séance 1)

Voilà donc à quoi ressemble notre projet vu dans l'interface Godot lors du lancement : dommage Nous avons bien ajouté un noeud de type Camera2D à la scène mais pour l'instant aucun script n'y est attaché. Cependant, avant de se pencher sur le script, il y a quelques vérifications à effectuer dans l'inspecteur :

Il est maintenant temps d'ajouter un script à notre caméra, j'ai choisi de l'appeler Camera_movement.gd. Ce script est donc une classe qui hérite dans ce cas précis de Camera2D. Nous allons tout d'abord gérer les déplacement de la caméra via les appuis sur les touches directionnelles.

Exercice

À ce stade, si on lance notre scène, les déplacements de la caméra sont bien pris en compte, vous pouvez ajuster la vitesse de déplacement en modifiant la valeur de la variable speed dans l'inteface.

La prochaine étape est de paramétrer le zoom. Les actions de zoom vont s'effectuer grâce à la molette de la souris et seront gérées dans la fonction _input(event) qui ne se déclenche que sur les frames dans lesquelles le moteur a effectivement détecté un événement en entrée. La classe Camera2D a une proriété zoom de type Vector2 qui définit le zoom de la caméra par rapport à la fenêtre. Les valeurs supérieures au vecteur (1, 1) effectuent un zoom arrière et les valeurs plus petites effectuent un zoom avant.

Exercice

Si on teste maintenant, on constate un souci : une fois l'action de zoom (ou dé-zoom) lancée, la caméra zoom à l'infini tant qu'on n'actionne pas la molette dans le sens opposé. Nous allons résoudre ce problème !

Exercice

Rendre des objets sélectionnables

Le but de cette partie est de créer des objets selectionnables auxquels il sera possible par la suite d'appliquer des actions.

Exercice

Notre unité est prête à être scriptée ! Voilà à quoi ressemble notre scène :

dommage
La suite consiste à ajouter un script pour permettre de sélectionner l'unité par un click.

Exercice

Vous devrez me rendre ce travail avant le 10/02/2022 23h59. Le sujet de votre mail sera "[GODOT]Séance 1". Dans le corps du mail, vous n'oublierez pas de préciser vos nom, prénom, numéro d'étudiant.

Signaux (Séance 2)

Pour qu'une action sur un noeud puisse avoir des répercutions sur d'autre éléments du jeu, nous allons utiliser les signaux. Un signal est un message qui peut être émis par un objet afin qu'un autre puisse l'intercepter et y réagir. Je vous invite à lire leur principe de fonctionnement ici. Il est donc possible pour un noeud d'émettre un signal personnalisé, la syntaxe pour le déclarer est la suivante : signal mon_signal. Une fois déclaré, le signal apparaît dans l'inspecteur et peut être connecté de la même manière que les signaux intégrés d'un noeud. Le signal est émis par l'appel de la fonction emit_signal("mon_signal"). Il est possible de déclarer des arguments au signal : signal mon_signal (arg1, arg2, ...). On ajoute les valeurs de ces arguments à la suite du premier argument lors de l'émission : emit_signal ("mon_signal", val_arg1, val_arg2, ...). Il est également possible de connecter le signal dans le script : connect ("mon_signal", target, "method"). Cela permet donc au signal passé en premier paramètre d'être connecté à la méthode method de l'objet target.

Exercice

Exercice

Exercice Supplémentaire

Les mouvements de caméras, n'étaient pas parfaits et je pense que cela mériterait d'y apporter quelques améliorations :

Vous devrez me rendre ce travail avant le 17/02/2022 23h59. Le sujet de votre mail sera "[GODOT]Séance 2". Dans le corps du mail, vous n'oublierez pas de préciser vos nom, prénom, numéro d'étudiant.

Séance 3

Notre but maintenant va être de lier nos éléments de jeu à l'interface graphique. Aujourd'hui, nous allons faire apparaître, dans la barre d'interface du bas de l'écran, un bouton avec le bon label, lors de la sélection d'une unité. Un clic sur ce bouton entrainera la déselection de l'unité correspondante.

Exercice

Voilà pour la partie bouton. Sauvegardez votre scène. Voici à quoi elle pourrait ressembler :

dommage
Nous allons maintenant retourner dans notre scène World.tscn

Exercice

Voici ce à quoi devrait ressembler votre jeu à cet instant :

Exercice

Nous allons ajouter une barre de vie à nos unités et la faire apparaître en cas de sélection.

Vous devrez me rendre ce travail avant le 5/03/2022 23h59. Le sujet de votre mail sera "[GODOT]Séance 3". Dans le corps du mail, vous n'oublierez pas de préciser vos nom, prénom, numéro d'étudiant.

Déplacement et recherche de chemin -- Séance 4

Maintenant qu'il est possible de gérer la sélection de nos unités, nous allons pouvoir les déplacer de vers un même point de la carte. Les unités devront contourner les obstacles présent sur leur chemin.

Exercice

Nous allons déjà enrichir notre monde afin de rendre les calcul de chemin de nos unités plus ardu. Pour cela, vous allez devoir créer deux scènes : une première qui reprend les éléments présent dans le noeud "Factory" du projet initial. Et une deuxième qui ressemblerait à celle ci-dessous :

dommage
Une fois créées, instanciez chacune d'elles plusieurs fois (au moins 5) et placez où vous le souhaitez. La carte est ainsi enrichie.

Exercice

Pour calculer un chemin entre deux position de la carte, nous allons utiliser un objet Navigation2D. La première chose à faire est donc de lire attentivement la documentation liée à cet objet et à son utilisation. Puis, regarder l'exemple fourni en lien sur cette même page 2D Navigation Demo. Ensuite, créer un noeud Navigation2D et dessinez le NavigationPolygonInstance en tenant compte des éléments de notre map. Voilà à quoi cela pourrait ressembler à ce stade :

dommage

Exercice

Le but est que les unités sélectionnées se déplacent vers un point de la carte en cas de doubleclick. Voilà une proposition de marche à suivre :

Voici une vidéo de l'objectif à atteindre :

Boules de feu

Exercice

Le but de cet exercice est d'élaborer la scène qui va permettre d'instancier autant de boules de feu que désiré. La première étape est donc de créer une nouvelle FireBall.tscn Cette scène sera composée de la manière suivante :

Elle aura un noeud fils Area2D auquel on ajoute un noeud fils de CollisionShape2D (qui aura une forme Circle de rayon 8) et un autre de type Particles2D. Il faut ensuite créer un ParticlesMaterial dans les propriétés du noeud et ajouter une texture à nos particules. Vous pourrez utiliser ce fichier (Merci https://www.kenney.nl/) : fire_particles.png

Exercice complémentaire

Faites en sorte que les tours éméttent des boules de feu

Vous devrez me rendre ce travail avant le 17/03/2022 23h59. Le sujet de votre mail sera "[GODOT]Séance 4". Dans le corps du mail, vous n'oublierez pas de préciser vos nom, prénom, numéro d'étudiant.

Séance 5-6

Exercice

En reprenant la scène Fireball.tscn, nous allons lui ajouter un script, afin gérer le lancement et la trajectoire d'une boule de feu par les tours. Il faut commencer par créer un champ speed initialisé à 20. Ensuite, il faut ajouter deux champs de type Vector2, chacun disposant d'un setter. Ainsi, à sa création, une boule de feu aura un vecteur de direction et une destination. Dans la méthode _process, gérer le déplacement de la boule de feu jusqu'à sa destination, puis la supprimer une fois l'objectif atteint.

Exercice

Nous allons compléter la scène Tower.tscn. Nous allons ajouter deux noeuds fils au noeud 2D principal :

Voici à quoi ressemble la scène Tower à cet instant :
dommage

Exercice

Pour émettre les boules de feu, nous avons besoin d'ajouter un script à la tour. Il est judicieux de l'ajouter au noeud racine, nous aurons ainsi accès facilement aux noeuds Timer et Position2D. Dans un premier temps, nous allons faire tourner les tours sur elles-même et les faire tirer toutes les cinq secondes. Voici les actions à réaliser :

Exercice

Nous allons faire en sorte que les unités prennent des dommages lorsqu'elles se font toucher par une boule de feu. Pour cela, nous allons créer une fonctio take_fb_damage dans le script Unit.gd. Dans cette fonction, il faudra dimnuer la valeur associée au noeud Life. Si cette valeur, n'est plus supérieure à 0, l'unité doit donc disparaître...

Exercice

Il ne reste plus qu'à ajouter un signal body_entered sur l'area2D. Ce signal, est connecté à la méthode _on_FireBall_body_entered(body). Dans cette fonction, il suffira de tester si l'élément entré en contact avec la boule de feu possède une méthode qui gère la perte d'énergie due à la collision avec la boule de feu (take_fb_damage dans notre cas). Si c'est le cas, on appellera la méthode en question.

Voici une vidéo de l'objectif à atteindre :

Exercice complémentaire

Et maintenant, vous pouvez faire en sorte que les tours aient également des points de vie, et que les unités puissent les attaquer et les détruire. Vous êtes libres de choisir comment se déroule l'attaque (juste le contact, tir de boules de feu également, épée...).

Vous devrez me rendre ce travail avant le 24/03/2022 23h59. Le sujet de votre mail sera "[GODOT]Séance 5". Dans le corps du mail, vous n'oublierez pas de préciser vos nom, prénom, numéro d'étudiant.

Séance 7-8 : réseau & multijouers

Pour commencer, je vous recommande de lire très attentivement la page suivante.

Exercice

Commencez par créer une scène dédiée au choix du username, à la création d'un serveur ou à la connexion à un serveur existant.

dommage

Exercice

Une fois capable de créer un serveur et d'y acceuillir des joueurs, configurer un jeu simple ou les joueurs se déplacent sur une map et peuvent se lancer des boules de feu.

Exercice

Essayez, maintenant d'intégrer une gestion du multijoueur dans le jeu que nous avons développé depuis le début du semestre. Dans un premier temps, vous pourrez limiter à deux joueurs, chacun aura ses unités et ses tours, le but étant de détruire toutes les tours de l'autre joueur.