Un patrón común en programación es crear una representación de datos de un concepto, como comandos de personajes, que puedes pasar y tratar como datos dentro de tu código. En este minijuego, los comandos deben tratarse como datos a generar a partir de la interacción con la IU y pasarlos al personaje para que los ejecute.
En este proyecto, un comando se representa como una clase abstracta, y cada comando específico es una subclase de esta clase command, como forward_command y turnright_command. El uso de una clase abstracta para el comando significa que los únicos comandos válidos son las subclases que no son abstractas. Si intentas crear una instancia de la clase command directamente, obtendrás un error cuando intentes compilar tu código.
Ya que los comandos de personaje son subclases de la clase command, puedes utilizarlos donde se espere la clase command, como la función del personaje ExecuteCommand() del paso anterior. El primer parámetro en ExecuteCommand() espera el tipo de comando, lo que significa que puedes usar una instancia de una subclase command como argumento sin problemas.
Cada subclase ofrece su propia implementación de DebugString() para que cuando imprimas un valor de comando tenga asociado el texto correcto, pero puedes añadir más diferencias a las clases si lo necesitas.
Estas clases también tienen el especificador unique para que podamos comparar instancias de las clases. Este especificador las hace comparables.
Las clases también tienen el especificador computes para que puedas crear instancias de ellas en el module-scope (en el módulo Commands directamente). Esto significa que podemos crear una instancia única para representar cada comando, por ejemplo: Commands.Forward para el comando de avance.
En este ejemplo, se utilizan instancias de subclases de comandos en lugar del tipo enum por lo que puedes añadir más comandos más tarde al crear más subclases. Con un tipo enum, no puedes realizar cambios o añadir más valores al enum después de la versión inicial publicada del proyecto, por lo que el tipo enum es mejor cuando no esperas que tus datos cambien después de publicar tu proyecto.
A continuación se muestra el código completo para la implementación del comando.
# 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
Próximo paso
Ya definimos los comandos y mostramos cómo añadir tantos como desees.
En el próximo paso, obtendrás más información sobre cómo utilizar estos comandos en la IU y cómo añadir una IU personalizada para controlar al personaje.