Particles

Hoy, tras un descansito, vamos a seguir dibujando cosas en OpenGL, algo bastante genérico que vamos a necesitar para casi cualquier proyecto: un sistema de partículas.

En el de hoy tampoco nos vamos a calentar mucho la cabeza, es mejor ir por partes y ver en un principio lo fácil que va a resultar tener muchas partículas y moverlas sin dificultad. En la siguiente entra ya os prometo hacer un sistema usable.

 

Crear un Proyecto OpenGL

Como siempre vamos a empezar desde 0 y es creando un proyecto en OpenGL Es, abrimos el XCode vamos a File > New Proyect y seleccionamos un proyecto “OpenGL ES Application“, pulsamos el botón choose y le damos el nombre que nos interese:

Nuestra base de Sprite

Para empezar partimos de nuestro sample Sprites en OGL para tener las rutinas básicas para dibujar Sprites en 2D por pantalla. De todos modos al final del tuto se incluyen tanto el .m como el .h, aunque igualmente deberíais echarle un vistazo porque aquí no explico como agregar el framework necesario ni como adjuntar la imagen que usaremos.

Particles and Dots

La lógica al crear cualquier sistema de partículas será siempre el de tener una clase principal que hará de contenedor de las partículas, sobre está clase será donde crearemos las partículas, desde donde se cargarán las texturas y desde donde se dibujarán. Esta clase tendrá un array con todas las partículas. Nunca trabajéis con partículas dinámicas, se supone que cuando se usan partículas para simular cualquier efecto o simplemente para añadir vistosidad a una aplicación vamos a estar continuamente creando y destruyéndolas por lo que no es nada optimo tirar de peticiones de memoria para esos casos, plantearos siempre un número máximo de partículas y crear un array de tamaño fijo.

Cada particula tendrá siempre una variable booleana que indica si la partícula está en uso o no (‘live’ suele ser un nombre bastante descriptivo). Cuando el sistema necesita una partícula recorre el array buscando una partícula muerta y nos la da … si no encuentra ninguna no deberia pasar nada, simplemente no se crea la partícula y listo.

De momento empezaremos viendo nuestra clase Particles:

Particles: h and m

Esto es nuestra cabecera del sistema de partículas, vemos que nos hemos puesto un máximo de 64 partículas, tenemos una declaración para la textura, y el array de la clase Dot (cada una de las partículas).
Y la implementación es de lo mas sencillo que vais a encontrar. Como veis esta clase solo inicializa los items del array, le da el touch a cada punto y los dibuja.

Lo del Touch era una sorpresa, jeje, vamos a dibujar los puntos en pantalla pero tiene algo mas de gracia si hacemos que interactuen al tocar la pantalla. Pues bien … nuestro sistema de partículas (como hemos dicho al principio) solo hará de contenedor, como podeis ver al hacer un touch no evaluamos nada, simplemente le damos ese touch a todas las partículas y que sean ellas las que decidan si hacen algo.

Siempre que podáis delegar sobre clases inferiores mucho mejor para todos, imaginar que en un futuro vamos a tener particulas que se ven afectada por el touch, y otras que no, mediante esta filosofía no tendríamos ningún problema, porque será la partícula quien decida lo que hace. Si en nuestra clase ‘Particles’ hubiéramos tomado alguna decisión ya estaríamos limitados a que todas las partículas se comportasen igual.

 Particles.m (892 Bytes)
 Particles.h (419 Bytes)
 Particles-1.png (31.54 Kb)

Dots: h and m

Para cada particula podemos ver las propiedades que tiene y como casi todos sus métodos son para establecer esas propiedades (a pesar de que en este ejemplo no los vamos usar desde el contenedor).

Así que vamos a ir a la parte de la implementación que requiera algo más de explicación:

Esto podría ser nuestro constructor ya que inicializa la partícula en pantalla, nos interesa que sea un método aparte y no el constructor porque lo vamos a llamar cada vez que queramos resetear una partícula. Como veis pilla casi todo de forma aleatoria, lo único que deberíamos resaltar es que mediante una booleana que le damos como parámetro le indicamos si queremos que la partícula nazca por la pantalla o fuera de ella. Así por ejemplo todas las partículas se crearán por primera vez dentro de la pantalla, pero luego al resetearlas las pondremos fuera de pantalla.

Touching particles

Este metodo se llama para cada partícula cuando se toca la pantalla, lo que hace es medir la distancia entre el punto donde tocamos y la partícula (no tiene en cuenta el radio .. aunque seria muy facil de implementar) y si se encuentra a una distancia menor de 40 pixels desplaza la partícula (ponemos en dx y dy el factor de separación que hay en el ejex y en el ejey respectivamente, así luego haremos que la partícula se desplace en función de la dirección inversa a donde se ha tocado)

Un detalle importante a la hora de medir distancias entre 2 puntos: todos sabemos (o deberiamos) que la distancia entre 2 puntos es la raíz cuadrada del cuadrado de sus componentes sqrt(x*x+y*y), hasta ahi todo es fácil, pero se puede ganar algo de tiempo si obviamos el sqrt, y en lugar de esperar un resultado de 45 pixels si hiciéramos la raíz, trabajar con 45*45, es lo mismo decir sqrt(x^2+x^2)<45 que x^2+y^2<45*45

Drawing

En primer lugar mirar como la posición x e y se desplazan en funcion de dx y dy que se establecian con el touch, y luego esas variables dx y dy se van multiplicando con 0.7f para que paso a paso se vayan desacelerando. Luego la posicion y se va decrementando en funcion de vy, osea .. se mueven todas parriba. Y finalmente comprobamos cuando las partículas quedan fuera de pantalla para crearlas de nuevo.

 Dot.m (2.15 Kb)
 Dot.h (791 Bytes)

Lo unico que debemos indicar en nuestro método ‘render’ es que hemos separado los métodos setTexture y setFrame, ya que todas las partículas usan la misma textura y no es nada lógico activar la textura con cada partícula …. una buena (muy muy muy buena) forma de optimizar esto es dibujar las partículas agrupadas por el frame que usan, así podríamos activar el frame 0 y dibujar solo las partículas que usen ese frame, y así sucesivamente.

 GL.m (4.93 Kb)
 GL.h (649 Bytes)

EAGLView

Empezamos por añadir estas variables en EAGLView.h

Y seguimos con el .m, lo primero que vamos a hacer es meter los métodos para manejar el touch de la pantalla, esto es una versión reducida de lo que ya hicimos en nuetro Touch-sample:

Y a continuación viene la inicialización que se encarga de crear nuestra clase de partículas:

Y finalmente nuestro método Draw solo haría esto:

 EAGLView.m (5.81 Kb)
 EAGLView.h (1.22 Kb)

You may also like...

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *