|
PRGs
|
| >> PRGs >> Cómo controlar muchos individuos by Wakroo. |
En este artículo quiero comentaros cómo solucioné el asunto de controlar distintos individuos de manera general. Se puede hacer que cada proceso se encarge de detectar si tiene que hacer algo o no, pero puede resultar un poco complicado, especialmente si hay varias maneras de darle órdenes a cada individuo. Si tenemos, además, distintos tipos de individuos con su propio proceso tendremos que repetir el código en cada proceso, con todo lo que esto conlleva: posibles errores al duplicar el código, tener que cambiar todos los procesos afectados si se hace algún cambio, código más largo y menos legible,...
¿Y qué solución propongo yo? Nada del otro mundo, la verdad. Algo tan sencillo como tener una estructura general donde guardar las distintas órdenes que recibirán los individuos. En esa estructura podemos guardar datos como la ID del proceso (muy útil en muchos casos, aunque sólo sea para destruirlo), sus coordenadas (para saber dónde está), las órdenes que tiene que cumplir (codificadas en un número: 1-> moverse ; 2-> disparar ; 3-> cavar trincheras ; ...), coordenadas de las órdenes que tiene que cumplir (a dónde se tiene que mover, qué posición tiene que bombardear,...), a qué individuo tiene que atacar (su id, su posición en la estructura,...), cuánta energía le queda,... Cualquier dato que necesite nuestro individuo. De esta manera, cada proceso no tiene más que mirar en la tabla para saber qué tiene que hacer, si le queda mucha o poca energía,...
En otro proceso, podremos poner todas las rutinas de control de individuos. Simplemente sabiendo el índice en la tabla del individuo al que le queremos dar órdenes podemos controlar todos los aspectos de ese individuo: le podemos decir que vaya a una posición concreta del mapa (la del ratón,...), cambiar el estado del individuo (que no se mueva ni ataque hasta que haya sido liberado, bajo los efectos de un ataque que le hace moverse más despacio,...), reducir su energía (exposición a rayos cósmicos mortales,...),... De esta manera tendremos todo el control centralizado en un único proceso, por lo que facilitaremos el desarrollo de nuevas aspectos del control, evitaremos muchos errores y abriremos más posibilidades. Por ejemplo, sería mucho más fácil hacer alguna especie de animación previa al principio de la fase (o en medio o donde queramos), ya que bastaría con ir modificando los datos de la estructura y los individuos responderán obedientemente. Y si no hemos activado el proceso encargado de darle el control al jugador no tendremos que preocuparnos por que el jugador intente mover las tropas o hacer cosas raras. Además, si creamos un nuevo tipo de tropa que se mueve dando saltos, ataca insultando al enemigo o hace cualquier otra cosa extraña no tenemos que tocar el sistema de control, simplemente tenemos que programar el proceso de manera que el individuo responda a las órdenes de la manera adecuada.
Otra posibilidad es dar órdenes a varios individuos a la vez. Se pueden guardar sus posiciones en la estructura en un pequeño array e ir variando a la vez todos las posiciones de la tabla que hagan falta. Así nos dará igual si los individuos que hemos elegido son del mismo tipo, de distinto tipo, si se pueden mover o no, todos mirarán las órdenes y su estado y actuarán en consecuencia. Todo esto unido a que cualquier proceso puede acceder en cualquier momento a estos valores para realizar cualquier tipo de comprobación o ajuste lo convierten, en mi opinión, en un buen sistema.
De todas formas el sistema tiene sus pegas. La primera es que si queremos eliminar un individuo y luego poder meter otros nuevos tendremos que andar recolocando la lista, es decir, mover todos los que estén por debajo una posición hacia arriba. Eso es fácil de hacer, pero entonces los procesos no estarán mirando la tabla en la posición adecuada. Habría que corregir eso. La manera más sencilla es hacer que el proceso compruebe si su ID y la de la posición de la tabla que está mirando son la misma y pasar a mirar en la posición superior de ahí en adelante si nno lo es. Es muy importante realizar esta comprobación y ajuste antes de mirar qué órdenes tiene que cumplir el individuo en cuestión, es decir, que sea lo primero que haga el proceso dentro del LOOP. Si no lo hacemos así puede ser que los datos de la tabla ya se hayan recolocado para tapar el hueco pero el proceso mire en la posición equivocada (en realidad estará mirando las órdenes y los datos del siguiente individuo en la lista). A mí me ha pasado y es un error bastante difícil de encontrar de primeras (yo me estuve todo un verano buscándolo y lo encontré por inspiración del Espíritu Santo, así que...).
Otro problema importante es que el número de individuos estará limitado por el número de posiciones que le hayamos puesto a la estructura, a no ser que vayamos aumentándola de manera dinámica. Esto se puede solucionar poniendo un número de posiciones lo suficientemente alto (muchos juegos comerciales tienen límite de número de unidades: en el Starcraft son 200). Lo malo es que si hay pocos individuos que controlar entonces estaremos desaprovechando bastante memoria, pero no es una grave pega hoy en día. Si lo hacemos de manera dinámica usaremos la memoria de una manera mucho más eficiente, pero complicaremos el código bastante.
He hecho un pequeño programa en el que se puede controlar a 4 individuos. Se selecciona cada uno presionando su número en el teclado. Entonces dejará de estar semitrasparente e irá a cualquier posición que pinchemos con el ratón (botón izquierdo). Si mientras se está moviendo pinchamos en otro sitio irá a ese nuevo sitio, aunque no haya llegado todavía al que tenía que ir (se podría haber implementado un sistema de puntos de ruta). Si mientras se está moviendo seleccionamos otro individuo le podremos dar órdenes y se moverá, pero sin afectar al movimiento del individuo original, que irá hasta donde tiene que ir. No se ha implementado la posibilidad de elección múltiple para no complicar el programa.
Yo creo que esto es todo en principio. La base de la idea es ésa y a partir de ahí lo único que tenéis que hacer es particularizarla para vuestro caso. Si conocéis alguna otra forma de hacerlo (que hay miles) o tenéis cualquier duda, pregunta, sugerencia o halago (a fin de cuentas soy un ser humano) escribidme un mail a lordwakroo@yahoo.es. Un saludo y que la Fuerza os acompañe.