martes, 2 de abril de 2013

Como se hizo ... la animacion lluvia

A continuación se explicará como se hizo el siguiente video.






Este ejemplo muestra la utilización de las transparencias. Simplificando el problema, y sin tener en cuenta la reproducción del audio, el video consta de tres partes:
  1.  Se oscurece la escena y desaparece las sombras.
  2.  Se inicia la lluvia, y el terreno empieza a oscurecer por las gotas caídas.
  3.  suena el trueno, empiezan a hacerse charcos de agua.


Para este proyecto se van a utilizar cuatro imagenes:
imagen 1: suelo con sombras ( terreno1.bmp ) - variable utilizada con el nombre de  suelo
imagen 2: suelo sin sombras ( terreno2.bmp ) - nombre variable: suelo2
imagen 3: hoja ( hoja.bmp ) - nombre variable : hoja
imagen 4: gotas de agua cayendo ( gotas.bmp ) - nombre variable : agua






Parte 1
Para esta escena se utilizan dos imágenes una con sombra y otra sin sombra.
Se crea un fundido entre las dos imágenes partiendo de la imagen con sombra, se va sustituyendo por la que no tiene sombra, de esta forma se crea el efecto de que se esta oscureciendo.

 
    for (int i=1; i <= 255; i++){
       //se pone la primera imagen en el buffer
       blit(suelo, buffer, 0, 0, 0, 0, 320, 240);

       // a continuacion se va sustituyendo la imagen por la otra
       set_trans_blender(0, 0, 0, i);
       drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);        
       draw_trans_sprite(buffer, suelo2, 0, 0);
       solid_mode();
       // muestra por pantalla
       blit(buffer, screen, 0, 0, 0, 0, 320, 240);
       rest(5);
    }

Se realiza un bucle que va de 1 a 255, que es el grado de transparencia, que se utiliza en el comando set_trans_blender(). Se pinta la imagen suelo primero y luego se va tapando con la imagen semitransparente suelo2, y finalmente se muestra el resultado por pantalla. Como en este ejemplo no se controla el numero de frames que se muestran por segundos se utiliza el comando rest() para pausar un poco la animación, dependiendo del equipo en el que se ejecute la animación, se verá mas o menos rápida.

Comandos:
 
blit(suelo, buffer, 0, 0, 0, 0, 320, 240);
Pone en  buffer el contenido de la imagen suelo

set_trans_blender(0, 0, 0, i);
Establece el grado de transparencia, indicada por la variable i que esta en el parámetro del canal alfa.

drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
Cambia el modo de dibujado, indicando que se va a dibujar con transparencias

draw_trans_sprite(buffer, suelo2, 0, 0);
Pone la imagen suelo2 sobre la imagen buffer de forma transparente, con un grado de transparencia según los comandos anteriores.

solid_mode();
Vuelve al modo normal, sin transparencias

blit(buffer, screen, 0, 0, 0, 0, 320, 240);
Vuelca el contenido de buffer a screen para mostrarlo por pantalla.

rest(5);
Realiza una pequeña pausa, según el numero indicado. En este caso una pausa de 5 milisegundos.

Parte 2
Oscurecer el terreno mediante pequeños círculos, que se pintan encima de forma aleatoria y semitransparente.
A la misma vez que se va realizando este proceso de pintar los círculos se debe mostrar la animación de las gotas moviendose hacia abajo, para ello se utiliza la imagen de las gotas, que se superpone sobre la imagen resultante.

 clear_to_color(buffer2, 0xffffff);
    for( int c=1; c <= 40; c++){
        blit(suelo2, buffer, 0, 0, 0, 0, 320, 240);
        for ( int i=1; i < 6; i++ ){
           ellipsefill(buffer2, rand()%320, rand()%240,
                        7+c*2+rand()%5, 5+c+rand()%4, 0x111daa);
        }
        set_multiply_blender(128, 128, 128, 128);
        drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0); 
        draw_trans_sprite(buffer, buffer2, 0, 0);

        solid_mode();
        masked_blit(hoja, buffer, 0, 0, 0, 0, 320, 240);
        
        set_trans_blender(0, 0, 0, 24);
        drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
        draw_trans_sprite(buffer, agua, 0, -240+ 6*c);
        
        solid_mode();
        blit(buffer, screen, 0, 0, 0, 0, 320, 240);
        rest(50); 
    }

Este código realiza un bucle principal que se repite 40 veces. En cada iteración se pinta el suelo2 en el buffer y sobre el buffer2 se dibujan 6 elipses con el segundo bucle. Después se dibuja de forma transparente el contenido del buffer2 sobre buffer. Luego se coloca la imagen de la hoja sobre el buffer. Y sobre todo esto se pone la imagen agua que va cambiando de posición según el eje y. Finalmente se muestra por pantalla.

Comandos:
NOTA:  Se detallan solo los comandos que aparecen por primera vez.

clear_to_color(buffer2, 0xffffff);
Rellena el contenido de buffer2 con el color blanco.


ellipsefill(buffer2, rand()%320, rand()%240,
              7+c*2+rand()%5, 5+c+rand()%4, 0x111daa);
Dibuja un elipse relleno de un color 0x111daa, en una posicion aleatoria y con unos tamaños variables.

set_multiply_blender(128, 128, 128, 128);
Establece el modo de transparencia multiply y el grado que lo pone al 50% de transparencia.

masked_blit(hoja, buffer, 0, 0, 0, 0, 320, 240);
Pinta el contenido de hoja sobre buffer, pero sin pintar el color rosado 0xFF00FF,



Parte 3
Partiendo de la imagen anterior obtenida oscurecida y manteniendo la animación del agua cayendo, ya solo falta volver a crear de forma aleatoria pequeños círculos que simulen las ondas que se crean al caer las gotas sobre el agua.

    int cont = 0;
    for ( int c=1; c<= 40; c++){

        
        int x1 = rand()%320;                
        int y1 = rand()%240; 
        int x2 = rand()%320;        
        int y2 = rand()%240;   
        int x3 = rand()%320;        
        int y3 = rand()%240;   
        int x4 = rand()%320;        
        int y4 = rand()%240;   
        int x5 = rand()%320;        
        int y5 = rand()%240;                   
         
        for ( int i=1; i < 20; i++){
            blit( buffer2, buffer, 0, 0, 0, 0, 320, 240);
            
            set_multiply_blender(0, 0, 0, 96);
            drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
            ellipse(buffer, x1, y1, i*2, i, 0x111daa);
            ellipse(buffer, x2, y2, i*2, i, 0x111daa);  
            ellipse(buffer, x3, y3, i*2, i, 0x111daa);   
            ellipse(buffer, x4, y4, i*2, i, 0x111daa);  
            ellipse(buffer, x5, y5, i*2, i, 0x111daa);                    
            ellipse(buffer, x1+5, y2-5, i*3, i, 0x111daa);  
            ellipse(buffer, x2-5, y4+5, i*3, i*2, 0x111daa); 
            ellipse(buffer, x3+5, y5-5, i*3, i, 0x111daa);
            ellipse(buffer, x4-5, y2+5, i*3, i*2, 0x111daa); 
            ellipse(buffer, x5+5, y1-5, i*4, i*2, 0x111daa);            

            solid_mode();
            masked_blit(hoja, buffer, 0, 0, 0, 0, 320, 240);            
            
            set_trans_blender(0, 0, 0, 24);
            drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
            cont+=7;
            if ( cont > 240 ) cont-=240;
            draw_trans_sprite(buffer, agua, 0, -240+cont );   
            
            solid_mode();
            blit(buffer, screen, 0, 0, 0, 0, 320, 240);
            rest(15);                      
                      
        }
    }

Se dibujan 10 elipses por cada iteración del bucle interno que se repite 19 veces. Y todo esto se repite 40 veces. Estas elipses se dibujan directamente sobre la variable buffer, al igual que la imagen hoja. Y sobre todo esto se pone la imagen agua que va cambiando de posición según el eje y.

Comandos:
NOTA:  Se detallan solo los comandos que aparecen por primera vez.
ellipse(buffer, x1, y1, i*2, i, 0x111daa);
Dibuja un elipse de color 0x111daa sobre la imagen buffer, en la posicion indicada por las variables x1,y1. Con un tamaño de ancho i*2, y de alto i

cont+=7;
if ( cont > 240 ) cont-=240;
Con la variable cont y la condición controla la animación del agua bajando.

Para quien quiera descargar este proyecto completo con imágenes y todo pulse aqui.

Esto es una forma de realizar el proyecto, lo cual no quiere decir que sea la mejor o sea exactamente como se hizo ya que se ha simplificado muchas cosas para centrarnos en la utilización de las transparencias.

2 comentarios:

  1. que librerias uso y por favor podrias ser mas explicativo oh hacer mejor un tutorial esto si es interesante

    ResponderEliminar

Related Posts Plugin for WordPress, Blogger...