Usuário: Renan Lopes
Categoria: Allegro
Visualizações: 1202
Minicurso de Allegro
Pontifícia Universidade Católica – PUC Minas - Campus Poços de Caldas
Autor: Renan Benites Guimarães Lopes.
Contato:
Objetivos:
- Visão geral sobre programação C e organização do código.
- Introduzir o leitor a API Allegro.
- Entender e produzir um programa funcional com uma interface gráfica agradável.
Pré-Requisitos:
- Conhecimento básico da Linguagem C/C++:
- Dominar o uso do if e else, assim como dos operadores || e &&.
- Saber usar com segurança estruturas de repetição: Do While, For.
- Entender o funcionamento e a utilização de structs e arrays.
Extras:
- Utilização de ponteiros.
- Manipulação de classes.
Referências e sites úteis:
=========================================================================================
Prefácio
Prezado leitor,
Este material foi desenvolvido originalmente por Renan Benites Guimarães Lopes, quando foi convidado pelo professor Dr. Will dos Santos Machados, na Pontifícia Universidade Católica de Minas Gerais - Campus Poços de caldas, e agora resolvo compartilha-ló com todos aqui neste fórum.
Serão apresentados alguns tópicos de programação, convenientes a um projeto organizado e legível, assim como uma introdução a API Allegro, explanando suas principais funções, a estrutura de uma aplicação usando a mencionada API, assim como a lógica por trás da programação gráfica, bem como uma abordagem sobre o uso de imagens e as técnicas pertinentes.
O documento aqui relatado tem um caráter mais prático, e está programado para funcionar como uma referência rápida, porém assegurando o entendimento do fluxo de uma aplicação Allegro, que não foge a uma aplicação corriqueira de um programa convencional C.
Para isso, junto com este material, estará disponível um código-fonte de um programa comentado, utilizando as funções aqui descritas, ajudando o leitor a melhor compreender os tópicos abordados.
Tópicos Abordados:
- Endentação.
- Notação Húngara.
- Comentários.
- Instalação.
- HelloWorld Allegro.
- Funções básicas.
- Input.
- Macros das Teclas
- Bitmaps.
- Double Buffering.
- Sons.
- Timers.
- Transparência.
- Ângulos.
- Inclusão de libs.
- gstream.
- alpng.
=========================================================================================
Introdução
O Allegro é uma API Open Source, multiplataforma*, voltada para a programação de jogos 2D, possui uma vasta comunidade de desenvolvedores e é adotada em projetos de pequeno porte.
Também possui suporte a aplicações 3D, porém suas rotinas neste aspecto são muito lentas e ineficientes, não sendo recomendável o seu uso para tal finalidade.
Possui suporte para interface gráfica, gerencia mouse, teclado e joystick, possui temporizadores de alta resolução, suporta sons, bitmaps, e também conta com diversas outras APIs que fazem com que sua aplicação Allegro suporte diversos outros tipos de arquivos, como por exemplo a lib Alpng, que dá suporte a bitmaps da extensão png.
Para uma aplicação provida de uma interface interessante, além de dominar a linguagem de programação, bem como a lógica, é necessário um trabalho de design, para assegurar um front-end agradável ao usuário, sendo assim, habilidades com o Photoshop entre outros softwares da espécie, ou uma equipe com essas características são essenciais para um projeto que visa ter um acabamento mais profissional.
*Suporte para:
- DOS.
- Windows.
- Linux.
- Mac (OS X).
- BeOS.
- QNX.
=========================================================================================
Endentação
Entende-se por endentação o espaçamento existente no código fonte, o tamanho do recuo e/ou avanço dos elementos hierarquicamente dispostos.
Apesar de não ser vital para uma aplicação, a endentação é de suma importância para um código legível e com aspecto profissional.
Na linguagem C / C++, a endentação assume um papel meramente estético, ao contrário de linguagens como Python, Occam e Haskell, em que a endentação é obrigatória.
Existem diversos estilos de endentação, é aconselhável que o programador crie o seu próprio e o siga metodicamente.
Eu pessoalmente uso minha “própria” endentação, que é a mesma usada por muitos, sempre contando 4
espaços para abrir chaves, e novamente contando 4 espaços para o código que vem entre as chaves, recuando 4 espaços para fechar as chaves, e novamente recuando mais 4 espaços para seguir o fluxo do programa.
Em caso de instruções como if, else, for, entre outras, os 4 espaços são contados a partir da primeira letra da instrução.
Exemplo:
main()
{
int a;
if (a > b)
{
a = b;
b++;
}
else if (a == b)
{
}
}
Exemplo:
Código em C sem a endentação:
if(a>b)
{
a = b;
b++;
}
for(i=0;i
{
a+=b+i:
b+=a;
}
Código em C com a endentação:
if( a > b )
{
a = b;
b++;
}
for( i=0; i
{
a += b + i:
b += a;
}
Percebe-se que o código com endentação é mais legível e agradável de ler, enquanto o primeiro fica confuso.
Em alguns lugares encontra-se escrito Indentação, ou Identação, que é uma forma ‘aportuguesada’ do termo em inglês ‘Indented’.
=========================================================================================
Notação Húngara
A Notação húngara, criada por Charles Simonyi, visa facilitar o reconhecimento do tipo de variável num programa. O nome foi dado a partir de uma brincadeira comum entre os primeiros a conhecer a notação que a achavam estranha, fazendo o seguinte comentário: "É tão estranho que até parece húngaro".
Esta técnica é muito empregada por grandes empresas como a Microsoft, e consiste em pré-fixar a variável com uma ou mais letras que identificam o seu tipo.
|
Seqüência
|
Tipo
|
|
- 1. by
- 2. c
- 3. s
- 4. i
- 5. si
- 6. l
- 7. f
- 8. b
- 9. d
- 10. dw
- 11. fn
- 12. h
- 13. lp
- 14. w
- 15. sz
- 16. g_
- 17. m_ ou c_
|
- 1. BYTE ou UCHAR
- 2. char
- 3. vetor de char
- 4. int
- 5. short int
- 6. long
- 7. float
- 8. bool
- 9. double
- 10. DWORD ( unsigned long )
- 11. Ponteiro para função
- 12. controle ( HANDLE )
- 13. Ponteiro long
- 14. WORD ( unsigned short )
- 15. String terminada em NULL
- 16. Variável global
- 17. Variável membro de classe.
|
Exemplo:
- char sString[10];
- bool bSemaforo;
- int iAltura;
Observação: Em alguns pontos, para descrever as funções do allegro, utilizou-se a notação Húngara nos parâmetros de funções, apenas para uma distinção mais rápida, porém, por padrão, não se deve utilizar a notação húngara na assinatura das funções/métodos.
=========================================================================================
Comentários
Ainda visando uma estética agradável e um código legível que pode ser facilmente entendido por outros programadores, contamos com um recurso muito importante, os comentários.
É importante criar um layout para seus comentários como, por exemplo, um cabeçalho para as funções.
Exemplo:
//|************************************************|
//| Nome: Push *|
//| Desc: Função para inserir um dado na pilha. *|
//| Pams: Stack, a pilha para inserir o dado. *|
//| ~~~~ iNovoDado, o dado a ser inserido. *|
//|************************************************|
bool Push(Stack *TheStack, int NewData)
{
struct stNodo *aux;
aux=(struct stNodo*)malloc(sizeof(struct stNodo));
if (aux==NULL)
return false;
aux->iDado = NewData;
aux->prox = TheStack->topo;
TheStack->topo = aux;
return true;
}
Vemos nesse exemplo o cabeçalho da função Push , nele se encontra o nome da função, a descrição de sua funcionalidade, e a listagem de todos os parâmetros, dessa forma fica fácil o entendimento do código fonte.
=========================================================================================
Instalação
A instalação do Allegro é muito simples.
Usaremos durante este mini-curso, a IDE DevC++ v4.9.9.2, que conta com diversos Packages, que facilita muito a inclusão de outras APIs.
O DevC++ apesar de ser de uso muito simples e intuitivo, é uma IDE que a tempos não é atualizada, recomendo a utilização de outra IDE também grátis, chamada Code::Blocks, que é atualizada constantemente pois é OpenSource, e possui diversas características superiores.
Instalando com DevC++:
Junto deste material, encontra-se a pasta chamada ‘Arquivos_Necessarios’, dentro dela está o instalador do DevC++ v4.9.9.2, execute-o.
Depois de instalado o DevC++, ainda dentro de ‘Arquivos_Necessários’, existe uma pasta chamada ‘Packages’, onde existe um Package de nome ‘allegro-4.2.2-1len.DevPak’, execute-o.
Pronto, o DevC++ v4.9.9.2 já está instalado juntamente com o Allegro
Instalando com Code::Blocks:
Com o Code::Blocks é ainda mais fácil, pois a instalação que disponibilizei, já vem configurada para a utilização do allegro, ou seja, basta instalar a IDE Code::Blocks, que o Allegro já será instalado automaticamente.
Esta versão do Code::Blocks foi feita pela comunidade Programadores De Jogos.
Criando um projeto:
Para criar uma aplicação Allegro, é obrigatório a criação de um novo projeto para isso, tanto no DevC++ como no Code::Blocks, vá respectivamente, em:
- File > New > Project > Multimedia > Allegro Application ( static )
- File > New > Project > Allegro Application
=========================================================================================
HelloWorld Allegro
Considerações iniciais:
Sempre incluir #include
Chame função allegro_init(); no começo do programa.
Coloque END_OF_MAIN(); depois do main().
Pressione Ctrl+Alt+End para terminar qualquer programa Allegro.
HelloWorld:
#include
int main()
{
// Função obrigatória, para inicializar o allegro //
allegro_init();
// Permite a utilização de rotinas para entrada de dados via teclado //
install_keyboard();
// Setando o modo gráfico //
set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
// Exibi a mensagem “Hello World” //
textprintf_ex(screen, font, 10, 20, makecol(200, 200, 20), -1, "Hello World");
// Espera uma tecla ser pressionada //
readkey(); // espera uma tecla ser pressionada
return 0;
}
END_OF_MAIN() // Sempre colocar depois do main() //
Entendendo o programa:
Primeiramente incluímos a API do allegro:
Chamamos a função responsável por inicializar o allegro:
Para futuramente usarmos a entrada de dados utilizando o teclado, chamamos a função responsável por esse processo:
Chamamos a função responsável por iniciar o modo gráfico:
- set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
O primeiro parâmetro diz qual o modo de exibição da janela, comumente são usadas 2 macros:
- GFX_AUTODETECT_WINDOWED
- GFX_AUTODETECT_FULLSCREEN
A primeira macro diz à aplicação que o programa rodará em modo Janela, enquanto a segunda macro irá produzir um programa em modo Tela Cheia.
O segundo parâmetro e o terceiro parâmetro dizem quais as dimensões terá o aplicativo, neste caso estamos fazendo um programa com um tamanho de 640x480 pixels.
O quarto parâmetro e o quinto parâmetro especificam o tamanho mínimo da tela virtual, quando não utilizamos, ou não nos importamos com a tela virtual (que é o nosso caso), passamos como parâmetro o numero 0.
Chamamos agora a função responsável por exibir uma mensagem na tela.
Detalhes sobre seus parâmetros serão visto mais a frente.
- textprintf_ex(screen, font, 10, 20, makecol(200, 200, 20), -1, "Hello World");
Por fim, chamamos uma função que pausa o programa e espera por uma tecla ser pressionada, lembre-se, ela depende do teclado, então se install_keyboard(); não tiver sido chamada, esta função não terá efeito algum.
Conclusão:
Este programa exibirá uma tela preta, e quando for pressionada uma tecla, o programa chegará ao fim. O código apresentado acima é o mais enxuto possível para um primeiro contato com o allegro.
=========================================================================================
Funções Básicas
Funções:
Esta é a principal função, e deve obrigatoriamente ser chamada para uma aplicação Allegro funcionar, lembre-se que a chamada desta função deve ser a primeira a ser feita, antes de qualquer outra função Allegro.
Exemplo de uso: allegro_init();
- int makecol( int iRed, int iGreen, int iBlue );
Passando-se os valores dos tons (que variam de 0 a 255), de vermelho, verde e azul, esta função retorna o código da cor.
Este método é muito utilizado para representar cores em diversas outras funções desta API.
Exemplo de uso: makecol (255, 0, 0 );
- void rest(unsigned int uiTime)
Interrompe a execução do programa durante um intervalo de tempo igual ao passado como parâmetro, em milisegundos.
Exemplo de uso: rest (1000);
- void putpixel(BITMAP *bmp, int iX, int iY, int iColor)
Colore um pixel do bitmap, nas coordenadas especificadas no segundo parâmetro e terceiro parâmetro, na cor passada no quarto parâmetro.
Exemplo de uso: putpixel(screen, 20, 300, makecol(0, 200, 30));
- void getpixel(BITMAP *bmp, int iX, int iY, int iColor)
Recupera o valor da cor de um pixel do bitmap, nas coordenadas especificadas no segundo parâmetro e terceiro parâmetro, na cor passada no quarto parâmetro.
Exemplo de uso: int iPixelColor = getpixel(screen, 20, 300, makecol(0, 200, 30 ));
- void floodfill(BITMAP *bmp, int iX, int iY, int iColor);
Preenche um bitmap com a cor especificada, em um espaço fechado, a partir do ponto X e Y.
Exemplo de uso: floodfill (screen, 20, 30, makecol(20, 60, 300));
- void vline(BITMAP *bmp, int iX, int iY1, int iY2, int iColor);
- void hline(BITMAP *bmp, int iX1, int iY, int iX2, int iColor);
- void line(BITMAP *bmp, int iX1, int iY1, int iX2, int iY2, int iColor);
A primeira função desenha uma linha vertical, a segunda função desenha uma linha horizontal a ultima função desenha uma linha entre 2 pontos quaisquer.
Exemplo de uso: line (screen, 20, 300, 400, 500, makecol(20, 60, 300));
- void rect(BITMAP *bmp, int iX1, int iY1, int iX2, int iY2, int iColor);
- void rectfill(BITMAP *bmp, int iX1, int iY1, int iX2, int iY2, int iColor);
A primeira função desenha um retângulo sem preenchimento, com o contorno colorido, enquanto a segunda função desenha um retângulo com preenchimento.
Exemplo de uso: rectfill (screen, 20, 300, 400, 500, makecol(20, 60, 300));
- void circle(BITMAP *bmp, int iX, int iY, int iRaio, int iColor);
- void circlefill(BITMAP *bmp, int iX, int iY, int iRaio, int iColor);
A primeira função desenha um círculo sem preenchimento, com o contorno colorido, enquanto a segunda função desenha um círculo com preenchimento.
Exemplo de uso: circlefill (screen, 20, 300, 10, makecol(20, 60, 300));
- void ellipse(BITMAP *bmp, int iX, int iY, int iXRaio, int iYRaio, int iColor);
- void ellipsefill(BITMAP *bmp, int iX, int iY, int iXRaio, int iYRaio, int iColor);
A primeira função desenha uma elipse sem preenchimento, com o contorno colorido, enquanto a segunda função desenha uma elipse com preenchimento.
Exemplo de uso: ellipsefill (screen, 20, 300, 5, 10, makecol(20, 60, 300));
- void textprintf_ex( BITMAP *bmp, FONT font, int iX, int iY, int iColor, int iCorDeFundo, char sTexto, ... );
Função para exibir um texto na tela, o sexto parâmetro deve ser -1 para um fundo transparente.
Exemplo de uso:
textprintf_ex(screen, font, 10, 20, makecol(200, 200, 20), -1, "X vale : %d", 10 );
=========================================================================================
Input
Considerações:
As funções como cout, cin, printf e scanf não podem ser usadas em modo gráfico, no caso das funções de saída de texto, o Allegro possui suas próprias funções, já no caso da entrada de texto, teremos de usar uma biblioteca de auxílio chamada gstream, veremos isso mais à frente.
Mouse Input:
Instala o handle de mouse do Allegro.
É necessário chamar essa função para se usar as funções que manuseiam o mouse.
Exemplo de uso: install_mouse();
- void show_mouse(BITMAP *bmp)
Mostra o cursor no bitmap passado como parâmetro, usualmente este bitmap é o screen, ou seja, a tela.
Exemplo de uso: show_mouse(screen);
- void set_mouse_speed(int iXSpeed, int iYSpeed)
Determina o quão rápido o cursor do mouse irá se mover, aceita valores de 1 a 10.
Exemplo de uso: set_mouse_speed(1, 1);
- void position_mouse ( int iXPosition, int iYPosition )
Move o cursor do mouse para a posição X e Y da tela.
Exemplo de uso: position_mouse(300, 100);
- if ( mouse_b ) // Se qualquer botão do mouse for pressionado dá verdade //
- if ( mouse_b&1 ) //Se botão esquerdo do mouse for pressionado dá verdade//
- if ( mouse_b&2 ) // Se botão direito do mouse for pressionado dá verdade //
- if ( mouse_b&3 ) // Se botão central do mouse for pressionado dá verdade //
- int mouse_x // Guarda a posição X atual do cursor do mouse //
- int mouse_y // Guarda a posição Y atual do cursor do mouse //
Keybord Input:
Instala o handle de teclado Allegro.
É necessário chamar essa função para se usar as funções que manuseiam o teclado.
Exemplo de uso: install_keyboard ();
Irá retornar um valor diferente de zero se alguma tecla for pressionada.
Exemplo de uso: if( keypressed() ) ...
Semelhante ao keypressed(), mas neste caso, ele retorna qual tecla foi pressionada.
Outra característica, é que a readkey() retorna a tecla pressionada, mas com algumas informações extras, que geralmente nós não queremos, para remover esta inconveniência pegamos o resto da divisão do readkey() por 256.
Se nenhuma tecla for pressionada, o programa ficará pausado até uma tecla ser pressionada, esta é o principal uso desta função.
Exemplo de uso: char ch = readkey() % 256;
Este é um array de teclas, indicando se a tecla está pressionada ou não.
Este é o método mais utilizado para interagir com o teclado.
Exemplo de uso: if( key[ KEY_ENTER ] ) // A tecla Enter foi pressionada //
Confira a lista das teclas a seguir:
Macros das Teclas
Listagem das teclas:
|
KEY_A ~ KEY_Z
|
|
KEY_0 ~ KEY_9
|
|
KEY_F1 ~ KEY_F12
|
|
KEY_ESC
|
KEY_MINUS
|
KEY_ENTER
|
KEY_EQUALS
|
KEY_TAB
|
|
KEY_BACKSPACE
|
KEY_OPENBRACE
|
KEY_CLOSEBRACE
|
KEY_LCONTROL
|
KEY_RCONTROL
|
|
KEY_COLON
|
KEY_TILDE
|
KEY_QUOTE
|
KEY_LSHIFT
|
KEY_RSHIFT
|
|
KEY_BACKSLASH
|
KEY_COMMA
|
KEY_STOP
|
KEY_SLASH
|
KEY_ASTERISK
|
|
KEY_ALT
|
KEY_SPACE
|
KEY_CAPSLOCK
|
KEY_NUMLOCK
|
KEY_SCRLOCK
|
|
KEY_HOME
|
KEY_END
|
KEY_PGUP
|
KEY_PGDN
|
KEY_MINUS_PAD
|
|
KEY_MENU
|
KEY_PLUS_PAD
|
KEY_INSERT
|
KEY_DEL
|
KEY_PRTSCR
|
|
KEY_UP
|
KEY_DOWN
|
KEY_RIGHT
|
KEY_LEFT
|
KEY_PAUSE
|
=========================================================================================
Prática 1.0
Considerações:
Munidos de um conhecimento geral de algumas das principais funções do Allegro, podemos discutir uma prática em cima do aprendido.
Loop Principal:
Construiremos um loop principal onde acontecerá toda a lógica do programa, como primeira prática, apresentarei um aplicativo que mostra as coordenadas do mouse na tela.
Mouse na tela:
#include
int main()
{
// Função obrigatória, para inicializar o allegro //
allegro_init();
// Permite a utilização de rotinas para a entrada de dados via teclado //
install_keyboard();
// Setando o modo gráfico //
set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
while ( ! key[ KEY_ESC ] ) // Enquanto a tecla ESC não for pressionada //
{
// Exibi as coordenadas do mouse na tela //
textprintf_ex( screen, font, 10, 10, makecol(200, 200, 20), -1, "X= %d , Y= %d ", mouse_x, mouse_y );
if( key[ KEY_A ] ) // Se pressionar a tecla A //
textprintf_ex( screen, font, 10, 20, makecol(10, 10, 20), -1, "Voce pressionou ‘A’", 20, 20 );
}
return 0;
}
END_OF_MAIN() // Sempre colocar depois do main() //
Entendendo o programa:
O programa ficará preso neste loop, e só sairá quando a tecla ESC for pressionada, usamos o vetor de teclas key[], especificamente na posição KEY_ESC, e o testamos para saber se a tecla ESC está sendo pressionada ou não, quando ela for pressionada, o operador ! irá inverter o resultado, fazendo a expressão contida no while assumir um estado falso e assim quebrar o loop.
- while ( ! key[ KEY_ESC ] )
Usamos a função textprintf_ex para exibir na tela a posição atual do mouse, note a semelhança com o printf.
A máscara %d indica que a função espera um argumento do tipo int para ser exibido na tela.
Usamos também as variáveis mouse_x e mouse_y que contém um valor inteiro corresponde as atuais posições do cursor.
- textprintf_ex( screen, font, 10, 10, makecol(200, 200, 20), -1, "X= %d , Y= %d ", mouse_x, mouse_y );
Por fim, novamente utilizamos o vetor key[], mas agora para testar se a tecla A está sendo pressionada, sendo assim, toda vez que o usuário pressionar a tecla A, será rapidamente mostrada a mensagem “Voce pressionou A”.
- textprintf_ex( screen, font, 10, 20, makecol(10, 10, 20), -1, "Voce pressionou ‘A’", 20, 20 );
Assim que o usuário pressionar ESC a aplicação terminará.
Vale lembrar que para terminar qualquer aplicação Allegro, também se pode pressionar a seguinte seqüência:
=========================================================================================
Bitmaps
Considerações:
O principal propósito em utilizar uma API gráfica é dar uma aparência elegante ao projeto, e para isso é indispensável o uso de imagens previamente trabalhadas, e o Allegro nos disponibiliza o recurso de carregar bitmaps da extensão .bmp em nossos programas.
Um bitmap é definido pela estrutura BITMAP que guardará a imagem, e dentro dessa estrutura temos o campo ‘w’ que significa width (largura) e o campo ‘h’ que signiica height (altura).
Uma variável do tipo BITMAP deve ser sempre um ponteiro, ou seja, possuir um * antes de seu nome.
O bitmap screen é o principal bitmap, tudo que é desenhado neste bitmap é mostrado ao usuário, tudo que vemos pelo monitor está no bitmap screen.
Veremos as funções mais comuns, responsáveis pelo tratamento dos bitmaps, e depois, segue-se uma prática com as devidas explicações.
Declarando a variável responsável por uma imagem:
Esta é a declaração de uma variável que será usada para criação ou carregamento de imagens
Funções:
- BITMAP *create_bitmap(int iTamanho, int iAltura)
Esta função cria um bitmap virtual das dimensões especificadas em seus parâmetros, e conterá pixels de cores randômicas, então, se precisar, use uma função para limpar o bitmap criado antes de usá-lo.
Exemplo de uso:
BITMAP *bmpBitmap_Virtual = create_bitmap(800, 600);
- BITMAP *load_bitmap(const char sCaminho, RGB rgpPalette)
Esta função carrega um bitmap do arquivo, no primeiro parâmetro é passado o caminho da imagem a ser carregada, no segundo parâmetro é passado a paleta de cores, mas nós não precisamos nos preocupar com isso, e neste material, sempre passaremos NULL como parâmetro.
Exemplo de uso:
BITMAP *bmpFundo = load_bitmap(“Pasta/Fundo.bmp”, NULL);
- void destroy_bitmap( bitmap *bmpImagem )
Esta função destrói um bitmap criado ou carregado, liberando a memória utilizada por ele.
Os bitmaps são destruídos automaticamente quando o programa termina, mas é importante liberar a memória em runtime, para evitar um consumo desnecessário de memória.
E lembre-se, nunca destrua um bitmap duas vezes ou o programa provavelmente irá abortar.
Exemplo de uso: destroy_bitmap( bmpFundo);
- void clear( bitmap *bmpImagem )
Esta função limpa os pixels do bitmap passado como argumento para preto.
Exemplo de uso: clear( bmpFundo);
- void clear_to_color( bitmap *bmpImagem, int iColor )
Esta função limpa os pixels do bitmap passado no primeiro parâmetro para a cor passada no segundo parâmetro.
Exemplo de uso: clear_to_color( bmpFundo, makecol( 255, 20, 100 );
- void draw_sprite( bitmap *bmpDestino, *bmpOrigem, int iX, int iY )
Esta função desenha o bitmap passado no segundo parâmetro direto no bitmap passado no primeiro parâmetro, lembrando que a tela, que nos vemos, é um bitmap chamado screen.
Exemplo de uso: draw_sprite( screen, bmpFundo, 0, 0 );
- void draw_sprite_v_flip( bitmap *bmpDestino, *bmpOrigem, int iX, int iY )
Esta função desenha o bitmap passado no segundo parâmetro direto no bitmap passado no primeiro parâmetro, porém o bitmap origem é virado no sentido da vertical.
Exemplo de uso: draw_sprite_v_flip( screen, bmpFundo, 0, 0 );
- void draw_sprite_h_flip( bitmap *bmpDestino, *bmpOrigem, int iX, int iY )
Esta função desenha o bitmap passado no segundo parâmetro direto no bitmap passado no primeiro parâmetro, porém o bitmap origem é virado no sentido da horizontal.
Exemplo de uso: draw_sprite_h_flip( screen, bmpFundo, 0, 0 );
- void draw_sprite_vh_flip(bitmap *bmpDestino, *bmpOrigem, int iX, int iY)
Esta função é como as 2 anteriores, porém faz as 2 transformações ao mesmo tempo.
Exemplo de uso: draw_sprite_vh_flip( screen, bmpFundo, 0, 0 );
- void rotate_sprite( bitmap *bmpDestino, *bmpOrigem, int iX, int iY, fixed lAngulo )
Esta função desenha o bitmap passado no segundo parâmetro direto no bitmap passado no primeiro parâmetro, porém o bitmap origem é rotacionado pelo ângulo passado no quinto parâmetro, (fixed = long).
Veremos a parte de ângulos mais a frente.
Exemplo de uso: rotate_sprite ( screen, bmpFundo, 0, 0, DEGREES(45) );
- void blit ( bitmap *bmpOrigem, *bmpDestino, int iXOrigem, int iYOrigem, int iXDestino, int iYDestino, int iTamanho, int i Largura)
Esta função de copia a imagem, ou seja, ela transfere um bloco da imagem, mais especificamente, ela copia um retângulo de pixels da origem, com o X e Y iniciais passados no terceiro parâmetro e no quarto parâmetro, para um retângulo no destino, com o X e Y inicias contidos no quinto parâmetro e no sexto parâmetro.
Para copiar um bitmap inteiro para outro, passamos 0 nestes parâmetros.
Os dois últimos parâmetros especificam o tamanho e a larguras do retângulo a ser copiado..
Este é o principal método usado para passar o bloco de imagem do back buffer, para a screen, o que veremos mais a frente em Double Buffering.
Exemplo de uso: blit( bmpFundo, screen ,0, 0, 0, 0, 800, 600 );
- void stretch_blit ( bitmap *bmpOrigem, *bmpDestino, int iXOrigem, int iYOrigem, int iOrigemTamanho, int iOrigemLargura,int iXDestino, int iYDestino, int iDestinoTamanho, int iDestinoLargura)
Esta função tem uma funcionalidade parecida com a da função blit, porém permite que os retângulos copiados possam ser de tamanhos diferentes, produzindo, dependo do caso, um efeito de distorção.
Exemplo de uso: stretch_blit( bmpFundo, screen ,0, 0, 0, 0, 800, 600 );
=========================================================================================
Prática 2.0
Considerações:
Veremos agora como carregar e exibir alguns bitmaps em sua aplicação.
Nunca carregue um bitmap dentro de um loop, a não ser que você saiba exatamente o que está fazendo, e certifique-se se destruí-lo corretamente.
Exibindo Bitmaps:
#include
int main()
{
// Função obrigatória, para inicializar o allegro //
allegro_init();
// Permite a utilização de rotinas para a entrada de dados via teclado //
install_keyboard();
// Setando o modo gráfico //
set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
BITMAP *bmpFundo = load_bitmap( “Pasta/Fundo.bmp”, NULL );
BITMAP *bmpBotao = load_bitmap( “Pasta/Botao.bmp”, NULL );
while ( ! key[ KEY_ESC ] ) // Enquanto a tecla ESC não for pressionada //
{
draw_sprite( screen, bmpFundo, 0, 0 ); // Desenhando o bmpFundo na tela //
draw_sprite( screen, bmpBotao, 100, 300 ); // Desenhando o bmpBotao na tela //
clear( screen ); // Limpando a tela //
}
destroy_bitmap( bmpFundo ); // Destruindo o bmpFundo //
destroy_bitmap( bmpBotao ); // Destruindo o bmpBotao //
return 0;
}
END_OF_MAIN() // Sempre colocar depois do main() //
Obs: Para obter o tamanho e a largura dos bitmaps, é só usar:
bmpFundo->w // Retorna a largura do bitmap bmpFundo //
bmpFundo->h // Retorna a altura do bitmap bmpFundo //
Entendendo o programa:
Primeiramente declaramos duas variáveis do tipo BITMAP que irão ler do arquivo a imagens Fundo.bmp e Botão.bmp.
Estas variáveis têm obrigatoriamente de ser ponteiros.
Poderíamos testar se o carregamento do arquivo foi bem sucedido, verificando se as variáveis são diferentes de NULL, se sim, tudo ocorreu bem.
- BITMAP *bmpFundo = load_bitmap( “Pasta/Fundo.bmp”, NULL );
- BITMAP *bmpBotao = load_bitmap( “Pasta/Botao.bmp”, NULL );
Entramos agora, no loop principal.
- while ( ! key[ KEY_ESC ] )
Utilizamos a função draw_sprite para poder desenhar o bitmap bmpFundo direto na tela ( screen ), nas coordenadas 0 e 0, ou seja na origem da tela.
- draw_sprite( screen, bmpFundo, 0, 0 );
Desenhamos também o bitmap bmpBotao direto na screen nas coordenadas 100 e 300.
- draw_sprite( screen, bmpBotao, 100, 300 );
No fim do loop limpamos o bitmap screen.
Neste caso em específico, como não há movimento nem sobreposição de bitmaps, não seria necessário limpar a screen, mas o fizemos para simular uma aplicação corriqueira manuseando bitmaps, provavelmente você verá que as imagens parecem estar piscando, este é um problema que será discutido e resolvido mais à frente, com a técnica Double Buffering.
Agora por fim, destruimos os bitmaps criados, liberando memória, nunca se esqueça deste passo, porém nunca o faça duas vezes para um mesmo bitmap, a não ser que você tenha uma função de carregar ou de criar neste mesmo bitmap, depois do ultimo destroy aplicado no mesmo.
- destroy_bitmap( bmpFundo );
- destroy_bitmap( bmpBotao );
=========================================================================================
Double Buffering
Considerações:
Como visto na Prática 2.0, quando as imagens são desenhas diretamente na screen ( tela ), acaba ocorrendo um efeito indesejado em que as imagens ficam piscando, isso ocorre pelo fato que a cada iteração do programa, a screen é limpa, e em seguida as imagens são desenhadas uma a uma, e em seguida a tela é limpa novamente, e assim sucessivamente.
Este fato ocorre várias vezes por segundo, mas mesmo assim nossos olhos conseguem perceber este processo, nos dando a impressão que as imagens estão piscando.
Para contornar, contamos com uma técnica chamada Double Buffering.
Double Buffering:
Esta técnica consiste em criar uma tela ‘virtual’, para isso criamos um bitmap do mesmo tamanho da tela, este bitmap é comumente chamado de buffer, ou backbuffer.
Nós não mais desenhamos e limpamos a screen, e ao invés disso, nos iremos limpar o buffer, e em seguida desenhar tudo que queremos nele, e depois copiaremos por meio da função blit, todo o buffer para a tela.
Agora a screen não é mais limpa a cada iteração, e assim não temos a sensação das imagens piscando, pois não chegamos a ver este processo, que agora ocorre no buffer, cujo qual não fica visível para o usuário.
=========================================================================================
Prática 3.0
Considerações:
Aplicaremos a técnica do Double Buffering no código apresentado na Prática anterior ( Prática 2.0 ).
Com isto conseguiremos eliminar o efeito indesejado em que as figuras aparentam estar piscando.
Aplicando o Double Buffering:
#include
int main()
{
// Função obrigatória, para inicializar o allegro //
allegro_init();
// Permite a utilização de rotinas para a entrada de dados via teclado //
install_keyboard();
// Setando o modo gráfico //
set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
BITMAP *bmpBuffer = create_bitmap(640, 480 ); // Criando o Buffer //
BITMAP *bmpFundo = load_bitmap( “Pasta/Fundo.bmp”, NULL );
BITMAP *bmpBotao = load_bitmap( “Pasta/Botao.bmp”, NULL );
while ( ! key[ KEY_ESC ] ) // Enquanto a tecla ESC não for pressionada //
{
draw_sprite( bmpBuffer, bmpFundo, 0, 0 ); // Desenhando o bmpFundo no buffer //
draw_sprite(bmpBuffer, bmpBotao,100,300); //Desenhando o bmpBotao no buffer //
blit( bmpBuffer, screen, 0, 0, 0, 0, 640, 480 ); //Copiando o Buffer para a screen //
clear( bmpBuffer ); // Limpando o Buffer //
}
destroy_bitmap( bmpBuffer ); // Destruindo o bmpBuffer //
destroy_bitmap( bmpFundo ); // Destruindo o bmpFundo //
destroy_bitmap( bmpBotao ); // Destruindo o bmpBotao //
return 0;
}
END_OF_MAIN() // Sempre colocar depois do main() //
Entendendo o programa:
A primeira alteração visível é a declaração da variável bmpBuffer, ela será a nossa ‘tela virtual’, é nela que ocorrerá os processos de desenho e limpeza.
- BITMAP *bmpBuffer = create_bitmap(640, 480 );
Agora, como se pode notar, as imagens não estão mais sendo desenhadas na screen ( tela ), e sim estão sendo desenhadas no bitmap bmpBuffer.
- draw_sprite( bmpBuffer, bmpFundo, 0, 0 );
- draw_sprite(bmpBuffer, bmpBotao,100,300);
Depois que foi tudo devidamente desenhado no Buffer, podemos agora apresentar o bmpBuffer para o usuário, desenhando todo o conteúdo do bmpBuffer na tela através da função blit.
- blit( bmpBuffer, screen, 0, 0, 0, 0, 640, 480 );
Finalmente exibido, podemos agora limpar o conteúdo do bmpBuffer, preparando-o para poder receber novas imagens da próxima iteração do loop.
Não se esqueça, que bitmaps criados com a função create_bitmap também têm de ser destruídos.
- destroy_bitmap( bmpBuffer );
Conclusão:
Double Buffering é uma técnica muito simples, e rezumindo o que mudou, é que, ao invés das imagens serem desenhadas na tela, elas são desenhadas em uma tela imaginária, chamada bmpBuffer, que nos criamos no início do programa,.
Após os devidos processamentos, esta tela imaginaria é desenhada na screen, de modo que, uma vez na screen, ela pode ser vista pelo usuário.
=========================================================================================
Sons
Considerações:
A utilização de sons não é uma constante nas aplicações gráficas, mas sua presença cria um maior envolvimento com o aplicativo.
Aprenderemos como utilizar os formatos de sons suportados nativamente pelo Allegro, e eles são:
Com o auxílio de algumas bibliotecas adicionais conseguimos suporte para outros formatos também.
Declarando a variável responsável por um som:
- SAMPLE *splSom;
- MIDI *midSom
Esta são as possíveis declarações de uma variável que será usada no manuseio de sons.
Funções:
- int install_sound( int iDigi, int iMidi, const char cfgCaminho )
Primeiramente temos que instalar o handle que é responsável pelo manuseio de sons, se está função não for chamada, as funções de sons não funcionarão.
Exemplo de uso: install_sound( DIGI_AUTODETECT, MIDI_AUTODETECT, 0 )
- SAMPLE *load_sample( const char *sCaminho)
Esta função carrega um arquivo de som wav do arquivo.
Exemplo de uso: SAMPLE *splSom = load_sample(“Pasta/Musica.wav”);
- MIDI *load_midi( const char *sCaminho)
Esta função carrega um arquivo de som mid do arquivo.
Exemplo de uso: SAMPLE *splSom = load_sample(“Pasta/Musica.wav”);
- void stop_sample( const SAMPLE *splSom )
Interrompe a execução de um sample que esteja sendo executado.
Exemplo de uso: stop_sample(splSom);
- int play_sample( const SAMPLE *splSom, int iVolume, int iBalanco, int iFrequencia, int iLoop )
Esta função toca um arquivo que já foi carregado e armazenado em uma variável do tipo SAMPLE.
O primeiro parâmetro é o sample que deve ser tocado.
O segundo parâmetro é o volume, que varia de 0 a 255.
O terceiro parâmetro é o balanço, que varia de 0 a 255, 0 o som sai só na caixa esquerda, 255 só na direita e 128 é o mais balanceado e sairá em todas.
O quarto parâmetro é responsável pela freqüência do som, ou seja, a velocidade que ele será tocado, uma freqüência de 1000 é a freqüência normal do som, um valor menor o som tocará mais rápido, e por conseqüência, um valor maior farpa com que o som toque mais devagar.
O quinto parâmetro é responsável pelo loop do som, se for passado um valor diferente de zero, o som será tocado até a função stop_sample ser chamada.
Exemplo de uso: play_sample( splSom, 255, 128, 1000, 0 );
- int play_midi( MIDI *midSom, int iLoop )
Esta função toca um arquivo que já foi carregado e armazenado em uma variável do tipo MIDI.
Exemplo de uso: play_midi( midSom, 0 );
- void destroy_sample( SAMPLE *splSom )
Função responsável por destruir um sample criado e limpar a memória.
Exemplo de uso: destroy_sample( splSom );
- void destroy_midi( MIDI *midSom)
Função responsável por destruir um sample criado e limpar a memória.
Exemplo de uso: destroy_midi( midSom );
- void set_volume( int iSampleVolume, int iMidiVolume );
Seta o volume global tanto para MIDI como para SAMPLE.
O valor do volume varia de 0 a 255.
Exemplo de uso: set_volume( 255, 255 );
=========================================================================================
Prática 4.0
Considerações:
O funcionamento do carregamento dos sons é bem parecido com o carregamento das imagens, cria-se a variável, carrega-se o arquivo, libera-se a memória.
Tocando sons:
#include
int main()
{
// Função obrigatória, para inicializar o allegro //
allegro_init();
// Permite a utilização de rotinas para a entrada de dados via teclado //
install_keyboard();
// Setando o modo gráfico //
set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
// Habilitando o som //
install_sound( DIGI_AUTODETECT, MIDI_AUTODETECT, 0 )
// Carregando o Som //
SAMPLE *splSom = load_sample(“Pasta/Musica.wav”);
// Tocando o Som //
play_sample( splSom, 255, 128, 1000, 0 );
destroy_sample( splSom ); // Destruindo o splSample //
readkey(); // Esperando uma tecla ser pressionada //
return 0;
}
END_OF_MAIN() // Sempre colocar depois do main() //
=========================================================================================
Timers
Utilizando os Timers:
Primeiro chamamos a função responsável pelo manuseio do tempo:
Agora criamos uma variável global, cuja qual, será incrementada a cada intervalo de tempo que definirmos.
- volatile int g_iContador = 0;
Agora definimos a função que irá incrementar a variável g_iContador a cada intervalo de tempo que definiremos mais a diante.
Esta função será como um callback.
As três ultimas macros tem um papel fundamental para um bom funcionamento, nunca se esqueça de incluí-las, e servem para garantir que o SO não irá ‘mexer’ nas variáveis / funções.
- void vIncrementa()
- {
- g_iContador ++;
- }
- END_OF_FUNCTION( vIncrementa );
- LOCK_FUNCTION( vIncrementa );
- LOCK_VARIABLE( vIncrementa );
Agora chamamos a função responsável por abrir um thread a partir da função callback que estamos passando como parâmetro.
No segundo parâmetro passamos uma macro como parâmetro:
SECS_TO_TIMER você passa quantos segundos você quer entre cada tick (chamada da função).
MSEC_TO_TIMER você passa quantos milisegundos você quer entre cada tick (chamada da função).
BPS_TO_TIMER você passa quantos ticks você quer por segundo.
BPM_TO_TIMER você passa quantos ticks você quer por minuto.
- install_int_ex( vIncrementa, SECS_TO_TIMER( 20 ) );
Prática 5.0
Uso de um Timer:
#include
volatile int g_iContador = 0;
void vIncrementa()
{
g_iContador ++;
}
END_OF_FUNCTION( vIncrementa );
LOCK_FUNCTION( vIncrementa );
LOCK_VARIABLE( vIncrementa );
int main()
{
// Função obrigatória, para inicializar o allegro //
allegro_init();
// Permite a utilização de rotinas para a entrada de dados via teclado //
install_keyboard();
// Setando o modo gráfico //
set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
// Habilitando o temporizador, e dizendo que será chamado a cada 5 segundos //
install_int_ex( vIncrementa, SECS_TO_TIMER( 5 ) );
while( ! key[ KEY_ESC ] )
{
// Mostrando o valor da variável global que está sendo incrementada //
textprintf_ex( screen, font, 10, 10, makecol(0, 0, 0), -1, "%d ", g_iContador);
}
return 0;
}
END_OF_MAIN() // Sempre colocar depois do main() //
Obs: A cada cinco (5) segundos a função vIncrementa será chamada, sendo assim g_iContador será acrescido em uma (1) unidade.
=========================================================================================
Transparência
Considerações:
As funções nativas do Allegro contam com um recurso de mascaramento de uma cor chamada Bright Pink, que é uma cor obtida através do RGB = ( 255, 0, 255), ou seja, 255 no Red ( vermelho ), 0 no Green ( verde ) e 255 no Blue ( azul ).
Note que apenas a cor 255, 0, 255 será escondida, então se houver qualquer tipo de sombra, causando por exemplo uma cor do tom 254, 0, 255, está cor irá aparecer.
Obtendo a transparência:
Primeiramente faça uma imagem que contenha a cor 255,0,255, em seguida utilize a seguinte função:
- void masked_blit ( bitmap *bmpOrigem, *bmpDestino, int iXOrigem, int iYOrigem, int iXDestino, int iYDestino, int iTamanho, int i Largura)
Está função tem uma funcionalidade parecida com a blit, vista anteriormente, porem, ela ignora os pixels da cor Bright Prink, quando em true color, ou então os pixels com valor 0, quando em modo 256 cores
Exemplo de uso: masked_blit( bmpFundo, screen ,0, 0, 0, 0, 800, 600 );
No caso de bitmaps da extensão bmp, a função draw_sprite também troca o Bright Pink por transparência.
Nada muda no código fonte, tendo como base os feitos anteriormente, que mostram imagens, a não ser que a cor mencionada não será exibida.
=========================================================================================
Ângulos
Considerações:
O allegro usa um formato bem peculiar para os ângulos usados em suas funções, então precisamos converter para o formato antes de utilizar.
Convertendo:
- #include
- #define DEGREES(x) int((x)/360.0*0xFFFFFF)
- #define RADIANS(x) int((x)/2/M_PI*0xFFFFFF)
Agora basta usar essas macros, passando como paramtro o ângulo ou radiano desejado.
Exemplo: rotate_sprite( bmpBuffer, bmpCarro, 200, 300, DEGREES( 45 ) );
=========================================================================================
Inclusão de libs
Considerações:
Libs é um termo vulgar que se refere a uma biblioteca / API / include.
O Allegro por si só não nos proporciona todos os recursos necessários para as aplicações, recursos tais que podem variar muito de programador para programador.
Mas isto não é um problema, pois contamos com diversas libs de apoio, que nos asseguram funcionalidades estendias sobre as atuais do Allegro.
Como um rápido exemplo, o Allegro, naturalmente nos dá um suporte para o gerenciamento de BITMAPS da extensão .bmp de 24 bits, porém o tamanho em disco de um bitmap desta extensão geralmente é de um tamanho considerável, e todos sabemos que o formato .png contém uma compressão que seria pertinente a um projeto mais leve.
O fato é que o Allegro não possui suporte para tal extensão, então recorremos para uma lib chamada ALPNG, que estende o uso das estruturas BITMAP e permite o carregamento de arquivos de imagens da extensão .png.
Instalando:
È muito simples, para o DevC++, essas bibliotecas são distribuídas como DevPaks, então basta você baixar e executar o DevPak correspondente pela biblioteca que você quer, e logo em seguida executá-lo.
Junto do material está disponível alguns DevPaks comumente usados.
Lembre-se o Code::Blocks também aceita os DevPaks.
Linker:
Para incluir a biblioteca no projeto, não basta apenas fazer #include , também precisamos linkar a biblioteca no projeto, cada bibliteca tem uma determinada sentença que deve ser adicionada as propriedades do projeto, que fica em:
Dev:
- Project > Project Options > Parameters > Linker
Code::Blocks:
- Project > Properties > Project > Project’s build options > Linker > Other linker options
=========================================================================================
GSTREAM
Considerações:
GSTREAM é uma biblioteca que estende as funcionalidades do Allegro, ela nos dá diversas funções de entrada e saída de dados.
Usaremos mais freqüentemente apenas a entrada de dados, a saída de dados pode ficar por conta tanto da própria gstream, como da alfont ou pelas próprias rotinas do Allegro.
Se você já usou os comandos cin e cout proveniente do C++, saiba que a sintaxe de entrada e saída desta lib é muito parecida.
Para instalar apenas execute o DevPak chamado “gstream-1.6-gcc3.4-2mol.DevPak”
Include:
Linker:
Declarando a variável responsável pelo Input/Output:
Este é um objeto da classe gstream, dele obteremos os métodos responsáveis pela manipulação do I/O advindo desta lib.
Funções:
Utilizando este método, providenciamos uma entrada de dados.
O que o usuário digitar será escrito na string sString.
Este método não se restringe só a strings, podendo ser usado para se escrever em uma variável do tipo int, float, double, etc.
As coordenadas X e Y aonde a entrada de dados irá ser feita, tem de ser determinadas previamente utilizando o método gs.goto.xy.
Exemplo de uso: gs >> iIdade;
Utilizando este método, temos uma saída de dados, mostrando o conteúdo da variável sString na tela.
As coordenadas X e Y aonde estes dados será exibidos tem de ser determinadas previamente utilizando o método gs.goto.xy
Exemplo de uso: gs << fAltura;
- void gstream::goto_xy(int iX, int iY);
Utilizando este método, podemos definir a posição atual em que a gstream está esperando uma entrada de dados ou saída de dados.
- Exemplo de uso: gs.goto_xy(100, 200);
- void gstream::set_max_input_length(int iMaxNumCaracteres);
Através deste método, podemos delimitar um número máximo de caracteres o usuário poderá entrar.
Exemplo de uso: gs.set_max_input_length(20);
- void gstream::set_bitmap (BITMAP *bmp);
Com este método podemos setar em qual bitmap a saída de dados da gstream serão exibidas.
Exemplo de uso: gs.set_bitmap (screen);
- void gstream::set_color (int iCor);
Com este método podemos mudar a cor da fonte.
Exemplo de uso: gs.set_color (makecol(20, 0, 255));
Limpa o buffer utilizado pela gstream.
Chamar esta função antes de utilizar alguma entrada de dados.
Exemplo de uso: gs << flush;
Reseta todas as alterações feitas para os valores padrões.
Exemplo de uso: gs.Reset;
=========================================================================================
Prática 6.0
Usando a GSTREAM:
// Adicionar ao linker : //
// - lgstrm //
#include
#include
int main()
{
allegro_init();
install_keyboard();
set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
char sNome[20];
gstream gs; // Criando o objeto chamado gs //
gs.set_bitmap (screen); // Setando a gstream para desenhar na screen //
gs.set_color (makecol(255, 0, 0)); // Definindo a cor da fonte para vermelho //
gs.goto_xy(10, 20); // Posicionando o cursor nas coordenadas 10, 20 //
// Dizendo que o número máximo de caracteres que o usuário poderá entrar é 19 //
gs.set_max_input_length(18);
gs << flush; // Limpando o buffer do teclado, para não pegar lixo //
gs >> sNome; // Neste momento o programa pausa, e espera o usuário digitar //
gs.goto_xy(10, 30); // Posicionando o cursor nas coordenadas 10, 30 //
gs << sNome // Mostrando o conteúdo da string sNome na tela //
return 0;
}
END_OF_MAIN() // Sempre colocar depois do main() //
=========================================================================================
ALPNG
Considerações:
ALPNG é uma biblioteca que estende as funcionalidades do Allegro, ela nos dá suporte a bitmaps da extensão.png.
Usaremos pouquíssimas funções desta biblioteca, nos beneficiares apenas do fato que, chamando sua função principal, depois podemos utilizar qualquer função Allegro, das já vistas da seção de BITMAPS, mas com o diferencial que agora elas passarão a aceitar arquivos .png.
Para instalar apenas execute o DevPak chamado “alpng-1.2-1mol.DevPak”
Include:
Linker:
Funções:
Esta função não é obrigatória, porém se ela for chamada, isso registrará a extensão png para o Allegro, então você poderá as rotinas já vistas para carregar as imagens desta extensão normalmente.
Exemplo de uso: alpng_init();
- BITMAP* load_png(const char *sCaminho, RGB* pal)
Você pode também usar este método para carregar as imagens .png.
Exemplo de uso: BITMAP* imgFoto = load_png(“pasta/Foto.pg”, NULL);
- int save_png(const char *sCaminho, BITMAP* bmp, const RGB* pal)
Está função salva um bitmap passado como segundo parâmetro no caminho passado como primeiro parâmetro, retorna um valor diferente de 0 se ocorrer algum erro.
Exemplo de uso: save_png(“Pasta/SS/ScreenShot1.png”, imgSS, NULL);
=========================================================================================
Prática 7.0
Usando a ALPNG:
// Adicionar ao linker : //
// --lalpng //
#include
#include
int main()
{
allegro_init();
install_keyboard();
set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
// Registrando a extensão png com o Allegro //
alpng_init();
// Como o png foi registrado, pode-se usar a funcao usual para carregar um png //
BITMAP *imgFoto1 = load_bitmap(“Pasta/Foto1.png”, NULL;)
// Ou intão, você usar a propria função da alpng //
BITMAP *imgFoto2 = load_png(“Pasta/Foto2.png”, NULL;)
// Desenhando //
draw_sprite(screen, bmpFoto1, 0, 0 );
draw_sprite(screen, bmpFoto2, 0, 400 );
// Liberando a memória //
destroy_bitmap(bmpFoto1);
destroy_bitmap(bmpFoto2);
return 0;
}
END_OF_MAIN() // Sempre colocar depois do main() //
=========================================================================================
Considerações Finais
Este material foi desenvolvido exclusivamente por mim, e pode ser redestribuído contanto que um email seja enviado para o autor (renanmaj@yahoo.com).
O documento ainda possui alguns erros de formatação pois foi tranferido de um documento Word para o fórum.
O documento pode possui alguns erros, e qualquer sujestão será bem vinda.
Espero que o material seja útil.
Renan Benites Guimarães Lopes.
|