Decora tu menú



Crearemos un menú en C++ y Allegro 5 utilizando la clase botón se se creó en un  curso anterior.

Si deseas ver el curso sobre la clase botón haz clic aquí.



El menú que se va a realizar es el que sale en el video.


El Código

#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_font.h>
int pantallax = 800;
int pantallay = 450;
ALLEGRO_FONT* font;
ALLEGRO_FONT* font2;
ALLEGRO_MOUSE_STATE ratonEstado;
class ALLEGRO_MIBOTON
{
    int x, y;
    int alto;
    int ancho;
    const char* texto;
    ALLEGRO_FONT* fuente;
public:
    void crea(int _x, int _y, ALLEGRO_FONT* font, const char* _texto)
    {
        fuente = font;
        x = _x;
        y = _y;
        texto = _texto;
        alto = al_get_font_line_height(fuente) + 8;
        ancho = al_get_text_width(fuente, texto) + 20;
    }
    void pinta()
    {
        ALLEGRO_COLOR grey;
        ALLEGRO_COLOR grey2;
        ALLEGRO_COLOR grey3;
        ALLEGRO_COLOR black;
        ALLEGRO_COLOR white;
        grey = al_map_rgb(0xe0, 0xe0, 0xe0);
        grey2 = al_map_rgb(0xc0, 0xc0, 0xc0);
        grey3 = al_map_rgb(0x90, 0x90, 0x90);
        black = al_map_rgb(0, 0, 0);
        white = al_map_rgb(155, 155, 155);
        if (ratonEstado.x >= x && ratonEstado.x < x + ancho + 1 && ratonEstado.y >= y && ratonEstado.y < y + alto + 1)
        {
            if (al_mouse_button_down(&ratonEstado, 1))
            {
                //pulsa el raton
                al_draw_text(fuente, black, x + 9.5, y, 0, texto);
            }
            else
            {
                // sin pulsar      
                al_draw_text(fuente, white, x + 9.5, y, 0, texto);
            }
        }
        else
        {
            al_draw_text(fuente, black, x + 9.5, y, 0, texto);
        }      
    }
    bool pulsado()
    {
        return (ratonEstado.x >= x && ratonEstado.x < x + ancho + 1 && ratonEstado.y >= y && ratonEstado.y < y + alto + 1) && al_mouse_button_down(&ratonEstado, 1);
    }
};
ALLEGRO_MIBOTON opcionesMenu[4];

struct {
    int FPS;
    ALLEGRO_EVENT_QUEUE* Mis_eventos;
    ALLEGRO_COLOR fondo;
} sistema;
void dibuja()
{
    al_clear_to_color(sistema.fondo);
    for (int i = 0; i < 4; i++)
    {
        opcionesMenu[i].pinta();
    }
    al_draw_text(font, al_map_rgb(50, 0, 0), 57, 382, 0, "KodayRPG 2020");
    al_draw_text(font, al_map_rgb(250, 150, 0), 55, 380, 0, "KodayRPG 2020");
    
    if (opcionesMenu[1].pulsado())
    {
        al_draw_text(font2, al_map_rgb(230, 200, 0), 295, 80, 0, "Has pulsado Opcion 1");
    }
    if (opcionesMenu[2].pulsado())
    {
        al_draw_text(font2, al_map_rgb(230, 200, 0), 295, 80, 0, "Has pulsado Opcion 2");
    }
    // muestra por pantalla
    al_flip_display();
}
void jugar(ALLEGRO_EVENT evento)
{
    ALLEGRO_MIBOTON volver;
    volver.crea(350, 90, font2, " Volver ");
    bool salir = false;
    while (!salir)
    {
        al_clear_to_color(al_map_rgb(240, 200, 0));     
        volver.pinta();
        al_flip_display();
        
        al_wait_for_event(sistema.Mis_eventos, &evento);
        // pasa un tiempo determinado
        if (evento.type == ALLEGRO_EVENT_TIMER)
        {
            al_get_mouse_state(&ratonEstado);
        }
        if (volver.pulsado()) salir = true;
    }
}
void update(ALLEGRO_EVENT evento)
{
    if (opcionesMenu[0].pulsado())
    {
      // que hacer cuando se pulsa jugar
        jugar(evento);
    }
    if (opcionesMenu[1].pulsado())
    {
        // hacer cuando se pulsa opcion 1
    }
    if (opcionesMenu[2].pulsado())
    {
        // hacer cuando se pulsa opcion 2
    }
}

void juego()
{
    font = al_load_ttf_font("datos/neuropol.ttf", 64, 0);
    font2 = al_load_ttf_font("datos/Dimbo.ttf", 32, 0);
    opcionesMenu[0].crea(350, 130, font2, " JUGAR ");
    opcionesMenu[1].crea(340, 180, font2, " OPCION 1 ");
    opcionesMenu[2].crea(340, 230, font2, " OPCION 2 ");
    opcionesMenu[3].crea(350, 280, font2, " SALIR ");
    ALLEGRO_EVENT evento;
    bool repetir = true;
    bool dibujar = true;
    while (repetir)
    {
        // Pinta si es dibuja y esta vacia la lista de eventos
        if (dibujar && al_event_queue_is_empty(sistema.Mis_eventos))
        {
            dibuja();
            dibujar = false;
        }
        // esperamos a que ocurra un evento
        al_wait_for_event(sistema.Mis_eventos, &evento);
        // se ha cerrado la ventana
        if (evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
        {
            repetir = false;
        }
        // se ha pulsado ESC
        if (evento.type == ALLEGRO_EVENT_KEY_DOWN)
        {
            if (evento.keyboard.keycode == ALLEGRO_KEY_ESCAPE )
            {
                repetir = false;
            }
        }
        // pasa un tiempo determinado
        if (evento.type == ALLEGRO_EVENT_TIMER)
        {
            dibujar = true;
            update(evento);
            al_get_mouse_state(&ratonEstado);
            if (opcionesMenu[3].pulsado() )
            {
                repetir = false;
            }
        }
    }
    al_destroy_font(font2);
    al_destroy_font(font);
}

int main(void)
{
    // inicializamos las librerías
    al_init();
    al_init_primitives_addon();
    al_init_font_addon();
    al_init_ttf_addon();
    al_init_image_addon();
    al_install_keyboard();
    al_install_mouse();
    ALLEGRO_DISPLAY* display = al_create_display(800, 450);
    ALLEGRO_TIMER* timer = NULL;
    al_set_window_title(display, "KodayRPG");
    
    sistema.fondo = al_map_rgb(40, 40, 120);
    sistema.FPS = 60;
    timer = al_create_timer(1.0 / sistema.FPS);
    // creo lista de eventos
    sistema.Mis_eventos = al_create_event_queue();
    // asigno eventos a la lista de eventos
    al_register_event_source(sistema.Mis_eventos, al_get_keyboard_event_source());
    al_register_event_source(sistema.Mis_eventos, al_get_display_event_source(display));
    al_register_event_source(sistema.Mis_eventos, al_get_timer_event_source(timer));
    al_start_timer(timer);
    juego();
    
    al_destroy_display(display);
}



Paso a paso


Lo primero de todo es incluir las librerías que vamos a utilizar en este ejemplo, concretamente las de allegro 5.
A continuación tenemos algunas variables globales y la declaración de la clase botón.  Si estas interesado en saber como funciona mira el tutorial de sobre la clase botón.
Se define una matriz llamada opcionesMenu de cuatro elementos, de la clase botón.

ALLEGRO_MIBOTON opcionesMenu[4];


El método dibuja, se encarga de pintar el menú y finalmente mostrarlo todo por pantalla. Como se utiliza una matriz, para almacenar los botones, a la hora de mostrarlo se ha realizado un bucle for que recorre toda la matriz y va pintando uno a no.

    for (int i = 0; i < 4; i++)
    {
        opcionesMenu[i].pinta();
    }


El método jugar, muestra una pantalla vacía con un único botón en pantalla para volver al menú, aquí irá el juego en cuestión que se realice.
El método update se encarga de comprobar los botones que se han pulsado, es por tanto que se deberán hacer las llamadas a las pantallas que se desean acceder, cuando se pulse el botón correspondiente. Está marcado con comentarios donde poner las distintas opciones.
El método juego se encarga de inicializar todas las variables que se van a utilizar en este caso, se inicializan las fuentes utilizadas, se crean los cuatros botones, y variables de control.

    opcionesMenu[0].crea(350, 130, font2, " JUGAR ");
    opcionesMenu[1].crea(340, 180, font2, " OPCION 1 ");
    opcionesMenu[2].crea(340, 230, font2, " OPCION 2 ");
    opcionesMenu[3].crea(350, 280, font2, " SALIR ");

Recuerda que la clase botón para crearlo debes de pasar como parámetro la posición donde quieres que aparezca x,y, el tipo de fuente que vas a utilizar, y el texto que contiene el botón. En comparación con la clase original en este ejemplo no se pinta el recuadro del botón.

El bucle principal se estará repitiendo hasta que se haga clic en la x o se pulse la tecla ESC, y además cuando se pulse el botón salir. Al igual que los anteriores cursos el funcionamiento es el mismo, espera a que ocurra un evento y según el evento realiza la acción correspondiente.
En la función principal main, se inicializa todo el entorno de la librería Allegro 5, y se crea la lista de eventos que debe de comprobar cada cierto tiempo.

Hasta aquí tendríamos un menú con el fondo en azul, ahora veremos como decorarlo para darle mejor aspecto a nuestro menú. Es tan sencillo como añadirle una imagen de fondo y para ello debemos hacer los siguientes cambios al código.

struct {
    int FPS;
    ALLEGRO_EVENT_QUEUE* Mis_eventos;
    ALLEGRO_COLOR fondo;
    ALLEGRO_BITMAP* img;
} sistema;

Se añade al struct una nueva variable que almacenará la imagen de fondo, llamada img.

void dibuja()
{
    al_clear_to_color(sistema.fondo);
    al_draw_bitmap(sistema.img,0,0,0);
    for (int i = 0; i < 4; i++)
    {
        opcionesMenu[i].pinta();
    }
    al_draw_text(font, al_map_rgb(50, 0, 0), 57, 382, 0, "KodayRPG 2020");
    al_draw_text(font, al_map_rgb(250, 150, 0), 55, 380, 0, "KodayRPG 2020");
    
    if (opcionesMenu[1].pulsado())
    {
        al_draw_text(font2, al_map_rgb(230, 200, 0), 295, 80, 0, "Has pulsado Opcion 1");
    }
    if (opcionesMenu[2].pulsado())
    {
        al_draw_text(font2, al_map_rgb(230, 200, 0), 295, 80, 0, "Has pulsado Opcion 2");
    }
    // muestra por pantalla
    al_flip_display();
}

En el método dibuja se añade al_draw_bitmap() para pintar la imagen de fondo, si se desea se puede suprimir el comando anterior al_clear_to_color() ya que no se va a ver el fondo, sino la imagen.

void jugar(ALLEGRO_EVENT evento)
{
    ALLEGRO_BITMAP* img1 = al_load_bitmap("datos/menu2.png");
    ALLEGRO_MIBOTON volver;
    volver.crea(350, 90, font2, " Volver ");
    bool salir = false;
    while (!salir)
    {
        al_clear_to_color(al_map_rgb(240, 200, 0));
        al_draw_bitmap(img1, 0, 0, 0);
        volver.pinta();
        al_flip_display();
        
        al_wait_for_event(sistema.Mis_eventos, &evento);
        // pasa un tiempo determinado
        if (evento.type == ALLEGRO_EVENT_TIMER)
        {
            al_get_mouse_state(&ratonEstado);
        }
        if (volver.pulsado()) salir = true;
    }
}


En el método jugar también se añade una imagen de fondo que se almacena en img1, aquí al igual que antes se puede suprimir el comando al_clear_to_color().

int main(void)
{
    // inicializamos las librerías
    al_init();
    al_init_primitives_addon();
    al_init_font_addon();
    al_init_ttf_addon();
    al_init_image_addon();
    al_install_keyboard();
    al_install_mouse();
    ALLEGRO_DISPLAY* display = al_create_display(800, 450);
    ALLEGRO_TIMER* timer = NULL;
    al_set_window_title(display, "KodayRPG");
    
    sistema.img = al_load_bitmap("datos/menu1.png");
    sistema.fondo = al_map_rgb(40, 40, 120);
    sistema.FPS = 60;
    timer = al_create_timer(1.0 / sistema.FPS);
        // creo lista de eventos
    sistema.Mis_eventos = al_create_event_queue();
    // asigno eventos a la lista de eventos
    al_register_event_source(sistema.Mis_eventos, al_get_keyboard_event_source());
    al_register_event_source(sistema.Mis_eventos, al_get_display_event_source(display));
    al_register_event_source(sistema.Mis_eventos, al_get_timer_event_source(timer));
    al_start_timer(timer);
    juego();
    
    al_destroy_display(display);
}


En la función main, se añade  sistema.img = al_load_bitmap("datos/menu1.png"); , que se encarga de cargar la imagen de fondo, en este caso es la imagen menu1.png que se encuentra en la carpeta datos.

Y con todo esto ya tienes un menú decorado tal y como se muestra en el video.



Haz click aquí si quieres descargar el código con las imágenes y las fuentes utilizadas.

SHARE
    Blogger Comment

0 comentarios:

Publicar un comentario