Un modèle courant en programmation consiste à créer une représentation de données d'un concept, par exemple des commandes de personnage, que vous pouvez transmettre et traiter sous forme de données dans votre code. Dans ce mini-jeu, les commandes doivent être traitées comme des données à générer à partir de l'interaction avec l'interface utilisateur et à transmettre au personnage pour qu'il les exécute.
Dans ce projet, une commande est représentée en tant que classe abstraite, et chaque commande spécifique est une sous-classe de cette classe command, par exemple forward_command et turnright_command. L'utilisation d'une classe abstraite pour la commande signifie que les seules commandes valides sont les sous-classes qui ne sont pas abstraites. Si vous tentez de créer une instance de la classe command directement, une erreur se produit lors de la compilation de votre code.
Dans la mesure où les commandes de personnage sont des sous-classes de la classe command, vous pouvez les utiliser partout où la classe command est attendue, par exemple la fonction ExecuteCommand() du personnage à l'étape précédente. Le premier paramètre dans ExecuteCommand() attend le type de commande, ce qui signifie que vous pouvez utiliser une instance d'une sous-classe de command comme argument.
Chaque sous-classe fournit sa propre implémentation de DebugString(), de sorte que lorsque vous affichez une valeur de commande, le bon texte lui est associé, mais vous pouvez ajouter d'autres différences aux classes si vous en avez besoin.
Ces classes possèdent également le spécificateur unique afin que vous puissiez comparer les instances des classes. Ce spécificateur les rend comparables.
Les classes possèdent également le spécificateur computes afin que vous puissiez créer des instances à l'échelle du module (directement dans le module Commands). Il est donc possible de créer une instance unique pour représenter chaque commande, par exemple Commands.Forward pour la commande Avancer.
Dans cet exemple, nous utilisons des instances de sous-classes de commandes au lieu du type enum, afin de pouvoir ajouter d'autres commandes ultérieurement en créant des sous-classes supplémentaires. Avec un type enum, vous ne pouvez pas modifier ni ajouter des valeurs à l'énumération après la publication de la version initiale du projet. Le type enum est donc préférable si vos données ne sont pas censées changer après la publication de votre projet.
Voici le code complet de l'implémentation des commandes.
# This file contains the data representation of all the commands that the NPC can receive
# and utilities for the data to help with debugging and troubleshooting issues.
# Each type of command that the NPC can perform will be an instance of this class.
# The class has the unique specifier to make instances of the class comparable.
# The class has the computes specifier to be able to instantiate it at module-scope.
# The class has the abstract specifier so it cannot be instantiated directly, and
# requires subclasses to implement any non-initialized functions, like DebugString().
command := class<computes><unique><abstract>:
DebugString():string
Étape suivante
Vous avez défini les commandes et appris à en ajouter autant que vous le souhaitez.
À l'étape suivante, vous découvrirez la façon dont ces commandes sont utilisées dans l'interface utilisateur et comment ajouter une interface utilisateur personnalisée pour contrôler le personnage.