Bienvenidos sean a este post, hoy veremos uno de los patrones para nuestro juego.
En el post anterior vimos como el patron flyweight nos permite optimizar el uso de memoria. Una conducta del juego es la creacion de los nuevos objetos en el juego, ya sean unidades asi como tambien los edificios creando sus unidades; las unidades construyendo edificios y la ambientacion del juego (arboles, piedra, etc). Para ello, debemos mejorar a la clase Unidad para agregarle la funcionalidad de clonacion. En este post, intencionalmente eliminamos al constructor de copia y al operador de asignacion, pero ahora agregaremos ese mecanismo que nos permita crear nuevos objetos desde unos existentes. Este patron nos pemite crear duplicados de objetos sin importar su tipo. Veamos como es nuestra nueva clase Unidad:
class Unidad
{
public:
Unidad() {}
Unidad& operator=(const Unidad&) = delete;
virtual ~Unidad() {}
virtual Unidad* clonar() = 0;
void mover(const Point& ir) {
// implemmentacion de graficos
}
virtual void atacar(const Unidad&) = 0;
virtual void destruir() = 0;
int get_poder() const { return poder_; }
int get_puntos_vida() const { return puntos_vida_; }
private:
Unidad(const Unidad& otro) {
puntos_vida_ = otro.puntos_vida_;
poder_ = otro.poder_;
}
int poder_;
int puntos_vida;
};
Esta clase es muy similar a la vista en este post, donde seguimos anulando al operador de asignacion, implementamos a la de mover para desplazarla en pantalla. El resto sigue siendo las mismas instrucciones, donde tenemos una virtual pura para cuando somos atacados, asi como taambien para eliminarlo pero entre las nuevas ahora tenemos una llamada clonar y sera la encargada de la magia. Recuerden que siempre este tipo de funciones van a tener asegurada aunque sea una definicion en alguna de sus herederas. Y su ultima modificacion es en la parte privada, donde ahora tenemos el constructor de copia. Esto permite asegurarnos que el objeto creado tenga una unica instancia. Aqui es cuando entra en accion clonar, para ello debemos definirlo en nuestras herederas, veamos un ejemplo de como puede ser:
class Lector : public Unidad
{
public:
Lector* clonar() override {
return new Lector(*this);
}
// codigo omitido para brevedad
};
Como dijimos al delegar la definicion del metodo clonar para cada unidad, este devolvera un objeto del tipo de unidad. Esto permite que se desacople el codigo del cliente con respecto a la clase del objeto. Veamos el siguiente caso:
Unidad* nueva_unidad = unidad->clonar();
Esto va a clonar la unidad sin necesidad de saber si es un lector o un soldado. El casteo dinamico trabaja muy bien cuando necesitaamos convertir un objeto en un tipo especifico. Con este hemos cubierto los patrones basicos que se pueden utilizar, y si bien lo vimos muy superficialmente, nos puede ayudar a tener una idea de como se puede tener un buen manntenimiento y diseño flexible para nuestros proyectos.
En resumen, hoy hemos visto a patron prototipo, que es, como nos ayuda, como se puede aplicar y para que se utiliza. Espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.50
