Un patrón habitual en programación es crear una representación de datos de un concepto, como las órdenes de un personaje, que puedas pasar y tratar como datos dentro de tu código. En este minijuego, las órdenes deben tratarse como datos a generar a partir de la interacción con la IU y que se pueden pasar al personaje para que las ejecute.
En este proyecto, una orden se representa como una clase abstract, y cada orden específica es una subclase de esta clase command, como forward_command y turnright_command. Utilizar una clase abstract para la orden significa que las únicas órdenes válidas son las subclases que no sean abstract. Si intentas crear directamente una instancia de la clase command, obtendrás un error al intentar compilar el código.
Como las órdenes de los personajes son subclases de la clase command, puedes utilizarlas en cualquier lugar donde se espere la misma clase command, como la función ExecuteCommand() del personaje en el paso anterior. El primer parámetro de ExecuteCommand() espera el tipo de orden, lo que significa que puedes utilizar una instancia de una subclase command como argumento sin problemas.
Cada subclase proporciona su propia implementación de DebugString() para que, cuando imprimas un valor de la orden, 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 permite compararlas.
Las clases también tienen el especificador computes para que puedas crear instancias de ellas en el ámbito del módulo (en el módulo Commands directamente). Esto significa que podemos crear una única instancia para representar cada orden, por ejemplo, Commands.Forward para la orden «avanzar».
Este ejemplo utiliza instancias de subclases `command` en lugar del tipo enum para que puedas añadir más órdenes más adelante creando más subclases. Con un tipo enum, no puedes cambiarlo ni añadir más valores a la enumeración después de la versión inicial publicada del proyecto, por lo que el tipo enum es más útil cuando no esperas que los datos cambien después de publicar tu proyecto.
A continuación se muestra el código completo para la implementación de la orden.
# 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
Siguiente paso
Hemos definido las órdenes y hemos visto que puedes añadir tantas como quieras.
En el siguiente paso, aprenderás cómo se utilizan estas órdenes en la IU y cómo añadir una IU personalizada para controlar al personaje.