You are on page 1of 14

TUTORIAL ALLEGRO

Escrito en francés por: Emeric Poupon


Traducción libre por: Ernesto Castelán Chávez

Introducción
Para comenzar, debo precisar que es necesario un correcto conocimiento de
C/C++ y que Allegro debe ya estar correctamente instalado.
- Durante todo el tutorial, los prototipos de las funciones propias de Allegro
serán mostradas en negritas.
- /* Los comentarios se mostrarán en un azul verdoso muy
característico */
- Los tipos de variables en marrón (int, float, …) incluyendo los tipos de
variables específicos de Allegro (BITMAP, DATAFILE, …)
- Las estructuras de control en azul (if, else, while, {}, …)
- Los números en rojo (0, 1, 324, 4, …)
- Los comandos del preprocesador en verde (#define, #include)
- “Las cadenas de caracteres en gris”

1. ¿Para que sirve Allegro?

Vayamos directo al grano: ¿Qué es Allegro? Es una librería que dispone de


todo lo necesario para programar un juego de video. En otras palabras, Allegro
nos brinda una solución para gestionar gráficos, sonido, el teclado, el ratón, los
temporizadores… en fin, ¡todo lo que necesite! Originalmente Allegro fue creada
por Shawn Hargreaves, para Atari ST, luego pasó rápidamente a DOS. Las
primeras versiones de la librería datan de principios de 1996: ¡no nació ayer!
Rápidamente, los programadores de Allegro orientaron su programación hacia una
librería multiplataforma. Ahora se puede usar Allegro para DOS (DJGPP, Watcom),
Windows (MSVC, Mingw32, Cygwin, Borland), Linux (consola), Unix (X), BeOS,
QNX, MacOS (MPW). Ya lo ha de haber comprendido, la gran fuerza de Allegro
reside en el hecho de que es soportada por un gran número de Sistemas
Operativos (SO). Concretamente, puede compilar sus programas bajo cualquier
compilador (de los mencionados arriba) sin cambiar una sola línea de código. De
alguna manera, Allegro seleccionará, solito, los controladores correctos según el
SO. Por ejemplo un programa bajo Windows utiliza la aceleración DirectDraw,
mientras que bajo Linux puede disfrutar de los controladores X11. De la misma
manera para DirectSound y DirectInput para Windows. En contraparte, lo 3D no es
el fuerte de esta librería: ninguna aceleración material será dada: nada de
Direct3D. Sin embargo OpenGL es muy bien soportado, gracias a un pequeño
parche de Allegro (AllegroGL). Mencionamos también que es una librería gratuita y
libre, y por tanto el código fuente esta disponible.

2. Allegro: Ejemplo de aplicación


Un juego que utilice Allegro puede ser una aplicación de Windows, en ese caso,
DirectX 7.0 (mínimo) será necesario para el funcionamiento del juego. Allegro
puede estar en un DLL (alleg42.dll) o puede, también, estar estático, en cuyo caso
el código de Allegro utilizado se encontrará en el ejecutable (es el caso para DOS).
Les aseguro que en los otros SO también podrán escoger una compilación
estática dinámica, así que no se preocupen.
Para ver un ejemplo, tienen a su disposición el demo oficial (en la carpeta
allegro/demo) que reagrupa en un solo programa algunas características muy
interesantes de la librería.
No olvide “linkear” le librería correctamente, o si no, obtendrá un mar de errores.
(Consulte los archivos de ayuda en cada compilador).
Tampoco olvide que tiene a su disposición toda una gama de ejemplos muy
prácticos. Es, de hecho, gracias a ellos que aprendi a servirme “correctamente” de
Allegro. Todas las descripciones de las funciones estan disponibles en el archivo
de ayuda generado en la instalación de Allegro (/docs/html/allegro.html). Están
muy bien explicadas y es muy útil para descubrir todas las funciones de Allegro.
En fin, si realmente quiere descubrir todo el potencial de esta librería, puede ir al
depósito oficial de los juegos Allegro: www.allegro.cc

3. Las bases de Allegro: un primer programa


Comencemos un pequeño programa básico que nos servirá de ejemplo. Para
comenzar hay que incluir el archivo de cabecera de la librería, cuyo nombre es
“allegro.h”. ¡Cuidado! Por el momento no hay necesidad de incluir WinMain ni
“windows.h”, olvídese de todo lo que concierne a un solo SO.

/* Incluimos el archivo de cabecera de Allegro */


#include <allegro.h>

/* Y comenzamos con la función main */


int main() {

Muy importante, antes de hacer lo que sea con la librería, hay que llamar la
función de inicialización.

/* Función general de inicialización */


allegro_init();

¡Perfecto! ¡Allegro está inicializado! Ahora, si instaláramos el teclado y el ratón


sería mucho más práctico…
/* Inicializa el teclado */
install_keyboard();

Si la función tuvo éxito, devuelve 0, sino, devuelve un número negativo. Podemos


considerar que no vale la pena verificar el resultado puesto que las probabilidades
de error son mínimas.

/* Inicializa el ratón */
install_mouse();

Aquí, la cosa se pone más interesante: si la función fracasa, devuelve -1, sino,
devuelve el número de botones del ratón que Allegro puede manejar. Es
importante efectuar una verificación puesto que los usuarios de DOS no
necesariamente tienen un controlador de ratón que funcione… Entonces podemos
escribir:

/* Si la función fracasa, entonces… */


if(install_mouse() == -1){
/* Mostramos el mensaje de error */
allegro_message(“Error! %s”, allegro_error);

/* Y salimos del programa */


return -1;
}
/*Ahora, sabemos que el ratón funciona correctamente */

En este punto me dirán: ¿Qué es allegro_message? ¿Y allegro_error?


Aquí el prototipo de allegro_message:

void allegro_message(char *msg, …);


Esta función utiliza el mismo formato de salida que la función printf. Es, por lo
tanto, muy cómoda de utilizar. ¡Cuidado, esta función sólo debe ser utilizada en
modos no gráficos! Sólo la puede utilizar si no ha inicializado el modo gráfico, o si
pasó explícitamente en modo texto. En este caso, por ejemplo, no hemos iniciado
aún el modo gráfico, podemos entonces usará la función sin problemas. En los So
que trabajan en modo texto o consola, como DOS y Unix, los mensajes
aparecerán, normalmente, en la consola. Para Windows y BeOS, esto mostrará un
cuadro de diálogo con un botón “OK” abajo. Tendrá como título el nombre del
ejecutable del programa. Esta función es muy practica para señalar errores,
independientemente del SO.

extern char allegro_error[ALLEGRO_ERROR_SIZE];


Es la cadena de caracteres usada por algunas funciones Allegro, como
set_gfx_mode o install_mouse. Sirve para reportar los errores que pudieron
surgir en la inicialización. Si el usuario quiere saber la naturaleza del error, la
cadena allegro_error contiene la descripción del problema: no queda más que
mostrarla (con allegro_message por ejemplo). ALLEGRO_ERROR_SIZE, para no
enredarlo, sencillamente es el tamaño de la cadena de caracteres.

Bueno, ya tenemos el ratón y el teclado. ¿Acaso no es genial? Solamente que


sería mejor pasar al modo gráfico... para comenzar, hay que definir el número de
colores que se usarán en el modo de vídeo. En es decir por cuántos bits estará
codificado cada píxel (8, 15, 16, 24 o 32 bits). Cuanto más alto sea el número de
bits, más amplia será la paleta de colores disponible. Por ejemplo para 16 bits,
tiene derecho a 2^16 = 65,536 colores, para 24 bits 2^24 igual 16,777,216 colores.
El caso de los colores de 8 bits es más particular, lo dejaremos de lado por el
momento.

/* Establecemos el número de colores para el modo gráfico.


Por el momento será 16 bits lo cual será lo suficientemente
amplio para nuestra pantalla. Tiene la ventaja de ser muy
expandido y por lo tanto fácilmente soportada por otras
tarjetas de vídeo espacio */
set_color_depth(16);

Ahora pasaremos al modo gráfico propiamente dicho. Para ello utilizaremos la


siguiente función:

set_gfx_mode(GFX_AUTODETECT,640,480,0,0);

Pero ahora, ¿cómo diablos utilice esta función? He aquí su prototipo:

int set_gfx_mode(int card, int width, int height, int v_width,


int v_height);
Comenzaremos por lo fácil, la función devuelve cero en caso de éxito, sino,
devuelve un número negativo.
“int card” no es muy descriptivo, es el índice del modo gráfico que queremos
utilizar. Aquí están los diferentes valores que debemos escribir (las definiciones
están en alguna parte de allegro.h):
- GFX_AUTODETECT. No nos ocupamos de nada, dejamos que Allegro escoja
el mejor controlador. Se pondrá en modo ventana si la resolución no está
disponible en pantalla completa y si el SO lo soporta.
- GFX_AUTODETECT_FULLSCREEN. Forzamos a Allegro a escoger un
controlador de pantalla completa
- GFX_AUTODETECT_WINDOWED. Forzamos a Allegro a escoger un
controlador en modo ventana
- GFX_TEXT. Es muy útil para regresar al modo texto, en ese caso, podemos
poner cero para las dimensiones de la pantalla.
Naturalmente, existen otros valores, pero son más específicos para cada SO (por
lo tanto tendremos que evitar usarlos), regresaremos a ello más tarde, por el
momento sólo vemos las bases. Los valores width y height representan el
tamaño gráfico de la pantalla creada. Puede acceder a las dimensiones de la
pantalla gracias a los macros SCREEN_W y SCREEN_H inicializados por la función.
Por el momento, no nos ocuparemos de v_width y de v_height (por lo tanto
podemos poner el valor cero). Como todo programa respetable, hay que verificar
si no hay errores. Agregaremos, entonces, las pruebas necesarias:

if(set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) != 0) {


/*Como han seguido bien mis explicaciones, han de saber que
allegro_message se utiliza únicamente en modo texto, es por
eso que utilizamos GFX_TEXT, para estar seguros de pasar a
modo texto */
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); /*aquí el comando
para modo texto*/
allegro_message("Imposible iniciar el modo video!\n%s\n",
allegro_error);
return 1; //y no nos olvidamos de salir...
}
//aquí todo salió bien. SCREEN_W = 640 SCREEN_H = 480;

¡Listo! ¡Terminamos de inicializar nuestro pequeño programa! Podríamos añadir


sonido e instalar un control de juego, pero eso será en capítulos próximos. Por
ahora, haremos que el programa se interrumpa cuando presionemos la tecla ESC.
Agregaremos entonces algunas líneas de código.

while(!key[KEY_ESC]){ //Mientras que ESC no se oprima...


/*Borramos la pantalla. Analizaremos esta función en
capítulos posteriores*/
clear_bitmap(screen);
}

Aquí vemos un aspecto importante de la librería, la gestión de teclas oprimidas por


el usuario.

extern volatile char key[KEY_MAX];


Es muy simple: todas las teclas de Allegro, están agrupadas en este arreglo (de
tamaño KEY_MAX, claro). Es un tablero en que cada tecla tiene un índice. Para
conocer la lista de todas las teclas, abra el archivo “allegro/keyboard.h”, todo
está definido ahí. Normalmente, este arreglo representa el estado de la tecla
actual. Es decir si está o no presionada: por lo tanto sólo es usada para leer. Se
“modifica” solito gracias a las interrupciones del teclado. Puede, claro está, simular
que oprime una tecla, pero eso es otra historia… Aquí otros ejemplos de uso (¡No
los copie en el código! Sería inútil, pues printf no funciona en modo gráfico):

if(key[KEY_ENTER])
printf(“La tecla Enter está oprimida \n”);
if(key[KEY_SPACE])
printf(“La barra espaciadora está oprimida \n”);
¡No nos olvidemos de salir del programa!

return 0; //Y así salimos del programa


}
END_OF_MAIN();

Quizás se haya dado cuenta que las aplicaciones de Windows tienen su punto de
entrada en WinMain y no en main. Es por eso que la macro END_OF_MAIN() es
necesaria: permita utilizar la función main sin importar el SO. Escríbala justo al
final de la función main y no tendrá ninguna advertencia o error a la hora de
compilar. ¡Nada de que preocuparse!

Pues esto es todo como bases de inicialización a Allegro. Si usted copió y


comprendió el programa de ejemplo, a medida que fue explicado, no debería tener
problemas. Claro que es muy básico, no hace más que mostrar una pantalla en
negro (si no ocurrió ningún error de inicialización antes) y esperar que oprima la
tecla ESC para salir. En el próximo capítulo nos interesaremos por una parte
esencial de los juegos de video: ¡Gráficos en la pantalla!

4. Gráficos en pantalla
4.1. Presentación general
Pasaremos ahora a la parte de los gráficos en pantalla, sin duda la parte más
importante. Para esto, mostraremos un disco blanco desplazándose hacia la
derecha de la pantalla. Estará exactamente a la mitad de la altura de nuestra
pantalla. El usuario deberá presionar ENTER para lanzar el disco. Modifiquemos,
pues, nuestro ciclo de espera (el que verifica que la tecla ESC no esté oprimida):

/* Declaramos nuestra variable, que representa la posición


del círculo. Si programa en C, escríbala al inicio de la
función main */
double circle_pos_x = 0;

/* Esperamos pacientemente a que el usuario oprima ENTER para


mostrar y mover el disco */
while(¡key[KEY_ENTER]);

while(¡key[KEY_ESC]){ //Mientras la tecla ESC no esté


oprimida…

/* Comenzamos borrando la pantalla */


clear_bitmap(screen);

/* Dibujamos un circulo “lleno” de blanco


(color 255,255,255) */
circlefill(screen,(int)circle_pos_x,SCREEN_H/2,50,
makecol(255,255,255) );

//Movemos el disco a la derecha 0.1 pixel


circle_pos_x += 0.1;

/* Verificamos si el disco sale de la pantalla, si es así


salimos del ciclo y por tanto finalizamos el programa */
if(circle_pos_x – 50 >= SCREEN_W)
break;
}

¡No se preocupe! Aclararemos todo esto… circlefill es la función que nos


permitirá mostrar un disco en pantalla.

void circlefill(BITMAP *bmp, int x, int y, int radius, int


color);
x y y representan las coordenadas del centro del disco en la pantalla. Todas las
coordenadas están dadas con respecto a la esquina superior izquierda de la
pantalla. radius representa, sencillamente, el radio en píxeles. Como se ha de
haber dado cuenta, aparece un nuevo tipo de dato aquí, y se trata de BITMAP. No
se preocupe, hablaremos de esto después.

extern BITMAP *screen;


Sólo recuerde que screen es una variable global que apunta hacia un BITMAP
(zona de imagen) que representa la memoria de vídeo, y por lo tanto apunta
directamente a la pantalla. El tamaño de este mapa de bits es SCREEN_W x
SCREEN_H. Entonces bmp es el mapa de bits en el cual dibujaremos nuestro disco,
es el destino de la función de dibujo. color es, como lo indica su nombre, el color
del disco. Lo mejor es usar una pequeña función para definirlo.

int makecol(int r, int g, int b);


Esta función permite definir un color, independientemente del modo de colores que
estemos usando. Podemos llamar a esta función en los modos de 8, 15, 16, 24 y
32 bits por píxel. r representa la parte roja, g el la parte verde y b la parte azul, es
decir que devuelve un color en formato RGB. Cada componente del color puede
tomar valores de 0 a 255. makecol(255,255,255) devuelve, por lo tanto, el
código del color blanco del modo de video actual.

Ahora, si ejecuta el programa, se dará cuenta que hay unos horribles parpadeos
en la pantalla. De hecho, no vemos un disco, sino una sucesión de líneas negras y
blancas. ¡Realmente no es el efecto que buscábamos! ¿Entonces, dónde está el
problema? Es muy sencillo, para programar correctamente un juego, no debemos
jamás escribir directamente sobre la pantalla, a menos que no nos importe para
nada el resultado, pero ese no es nuestro caso. Utilizaremos, pues, un nuevo
modo de impresión en pantalla, el “double buffering”. El principio es muy básico:
en vez de dibujar en la pantalla, dibujaremos en un mapa de bits que tendremos
guardado en la memoria principal (RAM). Luego, al final de nuestro ciclo,
copiaremos de golpe el contenido de ese mapa de bits (hablamos del buffer) en la
pantalla. No es el método que da los resultados más espectaculares, pero ¡será
mucho mejor! Definamos de una vez por todas el tipo BITMAP (podrá encontrar la
declaración en los archivos de cabecera de la librería):

typedef struct BITMAP {


// El tamaño del mapa de bits en píxeles (w ancho, h alto)
int w, h;
};

Naturalmente, existen otras variables en el tipo BITMAP, pero no las utilizaremos.


Así, para conocer el tamaño de la pantalla hay otro método, screen->w que
representa el ancho y screen->h que representa el alto. No olvide nunca que
Allegro trabaja con punteros hacia BITMAP (o sea BITMAP*). Declararemos pues
nuestro buffer de video:

BITMAP* buffer; //La variable que apunta al buffer de video

Ahora, es necesario crear un mapa de bits de las mismas dimensiones que la


pantalla. Este paso debe hacerse después de iniciar el modo de gráfico.

buffer = create_bitmap(SCREN_W,SCREEN_H);

BITMAP* create_bitmap(int width, int height);


Esta función crea un mapa de bits de anchura width y de altura height.
Devuelve un puntero hacia el BITMAP creado. Normalmente esta imagen creada
en la memoria no esta completamente vacía (negra) y deben quedar residuos. Hay
que vaciarla antes de poder utilizarla. Para vaciar un mapa de bits al color 0 (negro)
utilizamos esta función:

void clear_bitmap(BITMAP* bitmap);

Esta función puede ser acelerada materialmente1, el resultado será un increíble


rendimiento.

clear_bitmap(buffer); //Así de sencillo

Escribiremos una vez más nuestro ciclo de espera:

while(!key[KEY_ESC]) { //Mientras ESC no se oprima…

//Empezamos por vaciar el buffer


1
El traductor no entendió claramente lo que quiso decir el autor original, pero supone que se refería a la
aceleración por hardware.
clear_bitmap(buffer);

//Dibujamos el círculo blanco en el buffer


//El blanco es el color 255,255,255
cireclefill(buffer, (int)circle_pos_x, SCREEN_W/2, 50,
makecol(255,255,255) );

circle_pos_x += 0.1;
//Movemos el círculo a la derecha 0.1 píxeles

/* Verificamos si el disco sale de la pantalla, si es así


salimos del ciclo y por ende del programa también */
if(circle_pos_x – 50 >= SCREEN_W)
break;

//Ahora copiamos el contenido del buffer el pantalla


blit(buffer, screen, 0,0,0,0,SCREEN_W,SCREEN_H);
}

Reemplazamos, pues, screen por buffer en todas las funciones necesarias. No


queda más que descubrir la función blit… Esta función permite copiar una zona de
un mapa de bits hacia una zona de otro mapa de bits.

void blit(BITMAP* source, BITMAP* dest, int source_x, int


source_y, int dest_x, int dest_y, int whidth, int eight);
¡He aquí una función interesante! source queda claro que es el mapa de bits de
origen (en este caso buffer), dest es el mapa de bits de destino (en este caso
screen). source_x y source_y representan las coordenadas del origen del
mapa de bits del que vamos a copiar. dest_x y dest_y representan las
coordenadas a partir de las cuales comenzaremos a dibujar en el mapa de bits de
destino. Finalmente width y eight representan las dimensiones que queremos
copiar.

En nuestro caso, queríamos copiar íntegramente el buffer en pantalla. Es por eso


que comenzamos a dibujar desde las coordenadas (0,0) y que dibujamos todo el
buffer (SCREEN_W y SCREEN_H). Ejecute el programa de nuevo y se llevará una
sorpresa. ¡No más parpadeos rebeldes! Las cosas pintan bien… Por otra parte la
velocidad del disco puede verse reducida notablemente. Es totalmente normal,
pues la computadora ocupa la mayor parte de su tiempo a mostrar en pantalla.
Mostrar un pequeño disco en pantalla es mucho más rápido que copiar todo el
buffer en pantalla, por lo tanto es preferible cambiar la línea de desplazamiento por:

++circle_pos_x; //Desplazaremos el disco 1 píxel esta vez

Aquí, la velocidad del disco depende directamente de la velocidad de nuestro


ordenador (la impresión en pantalla es un factor muy limitativo de de la velocidad
del programa). Inclusive en un ordenador poderosísimo, no podrá alcanzar
velocidades astronómicas (en termino de imágenes por segundo) pues hay que
esperar que cada imagen sea dibujada por la tarjeta de video. No se desanime, en
los próximos capítulos hablaremos del tiempo real, es decir, que su juego vaya a
la misma velocidad sin importar la potencia de la computadora en la que se este
ejecutando.

4.2 Impresión de texto por pantalla


Una de las funciones “genialisísimas” de Allegro es imprimir texto en la pantalla de
una manera muy sencilla. En efecto, en modo gráfico, es absolutamente imposible
usar la función printf y otras de ese tipo. Allegro nos da una amplia gama de
funciones que nos permiten efectuar esas tareas de forma automática.
Modifiquemos otra vez el ciclo de espera principal de nuestro pequeño programa
para que muestre la resolución actual de la pantalla y la posición de nuestro
pequeño disco blanco:

while(!key[KEY_ESC]) { //Mientras no se oprima ESC…


//Comenzamos por borrar el (buffer);
clear_bitmap(buffer);

/* Imprimimos una cadena de caracteres en las coordenadas


(0,0) y para el color utilizaremos un azul violeta vivo
(150,150,255) */
textout(buffer, font, “Estoy escribiendo texto!”,
0,0,makecol(150,150,255) );

//Movemos el disco 0.1 píxeles a la derecha


cricle_pos_x += 0.1;

/*Verificamos que el disco no salga de la pantalla, si es


asi, salimos del boucle y por tanto terminamos el programa */
if(circle_pos_x – 50 >= SCREEN_W)
break;

/* Ahora hay que copier el contenido del buffer en la


pantalla*/
blit(buffer, screen, 0,0,0,0,SCREEN_W, SCREEN_H);
}

Hemos utilizado la función textout para imprimir el texto:

void textout(BITMAP* bmp, const FONT* f, const char* str, int


x, int y, int color);
bmp representa el mapa de bits en el cual imprimiremos el texto. str será la
cadena de texto a mostrar, x e y serán las coordenadas del punto superior
izquierdo del texto (0,0 nos asegura que el texto aparecerá en la esquina de la
pantalla). color, como ya se había visto, representa el color con que se mostrará
str. Sólo queda introducir la noción de lo que es FONT. Tal como en Windows,
Allegro es capaz de mostrar varios tipos de fuentes. Basta con especificar un
puntero hacia la fuente deseada, la cual deberá ser del tipo FONT. Veremos en
futuros capítulos como cargar fuentes. Afortunadamente, por el momento,
podemos usar la predeterminada de la BIOS:

extern FONT* font;

Normalmente podríamos modificar este puntero hacia cualquier otra fuente, pero
esto no nos es muy útil por el momento ya que no sabemos cómo cargarlas.

Ahora, ¡podemos mostrar el tamaño de la pantalla! Basta con agregar:

#include <string.h> /* incluimos el archivo de cabecera de


esta librería del C ANSI */

Necesitaremos una variable nueva:

//Un pequeño buffer que puede contener 256 caracteres


char str_buf[256];

Transformaremos nuestra función textout:

/*Copiamos primero el tamaño de la pantalla en str_buf */


sprintf(str_buf, “El tamaño de la pantalla es: %d x %d”
,SCREEN_W,SCREEN_H);

/* Listo, no nos queda más que reemplazar nuestra cadena de


texto */
textout(buffer,font,str_buf,0,0,makecol(150,150,255) );

¡Admire el resultado! Obtiene en su pantalla, arriba a la izquierda: “El tamaño de la


pantalla es: 640 x 480”. ¡Pero los desarrolladores de Allegro pensaron en todo!
Para ahorrarle una línea y una variable, crearon una función textout con la
sintaxis de printf. Podemos ahora simplificar nuestro programa:

//Cambiaremos de color para celebrar…


textprintf(buffer,font,0,0,makecol(100,255,100),”El tamaño de
la pantalla es: %d x %d”,SCREEN_W,SCREEN_H);

void textprintf(BITMAP* bmp, const FONT* f, int x, int y, int


color, const char* fmt, ...);
Aquí esta el prototipo de la función. Ahora puede imprimir texto con formato, justo
como con printf. La función es muy similar a textout, por lo que no hay
necesidad de regresar a los detalles. Gracias a esta implementación podemos
deshacernos de la línea include <string.h> y de nuestro buffer de caracteres,
el cual es inservible.
¿Por qué no mostrar la posición del disco en la pantalla? ¡Y que mejor que el color
varíe con respecto a la posición actual del disco!

/* He aquí la línea, un poco más larga */


textprintf(buffer,font,0,10,makecol(circle_pos_x/SCREEN_W*255,
circle_pos_x/SCREEN_W*255,circle_pos_x/SCREEN_W*255),
"Posicion del disco: %d", (int)circle_pos_x);

La cadena de caracteres se mostrará con una luminosidad progresiva, lo que crea


un efecto visual simpático. ¡En los últimos 50 píxeles, el texto desaparece! En
efecto, es debido a que la variable circle_pos_x toma un valor superior a 255.
El programa “repasa” el excedente desde 0, y se genera un color muy oscuro.
Para ir un poco más lejos, existen otras funciones muy similares a textprintf:

void textprintf_centre(BITMAP *bmp, const FONT *f, int x,


int y, int color,const char *fmt, ...);
Esta función realiza exactamente lo mismo que textprintf, excepto que
interpreta a x e y como el centro de la cadena de caracteres a mostrar, y no la
esquina superior izquierda como solía ser.

void textprintf_right(BITMAP *bmp, const FONT *f, int x,


int y, int color,const char *fmt, ...);
Aquí es lo mismo, pero x e y son las coordenadas de la esquina superior derecha.

void textprintf_justify(BITMAP *bmp, const FONT *f, int x1,


int x2, int y,int diff, int color,const char *fmt, ...);
Aquí dibujamos el texto de manera justificada entre las coordenadas x1 y x2. Si
las letras llegaran a salirse la función se convierte en un textprintf estándar.

¡Listo!, ya conoce todas las funciones de Allegro basadas en textprintf.


Existen otras funciones anexas que pueden ser muy practicas en algunos casos.
Por ejemplo:

int text_length(const FONT *f, const char *str);


Esta función devuelve la longitud en píxeles, de la cadena de caracteres str
usando la fuente f. Puede servir para saber si un determinado texto se saldrá de
la ventana, por ejemplo.

int text_height(const FONT *f);


Aquí no debemos especificar ninguna cadena de caracteres, pues sólo nos
interesa la altura. Solo basta con definir la fuente f, y saber así su altura en píxeles.
Ahora utilizaremos la función textprintf_centre en nuestro pequeño
programa de prueba. Reemplazaremos, pues, la línea que escribe las
dimensiones de la pantalla por ésta otra:

/* Mostramos las dimensiones justo en el centro de la


pantalla */
textprintf_centre(buffer, font, SCREEN_W/2, SCREEN_H/2,
makecol(100,255,100), “El tamaño de la pantalla es: %d x %d”,
SCREEN_W, SCREEN_H);

Compile y ejecute el programa… Si siguió correctamente mis instrucciones, el


disco debería mostrarse por encima del texto. Es perfectamente lógico, pues se
dibuja el disco después de haber impreso el texto en pantalla. Ahora, posicione
esta línea después de la que dibuja el disco.
Vuelva a compilar y a ejecutar. Esta vez, el texto si se mostrará por encima del
disco, pero, ¡Está en un curioso cuadro negro! Le aseguro… esto es
perfectamente normal. Arreglemoslo inmediatamente con las siguientes lineas:

/* Pasamos al modo transparente de impresión de texto */


text_mode(-1);

/* Mostramos las dimensiones justo en el centro de la


pantalla */
textprintf_centre(buffer, font, SCREEN_W/2, SCREEN_H/2,
makecol(100,255,100), “El tamaño de la pantalla es: %d x %d”,
SCREEN_W, SCREEN_H);

El resultado es perfecto: ¡No más cuadro negro! ¿Pero como funciona? Pues, todo
texto impreso se divide en dos partes: la frontal (el texto en sí) y la parte trasera,
que es un cuadro rodeando los caracteres de nuestro texto. Por defecto, este
cuadro es negro, y es por eso que no se había dado cuenta (planee muy bien la
sorpresa, ¿verdad?), pero si el texto se imprime sobre otro color este cuadro es
perfectamente visible.
Veamos la función text_mode:

int text_mode (int mode);


Es muy fácil de utilizar. mode es el color del cuadro sobre el cual se mostrará el
texto. Podemos, pues, crearla con makecol, como ya hemos visto. Por ejemplo
para mostrar un cuadro blanco por debajo:

text_mode(makecol(255,255,255) );

Hay sin embargo un detalle. Para no mostrar este cuadro, es decir tener un efecto
de transparencia, hay que utilizar el color -1. Pero hay que tener mucho cuidado,
ya que text_mode se aplicará a todas las funciones de impresión de texto
subsiguientes. Por ende, hay que definir un color de fondo cada vez que le haga
falta. Por ejemplo en nuestro programa, a partir de la segunda ocurrencia del ciclo,
¡todos los textos serán mostrados en transparencia!

Bueno, ahora tiene todas las herramientas necesarias para mostrar texto en
pantalla, durante sus programas. No dude pues en usar todas las funciones, nada
vale tanto como la práctica y la experiencia personal.

Hemos dibujado un disco… ¿No sería mejor imprimir una imagen de verdad?
(Hablamos entonces de un sprite)

You might also like