En este ejemplo se muestran dos espejos, uno grande en el lateral derecho y otro mas pequeño en el muro de arriba.
Para crear el efecto de espejo pequeño se realizan dos tareas:
- Por un lado se crea una copia del suelo que se va a reflejar en el espejo, y esta imagen se voltea de forma vertical.
- Y por otro lado se crea la imagen reflejo del personaje. Esta imagen es la misma del personaje pero con las direcciones invertidas. Además la imagen reflejo esta volteada de forma horizontal.
Para crear el efecto de espejo grande es mas sencillo, pues toma una copia de toda la imagen que se quiere reflejar y esta imagen se voltea de forma horizontal.
Para un correcto funcionamiento el orden de dibujar los espejos debe ser el primero el espejo pequeño, y luego el grande lateral, ya que este último reflejará también el contenido del espejo pequeño.
al_set_target_bitmap(espejo2); al_draw_bitmap_region(buffer, 65, 138, 350, 90, 0, 0, ALLEGRO_FLIP_VERTICAL); // invertir direccion para el personaje espejo if (dir == 3) dirEsp = 0; if (dir == 0) dirEsp = 3; if (dir == 1) dirEsp = 2; if (dir == 2) dirEsp = 1; al_draw_bitmap_region(personaje, paso * 48, dirEsp * 48, 48, 48, x - 65, 135 - y, ALLEGRO_FLIP_HORIZONTAL);
Este código se encarga del primer espejo, el pequeño. En la primera línea se establece la imagen espejo2 como el bitmap con el que vamos a trabajar, todas las instrucciones que se realicen con imágenes se realizaran sobre la imagen espejo2.
En la segunda línea se crea una copia de la imagen buffer, exactamente una región que viene delimitada por la coordenada de inicio (65,138) y por un tamaño (350 de ancho y 90 de alto). Y esta imagen se pega en espejo2 en la coordenada (0,0), y según el flag indicado la imagen estará volteada de forma vertical.
Las siguientes líneas se encargan de invertir la dirección del personaje espejo, y es almacenada en la variable dirEsp.
En la última línea se dibuja el personaje invertido volteado de forma horizontal sobre la imagen espejo2. Llegado a este punto la imagen espejo2 contiene toda la imagen que se va a mostrar del espejo pequeño.
al_set_target_bitmap(buffer2); al_draw_bitmap_region(buffer, 100, 0, 350, 600, 0, 0, ALLEGRO_FLIP_HORIZONTAL); al_set_target_bitmap(buffer); al_draw_tinted_bitmap_region(buffer2, al_map_rgba_f(1, 1, 1, .9), 0, 0, 350, 600, 449, 0, 0);
Con el primer comando, indicamos que se va a trabajar con la imagen buffer2, esta imagen contendrá la imagen reflejo del espejo grande.
Con el segundo comando se realiza una copia del contenido de la imagen buffer, partiendo de la posición (100,0), con un tamaño de 350 de ancho y 600 de alto. Y se pega en la imagen buffer2 en la posición (0,0) volteada de forma horizontal.
Luego se vuelve a indicar que se trabaja con la imagen buffer. Y con el último comando se pega el contenido de buffer2 sobre buffer, partiendo de la posición (0,0), con un tamaño de 350 de ancho y 600 de alto, en la posición (449,0), tintado con un 0.9 de transparencia.
El Código
/* Name: Efecto Espejo Author: Yadok - KODAYGAMES Date: 05/10/21 Web: http://devcpp-allegro.blogspot.com/ */ #define FPS 60 // pixeles que se desplaza por segundo #define Velocidad 180 int main() { al_init(); al_install_keyboard(); if (!al_init_image_addon()) { return -1; } ALLEGRO_DISPLAY* pantalla = al_create_display(800, 600); ALLEGRO_BITMAP* buffer = al_create_bitmap(800, 600); ALLEGRO_BITMAP* buffer2 = al_create_bitmap(350, 600); ALLEGRO_BITMAP* espejo2 = al_create_bitmap(350, 90); ALLEGRO_BITMAP* fondo = al_load_bitmap("fondo.png"); ALLEGRO_BITMAP* espejo = al_load_bitmap("frontales.png"); al_set_window_title(pantalla, "Efecto Espejo"); 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; int dirEsp = 3; int desplazamiento = Velocidad / FPS; // inicializar vbles x = 50; y = 200; salir = false; // creo lista de eventos Mis_eventos = al_create_event_queue(); // 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_set_target_bitmap(buffer); al_clear_to_color(al_map_rgb(125, 155, 225)); al_draw_bitmap(fondo, 0, 0, 0); if (x > 400) x = 400; if (x < 0) x = 0; if (y < 100) y = 100; if (y > 550) y = 550; al_set_target_bitmap(espejo2); al_draw_bitmap_region(buffer, 65, 138, 350, 90, 0, 0, ALLEGRO_FLIP_VERTICAL); // invertir direccion para el personaje espejo if (dir == 3) dirEsp = 0; if (dir == 0) dirEsp = 3; if (dir == 1) dirEsp = 2; if (dir == 2) dirEsp = 1; al_draw_bitmap_region(personaje, paso * 48, dirEsp * 48, 48, 48, x - 65, 135 - y, ALLEGRO_FLIP_HORIZONTAL); al_set_target_bitmap(buffer); al_draw_tinted_bitmap_region(espejo2, al_map_rgba_f(.9, .9, 1, 1), 0, 0, 350, 90, 65, 30, 0); al_set_blender(ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_INVERSE_ALPHA ); // sombra al_draw_tinted_bitmap_region(personaje, al_map_rgba_f(1, 1, 1, 0.25), paso * 48, dir * 48, 48, 48, x, y+44 , ALLEGRO_FLIP_VERTICAL); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); al_draw_bitmap_region(personaje, paso * 48, dir * 48, 48, 48, x, y, 0); al_set_target_bitmap(buffer2); al_draw_bitmap_region(buffer, 100, 0, 350, 600, 0, 0, ALLEGRO_FLIP_HORIZONTAL); al_set_target_bitmap(buffer); al_draw_tinted_bitmap_region(buffer2, al_map_rgba_f(1, 1, 1, .9), 0, 0, 350, 600, 449, 0, 0); al_set_target_backbuffer(pantalla); al_draw_bitmap(buffer, 0, 0, 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_W) || al_key_down(&teclado, ALLEGRO_KEY_UP)) { pas = true; y= y - desplazamiento; } if (al_key_down(&teclado, ALLEGRO_KEY_S) || al_key_down(&teclado, ALLEGRO_KEY_DOWN)) { pas = true; y= y + desplazamiento; } if (al_key_down(&teclado, ALLEGRO_KEY_A) || al_key_down(&teclado, ALLEGRO_KEY_LEFT)) { pas = true; x= x - desplazamiento; } if (al_key_down(&teclado, ALLEGRO_KEY_D) || al_key_down(&teclado, ALLEGRO_KEY_RIGHT)) { pas = true; x= x + desplazamiento; } if (pas) { paso++; if (paso > 2) paso = 0; } } // liberar recursos utilizados al_destroy_bitmap(fondo); al_destroy_bitmap(buffer); al_destroy_bitmap(buffer2); al_destroy_bitmap(espejo); al_destroy_bitmap(espejo2); al_destroy_bitmap(personaje); al_destroy_event_queue(Mis_eventos); al_destroy_display(pantalla); return 0; }
A este código solo le falta incluir las librerías, allegro5/allegro.h y allegro5/allegro_image.h, que se deben de poner al principio del código antes de los #define.
Al principio se inicializa la librería allegro, y carga las imágenes que va a utilizar: fondo.png, frontales.png y chica.png, y se declaran las variables que se utilizarán.
El bucle principal se estará repitiendo mientras salir sea false. Al principio todo con respecto a las imágenes se realiza sobre la imagen llamada buffer, y al final se muestra por pantalla. El funcionamiento principal del código es igual al ejemplo de las transparencias.
El movimiento del personaje se puede realizar mediante las teclas W,A,S,D, o las teclas de las flechas del cursor.
Para finalizar el programa puedes pulsar la tecla ESC o pulsar sobre la X de la ventana. Al terminar el programa elimina todas las imágenes utilizadas.
Si deseas el código completo y las imágenes utilizadas descarga el archivo ZIP haciendo clic aquí.
0 comentarios:
Publicar un comentario