sábado, 7 de noviembre de 2020

Crear un menú en C++



Aprovechando la clase botón del curso anterior, ahora se va a hacer un menú. 

Este menú tendrá cuatro opciones:

  1. Jugar
  2. Opcion 1
  3. Opcion 2
  4. Salir
El manejo del menú se realiza mediante el ratón, tal y como se muestra en el siguiente 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.


Pincha aquí para descargar el código y las fuentes utilizadas en el ejemplo.

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...