Bienvenidos sean a este post, en el post anterior hablamos como tener un objeto juego para poder manejar cada uno de ellos, con sus pros y contras, hoy nos centraremos en analizar una fabrica para generarlos.
Si bien al final del post anterior dijimos que se deberia usar una composicion basada sobre herencia y parece una solucion genial pero tambien tiene algunos inconvenientes, el principal problema va a ser que nuestra nueva clase necesita saber todos los tipos diferentes de los componentes y cada tipo de objeto en el juego, si bien nosotros disponemos de una clase universal llamada GameObjeto que puede ser cualquier cosa que deseemos, despues debemos hacer un codigo con una logica que conozca sobre como construir estas instancias de GameObjeto super flexibles y componerlas con los componentes correctos pero si agregamos este nuevo codigo dentro del codigo anterior la volveria increiblemente amplia y desbarataria la razon de usar un patron de entidad-componente.
Vamos a crear una clase hipotetica llamada GameObjeto, su codigo seria semejante a este:
class GameObjeto
{
MovimientoComponente mMoviComp;
GraficosComponente mGrafComp;
EntradaComponente mEntComp;
Transformar mTransformar;
... Mas miembros de la clase.
GameObjeto(string tipo)
{
if(tipo=="diver")
{
mMoviComp = new DiverMovimientoComponente();
mGrafComp = new StdGraficosComponente();
}
else if(tipo == "chaser")
{
mMoviComp = new ChaserMovimientoComponente();
mGrafComp = new StdGraficosComponente();
}
... mas instrucciones ...
}
}
Como pueden ver tenemos unos objetos de tipo «genericos» que luego en el constructor en base al tipo iremos definidiendo tanto a mMoviComp como a mGrafComp, recuerden que eso que hicimos en el ejemplo debemos hacerlo con todos los enemigos faltantes, jugador, laser y el fondo de pantalla, tambien la clase GameObjeto necesita saber no solamente cual componente va con el GameObjeto sino tambien que objetos de GameObjeto no necesitan ciertos componentes como los componentes relacionados a la entrada para controlar al jugador.
Si nos remontamos a este post cuando hablamos de la creacion de la UIcontroladora a la cual registramos en la GameEngine como un observador, se le hizo prestar atencion a los botones de nuestro HUD por medio de un ArrayList con elementos de tipo Rect a su metodo handleInput cada vez que GameEngine recibia un informe de toque en el metodo onTouchEvent, si hacemos que GameObjeto entienda esta logica hara que perdamos cualquier beneficio o eficiencia obtenida por medio de la composicion sobre herencia.
Vamos a suponer un par de situaciones, que sucederia si deseamos agregar una nueva clase de enemigo? Vamos a tener que agregar no solamente su clase sino todos los metodos y clases necesarias para poder manejarlas o peor aun que sucede si queremos que alguno de nuestros enemigos haga un nuevo movimiento? Deberemos agregar no solamente un monton de condicionales para manejar todos estos cambios sino ademas ver como podemos hacer que estos enemigos hagan el nuevo movimiento o por ahi que algunos lo hagan y otros no, en fin mas cambios sobre lo que ya tenemos creado, otra situacion interesante puede ser que necesitemos agregar otro GameObjeto que acepte entradas, es decir que pueda ser manejado, y esto no va a hacer otra cosa que empeorar aun mas las cosas porque ahora tambien debe asegurarse de pasar en una referencia de GameEngineBroadcaster y este GameObjeto debe saber lo que tiene que hacer.
Esto tambien trae como consecuencia que cada GameObjeto poseera un EntradaComponente pero no todos necesitan uno, lo cual no solamente sera un gasto excesivo de memoria sino que tambien por cada GameObjeto se iniciara EntradaComponente y esto sera un desperdicio de llamadas a GameEngineBroadcaster o peor aun en un EntradaComponente nulo que estara latente para crashear con el juego.
Nota: Cuando digo Crashear me refiero a un error que termine el juego repentinamente.
Un ultimo vistazo si observan la hipotetica clase podemos ver que existe un objeto llamado Transformar, es decir que todas las instancias estaran compuestas con este objeto el cual almacenara el tamaño, la posicion y otros parametros pero de esto hablaremos un poco mas adelante.
Hasta aca solo tuvimos malas noticias y dolores de cabeza pero vamos a comenzar con las buenas nuevas, aca veremos como el patron de Fabrica simple va a ser el mejor compañero para el patron Entitdad-componente.
Siempre tengamos en cuenta que los diseñadores de juego van a proveer las especificaciones para cada tipo de objeto en el juego, el programador debera proveer una clase de tipo fabrica para construir estas instancias de los objetos en base a las especificaciones del diseñador, puede suceder que el diseñador venga con nuevas entidades, nuevas capacidades, o nuevas especificaciones, esto deberia involucrar que se cree una nueva linea de la fabrica, la cual use un componente existente, hagamos un nuevo bloque de codigo para un componente o simplemente actualizar componentes existentes, mas alla de lo que necesitemos el punto aqui es que bajo ninguna circunstancia no modifiquemos a GameObjeto, GameEngine, Renderer y FisicasEngine, un ejemplo podria ser asi:
GameObjeto objetoActual = new GameObjeto;
switch(tipoObjeto)
{
case "diver":
objetoActual.setMovimiento(new DiverMovimiento());
objetoActual.setDibujar(new StdDibujar());
break;
case "chaser":
objetoActual.setMovimiento(new ChaserMovimiento());
objetoActual.setDibujar(new StdDibujar());
break;
}
En este ejemplo creamos un objeto de tipo GameObjeto, nuestro siguiente paso sera un switch donde verifica a tipoObjeto y en base al valor en esta variable usara a la clase que corresponda porque como vinimos diciendo el metodo para dibujar puede ser igual para todos los elementos pero sabemos que los movimientos si van a ser distintos, cabe aclarar que este es un codigo de ejemplo y sera diferente al que veremos mas adelante, y si bien no es el apropiado para nuestro caso veremos que no esta tan alejado a los que utilizaremos en la clase de fabrica.
En resumen, hoy hemos terminado con la teoria de como poder manejar multiples elementos en nuestro juego, como podemos seguir agregando o modificando elementos sin necesidad de agregar mucho mas codigo, como es el concepto de fabrica para mejorar la manipulacion de los elementos de forma completamente independiente, les pido un poco de paciencia y ya continuaremos con el proyecto, espero les haya gustado 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.
Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar
Es para mantenimiento del sitio, gracias!
$1.00