Sites


Utiliser Godot Game Engine 3.0

Ajouter des obstacles en GDScript

Nous avons donc ajouté et organisé toutes les ressources que nous voulions utiliser dans l’éditeur. Mais comment faire en sorte que des choses se produises ? Comme le joueur va il interagir avec le monde ? Comment allons-nous calculer le score ? Les scripts vont nous permettre tout cela.

Pour le code, Godot utilise son propre langage : le GDScript, qui emprunte beaucoup à Python. Il est fait pour être simple à apprendre, lisible et offre de nombreuses classes prédéfinies qui accélèrent le développement. Il n’a pas besoin d’être compilé, mais bien sûr, cela n’accélère pas le rendu mais son apprentissage. La principale optimisation est opérée au niveau du moteur et le GDScript améliore considérablement les performances par rapport à Python dans le contexte du jeu. Si vous souhaitez des performances supérieures, sachez que Godot est aussi compilé avec le langage mono (C#) mais que cela demandera des efforts d’apprentissage supérieurs.

Pour lire ce chapitre, il est préférable d’avoir quelques bases des concepts de programmation. Vous pouvez trouver quelques informations sur Python dans notre manuel.

La partie principale de la structure du code est donnée par Godot, directement. Les scripts sont attachés aux Nodes et étendent les classes sur lesquelles ces Nodes sont basés. Nous avons simplement besoin de définir ce qui est spécifique au jeu comme les variables et les fonctions.

Variables

Les variables sont des éléments de programmation de base qui permettent de stocker une information : cela peut être une propriété du joueur, cela peut aussi être le score… Dans un jeu, il y a des centaines voir des milliers de variables, leur nombre augmentant avec la complexité du jeu. 

Les variables sont explicitement déclarées :

  • En haut du fichier d’un script si elles ont besoin d’être partagées dans les fonctions,
  • Dans les fonctions elles-mêmes.

Utilisez le mot clef var pour déclarer la variable. Puisque GDScript est un langage dynamique, il n’y a pas besoin de définir la nature (type) d’une variable. Cette information sera définie lorsqu’une valeur lui sera attribuée, sinon, elle est nulle (ce qui reste un format de variable).

var speed

Il est évidement possible de leur attribuer des valeurs dès le début :

var speed = 100

Ou bien à n’importe quel moment dans n’importe quelle fonction  (pas besoin du mot clé var si elle est déjà déclarée ailleurs):

speed = 100

GDScript intègre des types de variables standards (comme les int, float, string, bool, null, array, dict…) mais également quelques types spécifiques à celui-ci pour certains calculs mathématique (comme les Rect2, Vector2, Vector3…) et quelques types relatifs au moteur de jeu (Color, Image, Object, InputEvent…). L’objectif de ce livre n’est pas de vous les décrire, vous allez pouvoir en apprendre plus sur l’aide intégrée à l’éditeur.

Notez qu’il est aussi possible de définir des constantes avec le mot clef const. Nous les utiliserons pour des "informations" dont le contenu ne doit pas changer au cours du jeu, par exemple, la gravité.

Nous allons parfois utile « d’exporter » la variable d’un script. Une fois fait, la variable est visible et modifiable dans l’inspecteur. C’est une option importante que certains codeurs feraient mieux d’utiliser pour leurs variables importantes. Cette option aide les game designer à tester certaines valeurs pour améliorer le jeu sans casser tout le code. C’est extrémement pratique pour la phase d’équilibrage.

export var speed = 100

Fonctions

Pour déclarer une fonction il suffi d’utiliser le mot clef func ainsi :

Func function_name() :
        # le contenu vient ici
Bien que GDscript utilise des mots clés pour les variables et son propre mot clé pour les fonctions, on voit qu’il hérite du principe d’indentation et des commentaires de python.

Si vous jetez un coup d’œil à Python, vous aurez remarqué qu’il n’y à pas de def ni de self qui est considéré comme implicite. Sinon, les fonctions while et for sont identiques.

Les fonctions prédéfinies de Godot commencent avec un underscore « _ ». Par exemple _ready(), qui se joue à l’entré du script dans l’arborescence.

Func _ready() :

Evidemment, à mesure de l’étendue du script, chaque fonction est une méthode d’une classe et peut être appelée en tant que membre.

Var player = get_node(«player »)

Player.do_this()

Donnons de la vie aux éléments avec un script

Assez parlé, voyons comment utiliser un script.

  1. Sélectionnez la racine de la scène et cliquez sur le bouton script en haut de la page de l’éditeur.
  2. Créez un script dans la fenêtre Fichier > Nouveau. Modifiez les préférences du pop-up, nommez le script et cliquez sur créer.
  3. L’éditeur de script apparait et affiche le contenue du fichier. Si le modèle par défaut est sélectionné, on peut voir l’extension Node2D (ce qui signifie que toutes les variables et les méthodes du Node2D sont utilisables dans le script) et la fonction _ready().
  4. Dans la fonction _ready(), supprimez les commentaires et le pass. Ajoutez un print(« test »). Sauvegardez le script et jouez la scène. La scène se joue et la fenêtre de Sortie Debugger reste visible. Si tout se passe bien, la Sortie devrait écrire « test » dans l’output.
  5. C’est un premier pas et on peut voir que tout fonctionne, continuons.
  6. Dans notre scène, ajoutons un Node Label dans lequel nous allons garder en mémoire le nombre d’obstacles passés. Comme vous pouvez le voir, le Label est vide… Sa valeur peut être modifiée dans l’inspecteur mais dans cet exemple, nous allons le modifier depuis un script car elle doit changer de manière dynamique dans le cours du jeu.
  7. Créons une fonction pour cela que nous appelons score. Si nous voulons qu’il soit appelé dès le début, il faut placer l’appel dans la fonction _ready() : on se retrouve avec :
func score() :
               print(« lecture de la fonction score»)
func _ready() :
                print(« test »)score()
  1. Si on joue la scène, les messages « test » et « lecture de la fonction score » devraient apparaitre dans la Sortie. S’il y a une erreur, vous ne pouvez pas la rater ! l’éditeur de Script affiche l’erreur en rouge en précisant la ligne et le numéro de charactère. De plus, la Sortie précisera aussi les erreurs rencontrées. Dans l’exemple plus bas, Il y a une fin de ligne imprévue (unexpected End Of Line : EOL) à la ligne 8 car il manque une parenthèse.
    erreur et débogage dans Godot
    Pensez à bien fermer le jeu après avoir fait une erreur pour pouvoir sauvegarder.
  2. Si vous souhaitez avoir plus de messages d’erreur et mettre en pause le jeu en cours, vous pouvez placer des breakpoint. Pour cela, cliquez sur le coté gauche du numéro d’une ligne ou cliquez sur F9. Si la ligne du script est lue par le jeu, il se met en pause et permet d’observer les valeurs sorties par les print. Il est alors possible, dans la fenêtre Débogueur, de cliquer sur le bouton continuer pour reprendre l’exécution du script.
  3. On peut maintenant changer le texte du Label. Pour commencer, nous avons besoin d’accéder au Node Label. Une méthode très simple pour y parvenir est d’utiliser la méthode get_node(). Vérifions tout d’abord si le Node existe :
If (get_node(« label »)) :
                Print(« Label found »)
Else :
                Print(« No label node »)
  1. Si un Node nommé Label est trouvé, le premier message apparaitra. Sinon, modifiez le nom du Label pour que les deux noms coïncident. Enfin, nous avons besoin de savoir comment modifier le texte dans le jeu. Si vous ne savez pas quoi utiliser, servez-vous de l’outil rechercher dans l’aide pour trouver le Label. Cliquez dessus pour avoir accès à toutes les méthodes de la classe. En haut, nous avons la méthode public appelée set_text() qui semble appropriée. Cliquez dessus pour afficher les détails : « définis le texte du Label ». Utilisons-la pour modifier le texte affiché dans le Label !
if (get_node("Label")):
     get_node("Label").set_text("0")
 else:
     print("No label node")

La prochaine étape va être de remplacer le texte par un integer (type de variable nombre entier) qui augmentera chaque fois que la chauve-souris passe un obstacle. Mais avant, nous avons besoin de faire apparaitre les obstacles et faire bouger le joueur. Voici comment nous allons nous occuper des bâtiments :

var obstacles = []
 var spawn_ofs = 1000
 export var spawn_distance = 500

 func spawn_obstacle():
     var obs = preload("res://obstacles.scn").instance()
     obs.set_pos(Vector2(spawn_ofs, 0))
     spawn_ofs += spawn_distance
     add_child(obs)
     print("Obstacle spawned at ", obs.get_pos())

On commence par déclarer nos variables : obstacle, spawn_ofs et spawn_distance. Vous pouvez voir que nous avons créée une variable exportée avec le mot clef export. Cela permet de l’afficher la variable dans l’inspecteur.

EXPORT DE VARIABLE DANS GODOT

On ajoute en suite une fonction qui précharge la scène contenant les obstacles et leurs instances. Nous saisissons la position des nouvelles instances via un Vector2. On met à jour la variable pour l’instance suivante et l’ajoutons comme enfant du Node racine.

Notre fonction sera utilisée lorsque la chauve-souris bougera. C’est donc ce que nous devons faire maintenant.

Il y a une erreur de communication avec le serveur Booktype. Nous ne savons pas actuellement où est le problème.

Vous devriez rafraîchir la page.