Introdução a Allegro 5
A Allegro é uma engine utilizada para o desenvolvimento
de jogos que é gratuita, de código aberto e está disponível para várias
plataformas (Linux, Windows, MacOS, etc.). Utilizada com a linguagem de
programação C/C++, ela fornece funções para gráficos, sons, dispositivos de
entrada, matemática, entre outras. Originalmente foi escrita por Shawn Hargreaves, de 1994 a 1998, para o compilador DJGPP, e
depois contou com a contribuição de mais de 150 pessoas.
Esta página tem como objetivo
passar informações iniciais sobre o uso da Allegro, e está dividida em tópicos,
conforme listado a seguir. Um guia de referência completo está disponível na página da Allegro e pode ser obtido clicando aqui.
1.
Instalação da Allegro 5
Para instalar os arquivos
necessários para utilizar a Allegro 5 com o Visual Studio 9 (2008) é necessário
seguir os passos descritos abaixo.
1. Atualizar o Visual Studio com o Service Pack 1. Link para uma cópia
local: ZIP - Cópia Local (830 MB). Link direto para a página da Microsoft: http://www.microsoft.com/downloads/en/default.aspx
(procurar por "Visual Studio Service Pack 1");
2. Instalar o Direct X SDK versão 9 ou posterior. Link para uma cópia local:
Cópia Local da versão 10 (550 MB). Link direto para a página da Microsoft: http://www.microsoft.com/downloads/en/default.aspx
(procurar por "Direct X SDK"). IMPORTANTE: Anote o nome do diretório onde
você instalou o DirectX, pois isto vai ser necessário para a configuração
do Visual Studio posteriormente. Neste material assume-se que a instalação foi
feita no diretório sugerido durante a instalação, que é C:\Program
Files\Microsoft DirectX SDK (February 2010);
3. Instalar as bibliotecas da Allegro 5. Para isto, é necessário criar um
diretório com o nome Allegro5 e descompactar a biblioteca neste diretório. Link
para uma cópia local: Cópia Local (2.5 MB). Link direto para a página da Allegro: http://www.allegro5.org/ (acessar o link Downloads). IMPORTANTE: Anote o nome do diretório onde
você instalou a Allegro, pois isto vai ser necessário para a configuração
do Visual Studio posteriormente. Neste ponto o diretório Allegro5 deve conter,
pelo menos os diretórios LIB e INCLUDE.
2. Configuração do Visual Studio 9 (2008) para Allegro
Após a instalação do Service Pack
1, do Direct X SDK versão 9 e das bibliotecas da Allegro 5, é necessário criar
e configurar um projeto no Visual Studio. Para isto, siga os passos descritos a
seguir.
1. Inicialmente, abra o Visual Studio e selecione o ambiente de
desenvolvimento C++.
1. No drive H, crie um novo projeto (Menu
File->New Project) chamado
Teste, como console application e
vazio (veja as orientações nas janelas abaixo).
2. Baixe o código fonte e a imagem disponível aqui para incluir no
projeto. Estes dois arquivos devem ser colocados na pasta Teste mais interna do
projeto. Depois, o código fonte deve ser incluído no projeto da seguinte
maneira: selecionar a pasta “Source Files”
do projeto no Visual Studio, clicar com o botão direito e selecionar AddàExisting Item... Na janela aberta, basta incluir o código fornecido (TesteAllegro1.cpp).
3. Ative a opção Properties,
clicando sobre o nome do projeto com o botão direito do mouse, ou através do
menu Project->Properties, conforme mostra a figura abaixo.
4. Na janela aberta, selecione o tipo de compilação que irá utilizar (Debug ou Release). Para este projeto, selecione a opção Debug, no item Configuration,
conforme mostra a imagem abaixo. Você també pode selecionar All Configurations, se preferir.
5. Ainda nesta janela, abra a opção C/C++, selecione Preprocessor Definitions e verifique se
a constante ALLEGRO_STATICLINK está presente. Se não estiver, adicione-a.
Clique OK.
6. Ainda na opção C/C++, selecione General
e selecione a opção Additional Include
Directories. Coloque nesta opção o diretório onde a Allegro está instalada,
provavelmente C:\Program Files\Allegro5\include.
.
7. Adicione as bibliotecas da Allegro, abrindo a opção Linker->General->Additional Library Directories. Adicione os diretório
da DirectX e da Allegro. No exemplo, este diretórios são os apresentados na
figura abaixo.
8. Selecione a opção Input,clique em
Additional Dependencies e adicione as
seguites bibliotecas da Allegro:
allegro_image-static-4.9.17.lib
png.lib
jpeg.lib
winmm.lib
psapi.lib
opengl32.lib
dxguid.lib
dinput8.lib
d3d9.lib
allegro-static-4.9.17.lib
zlib.lib
9. Selecione a opção Ignore Specific
Library e coloque MSCRT.
10. Na opção Command Line, coloque
/LTCG em Additional Options.
11. Neste momento o VisualStudio deve estar pronto para compilar um programa
com a Allegro. Pressione F7 e logo a seguir, F10 para executar. Deve
aparecer uma janela que exibe uma imagem (veja a figura abaixo) que será
fechada em 5 segundos.
3.
Primeiro Exemplo
A seguir é descrito o exemplo
apresentado para o teste da configuração do Visual Studio. Quando executado, ele
simplesmente abre uma janela Allegro e exibe uma imagem por 5 segundos. Uma
descrição de todas as funções utilizadas é apresentada como comentário no
código fonte deste exemplo, disponível aqui e apresentado abaixo.
// Programa que exemplica como utilizar a
Allegro. Quando executado, abre
// uma janela de teste por 5 segundos exibindo
uma imagem nela.
//
// Curso de Especializacao em Desenvolvimento de
Jogos Digitais
// Disciplina: Programacao 2D
// Professores: Isabel H. Manssour e Marcio S.
Pinho
#include <iostream>
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_opengl.h>
int main(void)
{
// Funcao de inicializacao da Allegro
al_init();
// Funcao para forcar o uso de OpenGL ao inves de DirectX
(DirectX eh o default)
al_set_new_display_flags(ALLEGRO_OPENGL);
// Funcao para criar uma janela com as dimensoes
passadas como parametro, que torna-se
// automaticamente ativa, com o backbuffer selecionado para
desenho. Os parametros
// da janela sao determinados pelas ultimas chamadas a
"al_set_new_display_*".
ALLEGRO_DISPLAY *display =
al_create_display(800, 600);
// Prototipo da funcao: void
al_clear_to_color(ALLEGRO_COLOR color)
// Limpa o bitmap de destino e recebe por
parametro uma referencia para a struct
// ALLEGRO_COLOR, que descreve a cor em um dispositivo de
forma independente.
// ALLEGRO_COLOR
al_map_rgb(unsigned char r, unsigned char g, unsigned char b)
// eh a funcao usada para converter uma cor RGB
para uma struct ALLEGRO_COLOR.
al_clear_to_color(al_map_rgb(0, 0,
0));
// Inicializa the "Image IO addon", que
tem funcoes declaradas no seguinte
// header: #include
<allegro5/allegro_image.h>
al_init_image_addon();
// Prototipo: ALLEGRO_BITMAP *al_load_bitmap(const char
*filename)
// Carrega uma imagem para a struct
ALLEGRO_BITMAP. O tipo do
// arquivo eh determinado pela extensao (bmp ou png).
ALLEGRO_BITMAP *img = al_load_bitmap("teste.png");
// Verifica se deu problema ou nao e notifica o
usuario.
if (!img)
std::cout
<< "Problemas na carga da imagem !";
else
std::cout
<< "Imagem carregada!";
// Prototipo: void al_draw_bitmap(ALLEGRO_BITMAP *bitmap,
float dx, float dy, int flags)
// Desenha um bitmap sem escala e sem rotacao na
posicao (dx,dy) passada por parametro
al_draw_bitmap(img,
10, 10, 0);
// Copia ou atualiza os buffers, assim o que foi desenhado
previamente fica visivel na tela.
al_flip_display();
// Faz uma pausa pelo numero de segundos passado por
parametro.
al_rest(5);
// Destroi o bitmap liberando os recursos usados por ele
al_destroy_bitmap(img);
return 0;
}
4.
Allegro e OpenGL
É possível fazer o rendering usando OpenGL com a Allegro.
Para utilizar os comandos OpenGL de rendering,
em primeiro lugar, é necessário incluir o header
“<allegro5/allegro_opengl.h>” e forçar o uso de OpenGL através do comando “al_set_new_display_flags(ALLEGRO_OPENGL);”.
Depois, é possível usar normalmente
os comandos OpenGL para fazer o desenho em uma janela Allegro, como ilustra a
função abaixo.
// Funcao que contem os
comandos OpenGL para fazer o desenho de um triangulo vermelho na janela
void draw_opengl(void)
{
// Especifica a cor de fundo da janela
glClearColor(0, 0, 0, 1);
//
Limpa a janela
glClear(GL_COLOR_BUFFER_BIT);
// Inicializa sistema de coordenadas de projecao
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Estabelece volume de visualizacao (xMin, xMax, yMin,
yMax, zMin, zMax)
glOrtho(-100,
100, -100, 100, -1, 1);
// Inicializa sistema de coordenadas do modelo
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Desenha um triangulo vermelho no centro da janela
glColor3f(1,
0, 0);
glBegin(GL_TRIANGLES);
glVertex2f(-50,
-50);
glVertex2f( 0,
50);
glVertex2f(
50, -50);
glEnd();
}
Um exemplo de programa completo,
responsável por abrir uma janela Allegro na qual é desenhado um triângulo, está
disponível aqui.
O resultado da execução deste programa é apresentado na figura a seguir.
5.
Eventos
Para trabalhar com eventos na
Allegro é necessário seguir as etapas descritas a seguir:
1.
Instalar o driver necessário de acordo com a fonte de eventos. Para isto basta
chamar as seguintes funções: al_install_joystick(), al_install_keyboard() ou
al_install_mouse(). Todas elas não recebem parâmetro e retornam verdadeiro se
executadas com sucesso, e falso caso contrário, como mostra o exemplo abaixo.
// Funcao que instala um driver de mouse. Se der problema,
retorna false, senao retorna true.
if ( !al_install_mouse() ){
return 1; // encerra se deu
problema
}
// Funcao que instala um driver de teclado. Se der
problema, retorna false, senao retorna true.
if ( !al_install_keyboard() ) {
return 1; // encerra se deu
problema
2.
Criar uma nova fila de eventos
vazia, retornando o ponteiro para a fila criada com sucesso. Em caso de erro, o
ponteiro receberá NULL ou ocorrerá um erro. Protótipo desta função:
ALLEGRO_EVENT_QUEUE *al_create_event_queue(void). Exemplo de sua utilização:
// Funcao que cria uma fila de eventos nova e vazia,
retornando o ponteiro para o objeto criado,
// ou NULL se ocorreu um erro.
ALLEGRO_EVENT_QUEUE *event_queue =
al_create_event_queue();
if (event_queue==NULL) {
return 1; // encerra se deu
problema
}
3.
Registrar cada uma das fontes de
eventos à fila criada. Protótipo da função: void al_register_event_source (ALLEGRO_EVENT_QUEUE
*queue, ALLEGRO_EVENT_SOURCE *source). O primeiro
parâmetro é o ponteiro retornado pela função “al_create_event_queue” chamada
anteriormente. O segundo parâmetro é um ponteiro para a fonte de eventos, que é
obtido através da chamada à função ALLEGRO_EVENT_SOURCE
*al_get_#_event_source(ALLEGRO_DISPLAY *display), onde # corresponde à fonte de
eventos (por exemplo, joystick, keyboard, mouse ou display). O uso
destas funções é apresentado a seguir.
// al_register_event_source(): registra a fonte de eventos
com a fila de eventos especificada.
// al_get_mouse_event_source(): recupera a fonte de eventos
do mouse.
// al_get_keyboard_event_source(): recupera a fonte de
eventos do teclado.
// al_get_display_event_source(): recupera a fonte de
evento associada a janela.
al_register_event_source(event_queue,
al_get_mouse_event_source());
al_register_event_source(event_queue,
al_get_keyboard_event_source());
al_register_event_source(event_queue,
al_get_display_event_source(display));
4.
Criar uma função que irá conter o
seguinte loop principal:
ALLEGRO_EVENT event;
while
(true)
{
// Verifica se a fila de eventos esta vazia.
// Se estiver vazia, faz o desenho e
atualiza os buffers para o que foi desenhado
// previamente ficar visivel na tela (chama al_flip_display())
// Verifica se a fila de eventos esta vazia para fazer o
"refresh" da tela
if
(al_event_queue_is_empty(event_queue)) {
draw_opengl();
al_flip_display();
}
// Espera ate que a fila de eventos nao esteja vazia. O primeiro
evento
// da fila será copiado em "event" e removido da fila.
al_wait_for_event(event_queue,
&event);
// Verifica qual foi o evento gerado e faz o tratamento
adequado usando ALLEGRO_EVENT,
// uma union que no campo “type” identifica o tipo do evento.
switch (event.type)
{
// Indica que o botao de fechar da janela foi pressionado.
case ALLEGRO_EVENT_DISPLAY_CLOSE:
…
break;
// Indica que um botao do mouse foi pressionado.
case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
..
break;
// Indica que uma tecla foi pressionada.
// O campo "keycode" do evento "keyboard"
contem uma constante que
// representa a tecla.
case
ALLEGRO_EVENT_KEY_DOWN:
if (event.keyboard.keycode == ALLEGRO_KEY_UP)
…
break;
}
}
Para ilustrar a utilização de
eventos com Allegro, pegue o exemplo disponível aqui no qual é aberta uma
janela Allegro com uma estrela desenhada no centro (veja a figura abaixo), que
permite as seguintes interações:
- Transladar a estrela usando as setas;
- Optar por desenhar a estrela com a cor amarela ou
azul clicando com um botão do mouse;
- Fechar a janela
pressionando ESC ou clicando no botão de fechar a janela.
6. Animação
Para fazer uma animação usando a Allegro é preciso instalar um timer, que será responsável por controlar
o intervalo de tempo para redesenho da imagem. Para isto, o primeiro passo é
chamar a função “al_install_timer”, que retornará o ponteiro para o timer, como
mostra o trecho de código a seguir.
// ALLEGRO_TIMER*
al_install_timer(double speed_secs)
// Funcao que instala um novo timer, retornando o
ponteiro para o mesmo. Se der
// problema, retorna NULL. O valor passado como parametro
deve ser positivo.
// O novo timer (ou controlador de tempo) é inicializado
parado.
ALLEGRO_TIMER *timer = al_install_timer(1.0 / FPS);
A partir disso, deve-se registrar a timer
na fila de eventos e inicializar o contador, como exemplificado abaixo.
// al_register_event_source(): registra a fonte de eventos
com a fila de eventos especificada.
//
al_get_timer_event_source(ALLEGRO_TIMER *timer): recupera a fonte de eventos
associada.
al_register_event_source(event_queue,
al_get_timer_event_source(timer));
// void al_start_timer(ALLEGRO_TIMER *timer) inicia o timer passado por
parametro.
// A partir disso, o contador do timer vai incrementar em
um frequencia constante
// e vai comecar a gerar eventos. Inicializar um timer que
ja foi inicializado nao
// faz nada.
al_start_timer(timer);
Finalmente, no loop principal do programa, basta tratar o evento
ALLEGRO_EVENT_TIMER, conforme mostrado a seguir.
while (true) {
// Verifica se a fila de eventos esta vazia para fazer o
"refresh" da tela
if
(al_event_queue_is_empty(event_queue)) {
draw_opengl();
al_flip_display();
}
// Espera ate que a fila de eventos nao esteja vazia. O
primeiro evento
// da fila será copiado em "event" e removido da
fila.
al_wait_for_event(event_queue, &event);
// Verifica qual foi o evento gerado e faz o
tratamento adequado.
// ALLEGRO_EVENT eh uma union, e a interpretacao de seu
conteudo
// depende do tipo de evento, que eh definido no campo
"type".
// Cada evento vem de uma fonte (mouse, joystick ou teclado,
// por exemplo), que pode ser acessada por
"event.any.source".
switch (event.type)
{
...
// Indica que o contador do timer foi incrementado.
case ALLEGRO_EVENT_TIMER:
update_position();
break;
}
}
Clique aqui
para obter o código fonte completo de um exemplo que ao ser executado mostra
uma estrela “andando” pela janela. A única interação é para encerrar a execução
do programa pressionando ESC ou clicando no botão de fechar a janela.
7. Sprites
Exibir sprites consiste, basicamente, em exibir
uma imagem. Portanto, assim como no primeiro exemplo, são usadas as seguintes
funções:
·
ALLEGRO_BITMAP *al_load_bitmap(const char *filename): carrega a sprite;
·
void al_draw_bitmap(ALLEGRO_BITMAP *bitmap, float dx, float dy, int
flags): desenha a sprite.
É importante
lembrar, que o ideal é utilizar uma imagem PNG que tenha uma camada de
transparência para a cor de fundo.
Já para exibir
uma sprite animada, por exemplo, um
personagem se movimentando, normalmente é criado um único arquivo com as várias
imagens do personagem se movimentando. Neste caso, é preciso saber utilizar
separadamente cada imagem. Para isto, é utilizada a seguinte função:
·
ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent, int x, int
y, int w, int h)
Esta função
cria um “sub-bitmap” a partir de um bitmap “pai”, nas coordenadas
especificadas, com a largura e altura também passada por parâmetro. Um
"sub-bitmap" é um bitmap que compartilha a memória de desenho com um
bitmap pré-existente (pai), mas possivelmente com tamanho diferente.
Clique aqui
para fazer o download de dois exemplos com sprites:
·
TesteSprite.cpp: abre uma janela
com 3 sprites que se movem aleatoriamente
pela janela; pressionando as teclas up
e down é possível aumentar e
diminuir, respectivamente, o número de sprites
que se movem pela janela.
·
TesteAnimaSprite.cpp: abre uma
janela e exibe uma sprite animada.
8. Links da Allegro 5
Download dos Fontes
Download dos Binários
Instalação da Allegro 5 no MSVC
Getting started guide
Wiki da Allegro
Links sobre bibliotecas de física