Allegro.pas tutorial 1/es

From Free Pascal wiki
Jump to: navigation, search

Aquí se muestra cómo inicializar Allegro, abrir una ventana y esperar a que el usuario pulse el botón de cierre de la misma.

Crea el proyecto

Crea un nuevo Programa simple con el menú Proyecto > Nuevo proyecto. No crees una "Aplicación", sino un "Programa simple".

El programa debería verse como esto :

PROGRAM Project1;
 
BEGIN
END.

Guarda el proyecto en una carpeta nueva a tu elección.

Te recomiendo que, para evitar que se mezclen los archivos, tengas los archivos fuente separados del binario final. Por ejemplo, crea un subdirectorio llamado "src" (de 'source') para las fuentes y otro "bin" (de 'binario') para el programa compilado.

Hacer que Allegro.pas esté disponible para tu proyecto

La forma más sencilla de que Allegro.pas esté disponible en tu proyecto es que copies el directorio lib del paquete Allegro.pas en el mismo directorio donde hayas guardado este nuevo proyecto.

La otra forma es agregar las unidades de Allegro.pas a la ruta de búsqueda del proyecto. Para hacer esto, ve a las opciones del compilador con el menú Proyecto > Opciones del proyecto. En Opciones del Compilador > Rutas > Otros archivos de unidad agrega Allegro.pas. Por ejemplo, si Allegro.pas esta en una carpeta siguiente a tu proyecto, la ruta relativa puede ser "..\allegro_pas".

Sea como fuere, añade la sección USES a tu programa:

  USES
    Allegro5;

Inicializar Allegro

La forma más sencilla de inicializar Allegro es la siguiente:

  IF NOT al_init THEN HALT;

Como ves, llama a la función al_init, la cual devuelve TRUE o FALSE dependiendo de si ha tenido éxito o no en la operación.

Si ejecutas el programa ahora verás que no sucede nada, salvo que el IDE se oculta y reaparece rápidamente. Esto es debido a que al_init simplemente prepara aspectos internos, como cargar bibliotecas (archivos .dll, .so...) e inicializar variables internas. Existe una versión extendida de esta función, llamada al_install_system, que sólo se usa en casos especiales.

Es importante recordar que Allegro debe estar inicializado antes de usar cualquier característica o módulo de Allegro. Por ello debe llamarse a al_init o a al_install_system lo antes posible.

Mostrar mensajes de error

La mejor forma de mostrar mensajes de error es a través de una caja de texto. Allegro provee una función que permite hacerlo fácilmente.

Primero, sin embargo, debemos añadir la unidad al5nativedlg a la sección USES, la cual quedará así:

  USES
    Allegro5, al5nativedlg;

Ahora ya podemos mostrar cajas de texto. Modifica el código de inicialización de Allegro para que quede así:

  IF NOT al_init THEN
  BEGIN
  { Mensaje de error. }
    al_show_native_message_box (
      NIL,
      'Error', '', '¡No pudo inicializarse Allegro!', '',
      ALLEGRO_MESSAGEBOX_ERROR);
  { Aborta el programa. }
    HALT
  END;

Si ejecutas, lo más probable es que siga sin pasar nada, salvo que se produzca un error. Si es así, prueba a quitar el NOT para ver la caja de texto. ¡No olvides restaurar el NOT de nuevo!

Si te estás preguntando por qué usamos al_show_native_message_box en lugar de ShowMessage, por ejemplo, se debe a que Allegro no es compatible con la biblioteca LCL. Es importante recordar esto, ya que si se mezcla Allegro con LCL en un mismo programa podría resultar en errores desastrosos.

Crear y mostrar una ventana

Allegro permite tanto funcionar en modo pantalla completa como en modo ventana. Permite un manejo muy completo de estos modos, pudiendo manejar varias ventanas y pantallas (displays) de forma simultánea. Sin embargo, en la mayor parte de los casos sólo es necesario una ventana, cuya gestión es muy simple.

Primero vamos a añadir unas constantes para indicar el tamaño de la ventana. Es una buena idea hacerlo así, ya que en proyectos más complejos pueden facilitarnos mucho las cosas si cambiamos la definición de pantalla.

Añade una sección CONST justo después de la sección USES:

  CONST
  (* Ancho y alto de la ventana. *)
    ANCHO = 640; ALTO = 480;

Ahora necesitamos una variable para hacer referencia al objeto display que corresponde a la ventana que vamos a crear:

  VAR
  (* Puntero al objeto "display" correspondiente a la ventana. *)
    Ventana: ALLEGRO_DISPLAYptr;

Finalmente, creamos la ventana. Añade el siguiente código tras el de inicialización de Allegro:

{ Crea la ventana. }
  al_set_new_display_flags (ALLEGRO_WINDOWED);
  Ventana := al_create_display (ANCHO, ALTO);
  IF Ventana = NIL THEN
  BEGIN
  { Mensaje de error. }
    al_show_native_message_box (
      NIL,
      'Error', '', '¡No pudo crearse la ventana!', '',
      ALLEGRO_MESSAGEBOX_ERROR);
  { Aborta el programa. }
    HALT
  END;

Como ves, primero llamamos a al_set_new_display_flags Ese procedimiento permite ajustar algunos valores que afectarán a la ventana o display que crearemos a contiuación. En este caso usamos la constante predefinida ALLEGRO_WINDOWED, que indica que queremos que cree una ventana. Si en lugar de esto quisiéramos un display en modo pantalla completa usaríamos la constante ALLEGRO_FULLSCREEN_WINDOW. Podemos combinar algunas de estas constantes usando el operador OR; por ejemplo si queremos que el usuario pueda cambiar el tamaño de nuestra ventana:

al_set_new_display_flags (ALLEGRO_WINDOW OR ALLEGRO_RESIZABLE);

Otro procedimiento que también permite configurar el tipo de ventana creada es al_set_new_display_option, que permite definir cosas como la profundidad de color, su formato, la orientación, etc. Por defecto se usa la misma configuración que la del escritorio, así que salvo casos especiales no es necesario hacer más configuraciones.

Introducción a los eventos

Si has ejecutado el programa te habrás dado cuenta de que la ventana creada aparece y desaparece rápidamente. En este ejemplo queremos que esta ventana no se cierre hasta que el usuario pulse el botón de cierre de la ventana. Para esto necesitamos manejar eventos.

Allegro permite manejar muchos tipos de evento, desde pulsaciones de teclado, acciones del ratón o mando de juego a interacción con la ventana (mover, cambiar el tamaño...) o interupciones de tiempo, e incluso eventos generados por el propio programa.

Para hacer las cosas sencillas, por ahora manejaremos un único evento: el cierre de la ventana.

La cola de eventos

Primero necesitamos una cola de eventos, la cual se encarga de obtener estos eventos de forma ordenada. Para ello hay que añadir una nueva variable a nuestro programa:

  (* Cola de eventos. *)
    ColaEventos: ALLEGRO_EVENT_QUEUEptr;

Ahora podemos crear la cola. Añade el código siguiente a continuación del de creación de la ventana:

{ Crea la cola de eventos. }
  ColaEventos := al_create_event_queue;
  IF ColaEventos = NIL THEN
  BEGIN
  { Mensaje de error. }
    al_show_native_message_box (
      Ventana,
      'Error', '', '¡No pudo crearse la cola de eventos!!', '',
      ALLEGRO_MESSAGEBOX_ERROR);
  { Cierra la ventana. }
    al_destroy_display (Ventana);
  { Aborta el programa. }
    HALT
  END;
 Como nota curiosa, dese cuenta de que el primer parámetro del procedimiento al_show_native_message_box es
 ahora Ventana y no NIL como en ocasiones anteriores.  Asociando el cuadro de texto a la ventana nos
 aseguramos de que sea visible y que funcione correctamente.

La cola de eventos no es capaz de obtener eventos por sí sola. Para obtener los eventos es necesaria una fuente u origen de eventos, que en nuestro caso es la ventana:

{ Añade los eventos de la ventana. }
  al_register_event_source (ColaEventos, al_get_display_event_source (Ventana));

Obtener y procesar eventos

Ahora ya podemos obtener y manejar los eventos. Primero es necesaria una variable donde almacenar los eventos según se vayan obteniendo:

(* Evento. *)
    Evento: ALLEGRO_EVENT;

La estructura (RECORD) ALLEGRO_EVENT contiene mucha información, cuyo contenido depende del evento que se esté procesando. Por ejemplo, contiene la posición del ratón en los eventos del mismo, o el código de la tecla pulsada en el caso de los eventos del teclado.

Nosotros esperamos un único evento, el de cierre de la ventana. Lo esperaremos dentro de un bucle:

{ Espera a que el usuario cierre la ventana. }
  REPEAT
  { Espera al siguiente evento y lo obtiene. }
    al_wait_for_event (ColaEventos, Evento)
{ Sólo interesa el evento "cierre de ventana". }
  UNTIL Evento._type = ALLEGRO_EVENT_DISPLAY_CLOSE

Como se ve, esperamos un evento y después comprobamos qué evento es para saber si se debe salir del bucle.

Este ejemplo es muy simple, pero en un juego real será más complicado. Para empezar tendríamos más fuentes de eventos: El teclado, el ratón, el reloj, la conexión de red... Además podríamos necesitar varios eventos de una misma fuente; por ejemplo, del ratón necesitaríamos la pulsación de botones y su desplazamiento, y quizá también cambios en la ruleta. En los siguientes tutoriales podrás ver muchos de estos eventos y formas de manejarlos.

Consejos finales

Recuerda que Allegro no es compatible con la biblioteca LCL, así que procura no mezclarlas. Allegro posee todo lo necesario, así que no necesitarás utilizar la LCL para nada.

En el programa de ejemplo no hemos hecho limpieza, es decir, no hemos destruido los objetos creados (ventana y cola) para liberar sus recursos. En principio no es necesario ya que Allegro lleva la cuenta de estos objetos y los destruirá al finalizar el programa. Sin embargo en un juego real es posible que sí debas destruir estos objetos, incluso aunque Allegro pueda hacerlo por sí sólo, para evitar un uso excesivo de recursos.

Programa de ejemplo completo

PROGRAM tutorial;
(*<Muestra cómo inicializar Allegro y abrir una ventana. *)
  USES
    Allegro5, al5nativedlg;
 
  CONST
  (* Ancho y alto de la ventana. *)
    ANCHO = 640; ALTO = 480;
 
  VAR
  (* Puntero al objeto "display" correspondiente a la ventana. *)
    Ventana: ALLEGRO_DISPLAYptr;
  (* Cola de eventos. *)
    ColaEventos: ALLEGRO_EVENT_QUEUEptr;
  (* Evento. *)
    Evento: ALLEGRO_EVENT;
 
BEGIN
{ Inicializa Allegro. }
  IF NOT al_init THEN
  BEGIN
  { Mensaje de error. }
    al_show_native_message_box (
      NIL,
      'Error', '', '¡No pudo inicializarse Allegro!', '',
      ALLEGRO_MESSAGEBOX_ERROR);
  { Aborta el programa. }
    HALT
  END;
{ Crea la ventana. }
  al_set_new_display_flags (ALLEGRO_WINDOWED);
  Ventana := al_create_display (ANCHO, ALTO);
  IF Ventana = NIL THEN
  BEGIN
  { Mensaje de error. }
    al_show_native_message_box (
      NIL,
      'Error', '', '¡No pudo crearse la ventana!', '',
      ALLEGRO_MESSAGEBOX_ERROR);
  { Aborta el programa. }
    HALT
  END;
{ Crea la cola de eventos. }
  ColaEventos := al_create_event_queue;
  IF ColaEventos = NIL THEN
  BEGIN
  { Mensaje de error. }
    al_show_native_message_box (
      Ventana,
      'Error', '', '¡No pudo crearse la cola de eventos!!', '',
      ALLEGRO_MESSAGEBOX_ERROR);
  { Cierra la ventana. }
    al_destroy_display (Ventana);
  { Aborta el programa. }
    HALT
  END;
{ Añade los eventos de la ventana. }
  al_register_event_source (ColaEventos, al_get_display_event_source (Ventana));
{ Espera a que el usuario cierre la ventana. }
  REPEAT
  { Espera al siguiente evento y lo obtiene. }
    al_wait_for_event (ColaEventos, Evento);
  { Sólo interesa el evento "cierre de ventana". }
  UNTIL Evento._type = ALLEGRO_EVENT_DISPLAY_CLOSE
{ Fin del programa.
 
  No es necesario destruir la ventana ni la cola de eventos, ya que la propia
  biblioteca Allegro se encarga de eso. }
END.