Ir para o conteúdo

Allegro - Programação de jogos em C

Allegro é uma biblioteca para programação de jogos que foi inicialmente criada por Shawn Hargreaves com o objectivo de facilitar a iniciação à programação de jogos. A sua intenção era de fazer uma biblioteca de código simples para que o iniciante na área de programação de jogos não precisasse ler uma grande quantidade de livros sobre DirectX, OpenGL ou outras APIs, e conseguir cumprir o seu objectivo, o Allegro é isso mesmo, uma biblioteca de utilização simples, com uma pequena curva de aprendizado e que nos possibilita de fazer coisas muito interessantes com ela. Para além disso é freeware e multiplataforma.

A quem se destina?

A todas as pessoas que se interessam pela criação/desenvolvimento de jogos mas que ainda não tenham um elevado grau de conhecimentos nesta área. Para conseguir trabalhar com esta API necessita de ter conhecimentos de C ou C++.

Instalando o Allegro

Usando o Dev-C++

O Dev-C++ tem um pequeno plug-in que facilita o trabalho de instalação do Allegro. Basta ir ao menu Ferramentas >> Actualizações >> Seleccione o Mirror >> Check for Updates >> Allegro.

Com o DEV C++ e o Allegro instalado, vamos colocar a mão na massa.

Primeiros Passos

Para começar é necessário criar um projecto Allegro static. No Dev-C++ vá a Ficheiro >> Novo >> Multimedia >> Allegro Static.

Hello World

Nada melhor que começar com um pedaço de código para introduzir.

#include <stdio.h>
#include <allegro.h>
#define MAX 800
#define MAY 600

int main()
{
    allegro_init();
    install_keyboard();
    set_color_depth(32);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, MAX,MAY,0,0);
    allegro_message("Ola");
    allegro_message("Meu primeiro programa em Allegro");
    while(!key[KEY_ESC])
        {      
        textout_ex(screen,font,"Outra forma de Escrever",0,0,makecol(0,255,0),-1);
        }
        return 0;
}
END_OF_MAIN();

Uma explicação de cada linha:

#include <allegro.h>

Primeiro temos de incluir a biblioteca na nossa aplicação.

allegro_init();

Inicializa as funções da biblioteca.

install_keyboard();

Inicializa o teclado.

set_color_depth(n_bits);

Define a número de bit de cores a ser usado e cria o ponteiro global de bitmap screen que representa a memória de vídeo do hardware. Esta função deve ser chamada antes da função set_gfx_mode.

Número de Bits Número de Cores
8 256
15 32 768
16 65 536
24 16 777 216
32 4 294 967 296

set_gfx_mode(GFX_AUTODETECT_WINDOWED, MAX,MAY,0,0);

Inicializa o modo gráfico. Tem como primeiro parâmetro a escolha do modo gráfico, neste exemplo forçamos o modo janela. O segundo e terceiro parâmetros servem para indicarmos a resolução, neste caso 800x600. O quarto e quinto parâmetro é para a resolução virtual que neste momento não utilizaremos.

Modo do set_gfx_mode Descrição
GFX_SAFE Faz com que o modo gráfico sempre seja inicializado correctamente.
GFX_TEXT Retorna para o modo Texto.
GFX_AUTODETECT Tenta definir a resolução para o especificado "maximizado". Caso falhe, tentará defini-la em janela.
GFX_AUTODETECT_WINDOWED Mesmo modo acima só que força a resolução para o tipo janela.
GFX_AUTODETECT_FULLSCREEN Força resolução para o modo maximizado.

allegro_message(string);

Mostra uma caixa de texto com o texto que for introduzido. No nosso exemplo a palavra “Ola” e a frase “Meu primeiro programa em Allegro”.

while(!key[KEY_ESC])

Enquanto o não for primida a tecla Esc o ciclo não pára.

textout_ex(screen,font,"Outra forma de Escrever",0,0,makecol(0,255,0),-1);

Escreve uma string num bitmap. O parâmetro (font) define o tipo de letra a ser utilizado. O quarto e quinto parâmetro são para defenir a posição no ecrã. O sexto parâmetro serve para indicar a cor do texto, para isso é utilizada a função makecol.

makecol(0,255,0)

Função para definir cor. Recebe como parâmetro o padrão RGB (Red, Green, Blue) ou seja, as 3 cores primarias.

O utlimo parâmetro é para indicar onde será colocado o texto, neste caso é no fundo de ecrã (-1).

END_OF_MAIN();

Finaliza a execução do programa. Após ter finalizado a função main, precisa desse comando para que o compilador link correctamente a biblioteca.

Imprimir imagens no ecrã

Neste exemplo vamos mostrar uma imagem no ecrã.

#include <stdio.h>
#include <allegro.h>
#define MAX 800
#define MAY 600

int main()
{
    allegro_init();
    install_keyboard();
    set_color_depth(32);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, MAX,MAY,0,0);
    BITMAP *PAP;
    PAP=load_bitmap("C:PAP.bmp", NULL);/*logo do P@P em bitmap*/
    draw_sprite(screen,PAP,0,0);
        while(!key[KEY_ESC])
        {
              textout_ex(screen,font,"Portugal a Programar",  0,80,makecol(0,255,0),-1);
              textout_ex(screen,font,"www.portugal-a-programar.org",  0,90,makecol(255,255,0),-1);
              textout_ex(screen,font,"A comunidade portuguesa de programadores",  0,100,makecol(255,0,0),-1);
        }
        return 0;
}
END_OF_MAIN();

Uma explicação dos novos elementos:

BITMAP *PAP;

Cria um ponteiro do tipo bitmap.

PAP=load_bitmap("C:PAP.bmp", NULL);

Carrega o bitmap do ficheiro com o parâmetro NULL para a Paleta que será explicada mais abaixo.

draw_sprite(screen, PAP, 0, 0);

Função para imprimir imagem. Copia a imagem contida em PAP para o ponteiro screen, imprimindo na posição 0,0.

O nosso exemplo depois de compilado fica assim:

Desenhar figuras

Vamos agora ver como desenhar rectas, rectângulos e círculos. O Allegro utiliza o plano cartesiano para desenhar gráficos. Mas, com algumas diferenças do plano cartesiano que conhecemos. No que estamos habituados as coordenadas (0,0) encontram-se na parte inferior esquerda, enquanto no Allegro encontram-se na parte superior esquerda. Entenderemos melhor após fazermos o exemplo.

Rectas

Desenhar rectas.

#include <allegro.h>

int main ()
{
    allegro_init();
    install_keyboard();
    set_color_depth(32);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800,600,0,0);
    while(!key[KEY_ESC])
    {
       line(screen, 0,0, 800,600, makecol(0,255,0 ));
       line(screen, 0,600, 800,0, makecol(0,255,0 ));
    }
    return 0;
}
END_OF_MAIN();

line(bitmap,X1,Y1,X2,Y2,makecol(R,G,B));

A função line() desenha uma linha no bitmap desde (X1,Y1) até (X2,Y2), com a cor indicada no último parâmetro.

Visualiação do exemplo:

Rectângulos

Após termos visto como se desenha uma recta, próximo passo é vermos como se desenha um rectângulo.

#include <allegro.h>

int main ()
{
    allegro_init();
    install_keyboard();
    set_color_depth(32);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800,600,0,0);
    while(!key[KEY_ESC])
    {
       rect(screen, 50,100, 400,200, makecol(0,255,0 ));
       rectfill(screen, 51,101, 399,199, makecol(255,0,0 ));
       rectfill(screen, 200,300, 400,500, makecol(0,0,255));
    }
    return 0;
}
END_OF_MAIN();

rect(screen, 50, 100, 400, 200, makecol(0, 255, 0));

Aqui desenhamos um rectângulo nas coordenadas X1,Y1(50,100) até X2,Y2(400,200) com a cor Verde.

rectfill(screen, 51, 101, 399, 199, makecol(255, 0, 0));

Visto que a função rect não preenche o rectângulo temos de usar a função rectfill para o preencher, criando um rectângulo que caiba dentro do outro.

rectfill(screen, 200, 300, 400, 500, makecol(0, 0, 255));

Com esta função podemos criar um rectângulo solido qualquer. Neste caso da posição X1,Y1(200,300) até X2,Y2(400,500) e com a cor Azul.

Visualização do exemplo:

Círculos

Agora aprenderemos como desenhar um círculo no ecrã. Assim como o rectângulo, o Allegro não desenha um círculo sólido, então, da mesma forma que fizemos com o rectângulo, utilizaremos outra função para o preencher.

#include <allegro.h>

int main ()
{
    allegro_init();
    install_keyboard();
    set_color_depth(32);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800,600,0,0);
    while(!key[KEY_ESC])
    {
       circle(screen, 400,300, 100, makecol(255,0,0));
       circlefill(screen, 400,300,98, makecol(255,255,255));
    }
    return 0;
}
END_OF_MAIN();

circle(screen, 400,300, 100, makecol(255,0,0));

Desenha uma circunferência com centro em X,Y(400,300) de Raio 100 e cor vermelha.

circlefill(screen, 400,300,98, makecol(255,255,255));

Cria um círculo, preenchendo a circunferência desenhada anteriormente, em branco.

Visualização do exemplo:

Usando som

Além de uma boa jogabilidade, óptimo enredo e gráficos estonteantes, falta um requisito para considerarmos um jogo perfeito. O Som. Um jogo perfeito reúne todas essas qualidades aliada a uma óptima banda sonora que envolve o jogador enquanto joga. Para musica de fundo o Allegro utiliza o formato MIDI, para outros efeitos sonoros, o formato mais usado é o do tipo WAV.

Usando MIDI

Um exempo usando um ficheiro MIDI.

#include <allegro.h>

int main ()
{
    allegro_init();
    install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT,NULL);
    install_keyboard();
    set_color_depth(32);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800,600,0,0);
    MIDI *Pantera;
    Pantera=load_midi("C:pantera.midi");
    play_midi(Pantera,TRUE);
    while(!key[KEY_ESC])
    {
       textout_ex(screen, font, "Ouvindo uma musica de fundo",0,0, makecol(0,255,0), -1);
    }
    stop_midi(); 
    return 0;
}
END_OF_MAIN();

install_sound(digi_card,midi_card,cfg_path);

Inicializa o modulo de som. Geralmente será passado como parametro DIGI_AUTODETECT e MIDI_AUTODETECT para assim deixar o Allegro escolher o driver de SOM e o driver de MIDI automaticamente. E passa NULL como parametro do cfg_path para assim manter a compatibilidade com versões antigas do Allegro.

Modos do digi_card Descrição
DIGI_AUTODETECT Instrui o Allegro a escolher o driver de som.
DIGI_NONE Sem som digital.
DIGI_SB Auto-detecta placas do tipo Sound Blaster.
DIGI_SB10 Sound Blaster 1.0 (8 bit mono).
DIGI_SB15 Sound Blaster 1.5 (8 bit mono).
DIGI_SB20 Sound Blaster 2.0 (8 bit mono).
DIGI_SBPRO Sound Blaster Pro (8 bit stereo).
DIGI_SB16 Sound Blaster 16 (16 bit stereo).
DIGI_AUDIODRIVE ESS AudioDrive.
DIGI_SOUNDSCAPE Ensoniq Soundscape.
Modos do midi_card Descrição
MIDI_AUTODETECT Instrui o Allegro a escolher o driver de MIDI.
MIDI_NONE Sem som MIDI.
MIDI_ADLIB Auto-detecta sintetizadores do tipo Adlib ou Sound Blaster FM.
MIDI_OPL2 Sintetizador OPL2 (mono, usado em Adlib e Sound Blaster).
MIDI_2XOPL2 Sintetizador OPL2 dual (stereo, usado em Sound Blaster Pro-I).
MIDI_OPL3 Sintetizador OPL3 (stereo, usado em Sound Blaster Pro-II e acima).
MIDI_SB_OUT Interface MIDI Sound Blaster.
MIDI_MPU Interface MIDI MPU-401.
MIDI_DIGMID Sample-based software wavetable player.
MIDI_AWE32 AWE32 (EMU8000 chip).

MIDI Pantera;

Criação do ponteiro do tipo MIDI Pantera.

Pantera=load_midi("C:pantera.midi");

Leitura do arquivo MIDI pantera do HD.

play_midi(Pantera,1);

Toca o ficheiro MIDI Pantera, com repetição até que o programa termine. Caso o parametro fosse 0, tocaria apenas uma vez.

stop_midi();

Para de tocar a MIDI.

Usando WAVE

Outro exemplo, mas desta vez usando SAMPLES em WAVE.

#include <allegro.h>

int main ()
{
    allegro_init();
    install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT,NULL);
    install_keyboard();
    set_color_depth(32);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800,600,0,0);
    MIDI *Pantera;
    SAMPLE *Tada;
    Pantera=load_midi("C:pantera.midi");
    Tada=load_wav("C:WINDOWSMediaringin.wav");
    play_midi(Pantera,1);
    play_sample(Tada,255,90,1000,1);
    while(!key[KEY_ESC])
    {
       textout_ex(screen, font, "Ouvindo uma musica de fundo",0,0, makecol(0,255,0), -1);
       textout_ex(screen, font, "E o efeito TADA",0,10, makecol(255,255,0), -1);
    }
    stop_midi();
    stop_sample(Tada);
    return 0;
}
END_OF_MAIN();

SAMPLE *Tada;

Cria o ponteiro para Sample Tada.

Tada=load_wav("C:WINDOWSMediaringin.wav");

Abertura do ficheiro .wav.

play_sample(SAMPLE, volume, balanço, frequencia, loop);

Toca o sample. O volume e o balanço variam de 0 até 255, a frequencia representa a frequencia com que o arquivo foi gravado e loop se terá ou não repetição. No exemplo utilizamos os seguintes valores: volume 255, balanço 90 e frequencia 1000, com repetição.