Implementación de un sistema de partículas

Los sistemas de partículas son utilizados en los juegos para crear una gran cantidad de efectos. Su implementación es mucho más sencilla de lo que parece, veamos como hacerlo utilizando C# y Managed DirectX.

Un sistema de partículas es una colección de pequeños objetos, denominados partículas, que se comportan de un modo predefinido para simular distintos efectos gráficos como humo, nieve, fuego, chispas, explosiones, hojas volando al viento, vapor, etc. Cada partícula posee propiedades que definen su comportamiento en el mundo así como su aspecto. Usualmente una partícula se encuentra compuesta por un pequeño mapa de bits aunque también podría ser un polígono o un conjunto de ellos.

freedomforce 01

Figura 1. El juego Freedom Force hace un uso intensivo de los sistemas de partículas

La implementación de un sistema de partículas puede ser bastante sencillo, aunque esto dependerá en parte del tipo de simulación que deseemos efectuar. Algunos sistemas implementan colisiones entre las partículas, algo costoso en términos de CPU pues la cantidad de partículas de un sistema suele ser elevada.

Arquitectura de un sistema de partículas

Todo sistema de partículas especifica un punto desde el cual las partículas nacen al mundo (aparecen en pantalla). Este punto se denomina generador o emisor y suele no poseer una representación gráfica (es invisible).

Es posible que, en función del tipo de sistema de partículas que deseemos crear, la generación no sea puntual, es decir que las partículas aparecerán en pantalla desde distintas posiciones (lluvia, nieve). Estas posiciones pueden ser totalmente aleatorias o pueden estar restringidas a un segmento o a una superficie.

generator

Figura 2. El generador es el punto desde el cual nacen las partículas

Estados de una partícula

Las partículas poseen un ciclo de vida:

. Nacen, aparecen en pantalla desde el generador.
. Viven, durante un período de tiempo durante el cual se desarrollan modificando una o varias de sus propiedades: posición, orientación, tamaño, color, etc.
. Mueren, retornando al repositorio de partículas disponibles para una nueva generación.

Aspectos de implementación

El diagrama de clases simplificado general que desearemos implementar es el siguiente:

particulas dc1

Figura 3. Diagrama de clases estático

Una clase sería la encargada de crear y controlar las partículas, y la clase partícula (que podría ser una estructura) contendría las propiedades de la partícula en cuestión.

Pero analicemos más detalladamente nuestra estrategia. Si deseamos poder poner en pantalla una gran cantidad de partículas deberemos tener algunas consideraciones en cuenta.

Idealmente el sistema de partículas comienza sin poseer ninguna partícula bajo su gestión, pues aún no ha nacido ninguna. Pasado un cierto tiempo se creará la primer partícula, cuando esto ocurra se fijarán ciertas propiedades iniciales de la partícula para que se muestre en pantalla según el efecto que deseemos simular (se le fijará la posición del generador, se le dará un color, un tamaño, se le fijará una velocidad inicial, etc.).

Luego, cuadro tras cuadro iteraremos por una lista donde estarán todas las partículas vivas y modificaremos algunas de sus propiedades según su ciclo de vida.

Finalmente, las partículas agotarán su tiempo de vida, momento en el cual serán eliminadas. Por supuesto, que esto último no ocurre para todas las partículas simultáneamente sino que van muriendo con la misma velocidad con la que fueron naciendo.

En una implementación trivial el nacimiento implicaría asignación de memoria, y la muerte implicaría desasignación (o al menos, por estar trabajando en C#, la indicación explícita que una determinada estructura de datos ya no es necesaria para nuestro programa).

Sin embargo, esto acción podría acarrear algunos problemas de desempeño por parte de nuestra aplicación. ¿Que ocurriría si el intervalo de generación de partículas fuese muy bajo y el tiempo de vida de cada partícula muy alto? Crearíamos muchísimas partículas hasta que, posiblemente, la aplicación comenzara a ralentizarse, sin mencionar que podríamos no saber a ciencia cierta la cantidad de memoria utilizada por nuestra aplicación.

Por lo tanto, deberemos emplear alguna estrategia que sea mas amigable con los recursos del sistema (CPU, memoria y GPU) y que sea más fácil de predecir en cuanto a los recursos que utilizará independientemente de la frecuencia de generación o el tiempo de vida de las partículas.

Nuestra estrategia consistirá en pre-generar una cantidad de partículas máxima que utilizará nuestro sistema y un mecanismo para reciclar partículas muertas sin reasignar memoria.

Pages: 1 2 3 4

Comments

  1. Master-Blaster
    April 9th, 2007 | 3:15

    lindo tutorial, gracias!

  2. Ni7ram
    April 9th, 2007 | 17:34

    Muy bueno

  3. kuo
    June 28th, 2007 | 12:53

    Oe man…precioso tutorial… te pasaste on… Por los diagramas de clases y diagramas de flujos y la paciencia que tienes para explicart …te puyedo asegurar que tienes dotes de profesor on..Bueno espero que sigas subiendo mas tutoriales on… son super buenos…A solo queria preguntarte si pronto vas a subir el tutorial de MD2(segunda parte y posteriores me serian de gran utilidad)

  4. kuo
    June 28th, 2007 | 12:57

    Oe man buen tutorial on(te pasaste)… por los graficos y diagramas te puedo asegurar que tienes dotes de profe on… sinceramente bueno …sigue colgando mas tutoriales on serian de mucha ayuda… A man ya ps acuerdate de subir el tutorial MD2 (segunda parte)

  5. kuo
    June 28th, 2007 | 13:01

    Man buenazo on te pasaste …se ve que tienes dotes de profesor

  6. kuo
    June 28th, 2007 | 13:10

    sinceramente myu bueno man…tienes dotes de profesor on…

  7. June 3rd, 2008 | 23:55

    muy bueno muy bueno.

Leave a reply