La librería Allegro 5 permite el manejo de imágenes en formato PNG, lo cual permite imágenes con transparencias, en la versión 4 de Allegro solo puedes manejar imagenes BMP. Pero en este ejemplo se realiza la transparencia de la imagen mediante comandos.
Para crear las transparencias de este ejemplo en Allegro 5, se utilizarán los siguientes comandos: al_set_blender, al_draw_tinted_bitmap_region.
COMANDOS
al_set_blender
void al_set_blender(int op, int src, int dst)
Establece la función que se utilizará para mezclar las imagenes.
Combinando los colores de origen y destino según la función especificada.
El primer parámetro op, indicará la formula a utilizar por Allegro.
ALLEGRO_ADD
ALLEGRO_DEST_MINUS_SRC
ALLEGRO_SRC_MINUS_DEST
En el segundo y tercer parámetro los valores válidos son:
ALLEGRO_ZERO
ALLEGRO_ONE
ALLEGRO_ALPHA
ALLEGRO_INVERSE_ALPHA
Para mas información sobre este comando visite el manual de allegro 5.
https://www.allegro.cc/manual/5/al_set_blender
al_draw_tinted_bitmap_region
void al_draw_tinted_bitmap_region(ALLEGRO_BITMAP *bitmap,
ALLEGRO_COLOR tint,
float sx, float sy, float sw, float sh,
float dx, float dy, int flags)
Dibuja una región del mapa de bits dado en el mapa de bits de destino.
Parámetros:
sx - fuente x
sy - fuente y
sw - ancho de la región
sh - altura de la región
dx - destino x
dy - destino y
flags - puede tener varios valores:
0 - Lo dibuja tal cual.
ALLEGRO_FLIP_HORIZONTAL - gira la imagen de forma horizontal
ALLEGRO_FLIP_VERTICAL - gira la imagen de forma vertical
Para mas información sobre este comando visite el manual de allegro 5.
https://www.allegro.cc/manual/5/al_draw_tinted_bitmap_region
NUESTRO EJEMPLO
En nuestro ejemplo se muestra un personaje que se mueve por el escenario, en este escenario se crea el efecto como si hubiese un espejo al lado derecho.
A continuación se muestra el código del ejemplo, lo único que le falta son las llamadas a las librerías utilizadas (#include), en este caso son "allegro5/allegro.h" y "allegro5/allegro_image.h".
#define FPS 60 int main() { al_init(); al_install_keyboard(); if (!al_init_image_addon()) { return -1; } ALLEGRO_DISPLAY* pantalla = al_create_display(800, 600); ALLEGRO_BITMAP* fondo = al_load_bitmap("fondo.png"); ALLEGRO_BITMAP* espejo = al_load_bitmap("frontal.png"); al_set_window_title(pantalla, "Transparencias"); al_clear_to_color(al_map_rgb(125, 155, 225)); ALLEGRO_BITMAP* personaje = al_load_bitmap("chica.png"); ALLEGRO_KEYBOARD_STATE teclado; // defino lista de eventos ALLEGRO_EVENT_QUEUE* Mis_eventos; ALLEGRO_EVENT evento; bool salir; bool pas = false; int x, y; int paso = 0; int dir = 0; x = 50; y = 200; // creo lista de eventos Mis_eventos = al_create_event_queue(); salir = false; // asigno eventos a la lista de eventos al_register_event_source(Mis_eventos, al_get_keyboard_event_source()); al_register_event_source(Mis_eventos, al_get_display_event_source(pantalla)); while (!salir) { al_clear_to_color(al_map_rgb(125, 155, 225)); al_draw_bitmap(fondo, 0, 0, 0); // limitar el movimiento if (x > 400) x = 400; if (x < 0) x = 0; if (y < 100) y = 100; if (y > 550) y = 550; al_set_blender(ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_INVERSE_ALPHA ); al_draw_tinted_bitmap_region(personaje, al_map_rgba_f(1, 1, 1, 0.3), paso * 48, dir * 48, 48, 48, x, y+46 , ALLEGRO_FLIP_VERTICAL); al_draw_tinted_bitmap_region(personaje, al_map_rgba_f(1, 1, 1, 0.2), paso * 48, dir * 48, 48, 48, 802-x + 48, y+46, 3); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); al_draw_tinted_bitmap_region(personaje, al_map_rgba_f(1, 1, 1, 0.80), paso * 48, dir * 48, 48, 48, 802-x + 48, y, ALLEGRO_FLIP_HORIZONTAL); al_draw_bitmap_region(personaje, paso * 48, dir * 48, 48, 48, x, y, 0); al_draw_bitmap(espejo, 0, 0, 0); al_flip_display(); al_wait_for_event_timed(Mis_eventos, &evento, 1.0 / FPS); // se ha cerrado la ventana if (evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { salir = true; } pas = false; // se ha pulsado una tecla if (evento.type == ALLEGRO_EVENT_KEY_DOWN) { if (evento.keyboard.keycode == ALLEGRO_KEY_W || evento.keyboard.keycode == ALLEGRO_KEY_UP) { pas = true; dir = 3; } if (evento.keyboard.keycode == ALLEGRO_KEY_S || evento.keyboard.keycode == ALLEGRO_KEY_DOWN) { pas = true; dir = 0; } if (evento.keyboard.keycode == ALLEGRO_KEY_A || evento.keyboard.keycode == ALLEGRO_KEY_LEFT) { pas = true; dir = 1; } if (evento.keyboard.keycode == ALLEGRO_KEY_D || evento.keyboard.keycode == ALLEGRO_KEY_RIGHT) { pas = true; dir = 2; } if (evento.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { salir = true; } } al_get_keyboard_state(&teclado); if (al_key_down(&teclado, ALLEGRO_KEY_UP)) { pas = true; y=y-3; } if (al_key_down(&teclado, ALLEGRO_KEY_DOWN)) { pas = true; y=y+3; } if (al_key_down(&teclado, ALLEGRO_KEY_LEFT)) { pas = true; x=x-3; } if (al_key_down(&teclado, ALLEGRO_KEY_RIGHT)) { pas = true; x=x+3; } if (pas) { paso++; if (paso > 2) paso = 0; } } al_destroy_bitmap(personaje); al_destroy_event_queue(Mis_eventos); al_destroy_display(pantalla); return 0; }
Se inicializan las librerías allegro, y allegro_image, también el teclado y la pantalla. La pantalla se configura a una resolución de 800x600.
Se cargan las dos imágenes que se utilizan en el ejemplo, la imagen de fondo, y la imagen frontal que se utiliza para el espejo.
Con el comando al_set_window_title(pantalla, "Transparencias"), le indicamos el titulo de nuestra ventana llamada "Transparencias".
Se carga la imagen del personaje llamada "chica.png".
Se define la lista eventos, y las variables que utilizaran, salir para el control del bucle, x,y para la posición del personaje, paso y dir para la animación de la imagen del personaje.Y se inicializan.
En el bucle principal se pinta el fondo, se controla los límites del personaje. Se dibujan las sombras, el reflejo y el personaje, tambien la imagen espejo y se muestra por pantalla.
- al_set_blender(ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_INVERSE_ALPHA );
- al_draw_tinted_bitmap_region(personaje, al_map_rgba_f(1, 1, 1, 0.3), paso * 48, dir * 48, 48, 48, x, y+46 , ALLEGRO_FLIP_VERTICAL);
- al_draw_tinted_bitmap_region(personaje, al_map_rgba_f(1, 1, 1, 0.2), paso * 48, dir * 48, 48, 48, 802-x + 48, y+46, 3);
- al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- al_draw_tinted_bitmap_region(personaje, al_map_rgba_f(1, 1, 1, 0.80), paso * 48, dir * 48, 48, 48, 802-x + 48, y, ALLEGRO_FLIP_HORIZONTAL);
- al_draw_bitmap_region(personaje, paso * 48, dir * 48, 48, 48, x, y, 0);
Este trozo de código se encarga de dibujar al personaje, su sombra, su reflejo y la sombra del reflejo.
La primera línea de código hace que se añade el color negro a la imagen, manteniendo la transparencia.
La segunda y tercera línea se encargan de dibujar las sombras. Con este comando se esta troceando una imagen que contiene la animación del personaje, de manera que dependiendo de las variables paso y dir se obtiene un trozo concreto de la imagen con el tamaño de 48x48, y además se le está indicando mediante al_map_rgba_f(1, 1, 1, 0.3) el grado de transparencia, que viene indicado por el 0.3. Esto indica que esta a un 30% de visibilidad. Añadiéndole el parámetro ALLEGRO_FLIP_VERTICAL indicamos que la imagen se voltea en vertical.
Para poder utilizar las transparencias podemos utilizar cualquier comando que incluya la palabra tinted, como por ejemplo al_draw_tinted_bitmap.
La cuarta línea de código cambia el funcionamiento para que se pinte normal.
En la quinta línea se encarga de dibujar el reflejo del personaje, al cual pone algo transparente (concretamente un 80% de opacidad), se gira la imagen de forma horizontal.
Y en la sexta línea de código se dibuja al personaje, según paso y dir, con un tamaño de 48x48, en la posición x,y.
Con el comando al_wait_for_event_timed(Mis_eventos, &evento, 1.0 / FPS) espera a que ocurra alguno de los posibles eventos, en cuanto se activa alguno, continua.
A continuacíon se comprueba que evento se a activado, las teclas de movimiento o la tecla para salir "ESC".
Antes de finalizar hay que liberar la memoria.
No hay comentarios:
Publicar un comentario