jueves, 6 de mayo de 2021

Transparencia con Allegro 5

 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.

  1. al_set_blender(ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_INVERSE_ALPHA );
  2. 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);
  3. 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);
  4. al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
  5. 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);
  6. 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.

Para descarga todo el ejemplo ( código e imágenes )

No hay comentarios:

Publicar un comentario

Antes de publicar un comentario

Todos los comentarios que se realicen en el blog son moderados.

Debido a esto es muy probable que tu comentario no aparezca de inmediato ya que previamente debe ser revisado para evitar un mal uso (SPAM).

Podrán realizar comentario cualquiera que tenga una cuenta de Google.

Related Posts Plugin for WordPress, Blogger...