Animação e a tecnica de double buffer em Allegro
A animação é recurso bastante interessante de ser usado em jogos e aplicações multimídias, por trazer “vida” ao que é mostrado na tela.
Neste post será mostrado como pode-se implementar uma animação simples usando Allegro e como faze-la usando Double-Buffer (buffer duplo).
Podemos definir animação como uma seqüência de imagens diferentes, que mostradas uma após a outra nos dá a impressão de “movimento”.
Em Allegro, poderíamos fazer uma animação carregando uma serie de BITMAP’s e depois mostrando-os na tela também em seqüência.
Neste post, iremos fazer um BITMAP se movimentando apenas. Então não será necessário carregarmos várias imagens diferentes, pois podemos apenas trocar suas posições (x,y).
Primeira coisa que devemos fazer é carregar uma imagem em um ponteiro BITMAP.
BITMAP *imagem;
BITMAP *buffer = create_bitmap(640,480);
Agora iremos declarar uma variável inteira para armazenar a posição x da imagem:
int x = 0;
Para fazermos a animação iremos usar um loop para mostrá-la continuamente até que seja apertado a tecla ESC. Dentro deste loop, iremos limpar a tela, escrever a imagem na tela e mudar a posição x.
while (!key[KEY_ESC]) {
clear(buffer);
draw_sprite(buffer, imagem, x++,20);
draw_sprite(screen, buffer, 0, 0);
}
Se executarmos nosso programa, já veremos uma animação de nossa imagem se movimentando para a direita.
Podemos melhora-la um pouco, fazendo com que ao chegar em um certo ponto da tela, ela volte a posição 0, facilmente solucionado com um if.
while (!key[KEY_ESC]) {
clear(buffer);
draw_sprite(buffer, imagem, x++,20);
draw_sprite(screen, buffer, 0, 0);
if (x==500){
x = 0;
}
}
Assim já temos nossa animação funcionando!
Mas creio que todos perceberam que ela ficou “piscando” na tela. Por que isso acontece? Simples! Estamos sempre limpando a tela (clear(screen)) assim ela fica um pequeno intervalo de tempo sem nada para mostrar por estar vazia.
Podemos solucionar usando Double-Buffer!
Double-Buffer é uma técnica que onde possuímos um buffer auxiliar, onde escrevemos tudo nele. E depois sobre-escrevemos a tela com esse buffer auxiliar. Assim não precisaremos limpar a tela e sim o buffer auxiliar.
int x = 0;
BITMAP *imagem;
BITMAP *buffer = create_bitmap(640,480);
imagem = load_bitmap("imagem.bmp", NULL);
while (!key[KEY_ESC]) {
clear(buffer);
draw_sprite(buffer, imagem, x++,20);
draw_sprite(screen, buffer, 0, 0);
if (x==500){
x = 0;
}
}
Onde temos o ponteiro buffer como sendo nossa tela auxiliar. Observe que escrevemos a imagem no buffer e depois o buffer na tela.
Com isso conseguimos solucionar o problema da tela piscar.
Espero que tenham gostado, qualquer dúvida comentem. Até a próxima. Abraços…

Luiz Eduardo Cavalcanti said,
Setembro 29, 2006 @ 10:09
Adorei a técnica!
Danillo Martins said,
Outubro 14, 2006 @ 17:18
Cara muito obrigado por ter editado esse topico sobre double buffer me ajudou muito…
vlw mesmo foi o mais bem explicado q ei encontrei
PARABENS
Fabio said,
Agosto 2, 2007 @ 21:42
Oi Eu gostaria de saber como faz para carregar duas imagens ao mesmo tempo no caso do exemplo Buffer? Ficarei muito grato!
Tulio Faria said,
Agosto 3, 2007 @ 16:57
Olá Fábio,
em uma das implementações que fiz usando mais de uma imagem, eu criei uma lista encadeada de imagens e suas devidas posições na tela que deveriam ser renderizadas na tela, assim de tempos em tempo eu atualizava a tela (com double buffer) lendo a estrutura…
Abraços,
Fabio said,
Agosto 10, 2007 @ 20:23
Obrigado pela resposta!
Ja nao sei mais a quem recorrer sobre uma outra duvida ligada a isso, se puder me ajudar prometo ser um bom menino
Bom to com um problema ja faz 3 dias e nao sei mais o que fazer, como é que faço para declarar um BITMAP dentro de uma funçao?
Fabio said,
Agosto 10, 2007 @ 20:25
Exemplo resumido para que entenda a logica basica da minha situação:
____
int personagem_y;
int main() {
init();
BITMAP *personagem;
personagem = load_bitmap(”personagem.bmp”, NULL);
BITMAP *buffer = create_bitmap(640,480);
Fabio said,
Agosto 10, 2007 @ 20:25
while (!key[KEY_ESC]) {
personagem_y = personagem_y+1;
clear(buffer);
carinha_posicao(1,personagem_y); // chamo a função do persongem
draw_sprite(screen,buffer,0,0);
}
Fabio said,
Agosto 10, 2007 @ 20:25
deinit();
return 0;
}
END_OF_MAIN()
void personagem(int personagem_x,int personagem_y)
{
BITMAP *personagem;
carinha = load_bitmap(”carinha.bmp”, NULL);
draw_sprite(buffer,personagem,personagem_x,personagem_y);
///aqui acima em buffer d erro de declaracao
}
Fabio said,
Agosto 10, 2007 @ 20:26
O programa da erro dizendo que buffer dentro da função tem que ser declarado, e como é que declaro buffer dentro da função sem dar conflito com o buffer la no inicio do codigo? Ja to me descabelando por causa deste erro! Se puder matar essa pra mim acho que vou chorar de alegria e dormir em paz a noite! rsrs
Fabio said,
Agosto 10, 2007 @ 20:28
só um detalhe a linha:
carinha = load_bitmap(”carinha.bmp”, NULL);
na verdade é:
personagem = load_bitmap(”carinha.bmp”, NULL);
Tenho quase certeza que essa duvida muitas pessoas devem ter, aguardo e obrigado!!!!
Fabio said,
Agosto 10, 2007 @ 20:33
Desculpe só mais um detalhe estou chamando a função:
carinha_posicao(1,personagem_y);
entao minha funçao começa com:
void personagem(int personagem_x,int personagem_y)
o correto é:
void carinha_posicao(int personagem_x,int personagem_y)
Desculpe a bagunça!
Tulio Faria said,
Agosto 13, 2007 @ 13:43
Olá Fábio,
atenção para o escopo das variáveis…
Apesar do main em C ser considerado a função principal, sendo a que o compilador irá chamar primeiro, tudo que for declarado dentro da mesma será considerado local para o main, ou seja, não será válido fora do mesmo.
Passe o BITMAP *buffer para fora do main, assim ela ficará global e acessível a toda aplicação…
Abraços,
Fabio said,
Agosto 13, 2007 @ 19:47
Caramba só isso? Ta resolvido aqui!! Obrigdaço!!
Fabio said,
Agosto 13, 2007 @ 21:28
Tulio olha o chato aqui dinovo… to me dedicando bastente no alegro para jogos, queria poder lhe mostrar meu estudo de um mes em c++ mas to querendo compilar um joguinho com som e tudo mais enfiim….
Bom eu gostaria muito que vc falasse um pouco mais sobre som Midi!
Eu consigo tocar som fundo musical no meu projetinho de jogo tipo mario, mas ao incluir um som para o personagem pular, a musica de fundo para no momento do som do pulo, e quando o som do pulo termina a musica de fundo nao continua… alguma sugestao? Tentarei deixar vc em paz… será que poderia me auxiliar mais nessa?
Obrigado desde já!!!
Vilma Ferreira said,
Setembro 16, 2007 @ 20:56
Legal esta materia, tenho q fazer um projeto de um joguinho, valendo minha prova do 4. bimestre, mas está dificil, pois agora q estou aprendendo os primeiros passos para programaçao em C. Esta materia, me ajudaria muito mas como ainda nao entendo direito do assunto, nao consegui assimilar, como fazer as imagens se movimentarem… o projeto q estou tentando montar, ou seja meu joguinho, eu quero som e movimentos… Será q vc pode me dar mais algumas dicas…
e mais, apos muitas tentativas, so consegui instalar a biblioteca allegro em meu PC apartir desta materia, achei interessante quando vc mencionou na materia ” (o link para quem está com preguiça de ir lá procurar)” me desculpe mas eu não estava conseguindo mesmo, so entao com sua ajuda é q consegui. Valeu mesmo. muito Obrigada!!!…
Tulio Faria said,
Setembro 17, 2007 @ 01:32
Fabio,
existem algumas “restrições” quanto ao uso de sons… Eu não lembro o motivo, mas lembro que poderia ocasionar estes problemas…
Vilma,
que bom que meus tutoriais ajudaram…
Denada e seja bem vinda sempre…
Abraços a todos,
Carlos said,
Outubro 28, 2007 @ 20:53
Essa explicação é muito boa me ajudou muito.
VALEU!!
Gustavo said,
Junho 6, 2008 @ 15:34
Tulio,
nesse 1° semestre na minha faculdade tive a materia “algoritmos e programação”
meu trabalho final eh desenvolver um jogo de cartas e já o fiz sem problemas
agora estou começando a olhar allegro para tentar colocar no meu jogu (alias seus turoriais/explicações relacionadas a ele plo jeitu me ajudaram mtu)
uma duvida q tenho é se é possivel eu colocar a imagem de uma carta associada a cada variavel-carta do meu jogu e tb se eh possivel apos cada rodada, na tela apagar o que ocorreu na 1° rodada e exibir então a 2° (pq do jeitu normal vai aparecendu os escritos fik um embaxo do outro e o programa vai embora, qria na vdd q ficasse como se fosse um painel sabe pra fikar um visual melhor)
Obs: em relação a imagem da carta, se plo menus conseguir aparecer uma especie de carta em branco e no meiu os escritus jah ajudaria mtu
Obs.2: e do painel, de apagar a rodada apos ela ocorrer, se for mtu complexo faze-lo talvez nem compense vc se extender na explicação, afinal ainda sou iniciante.
De qq modo, obrigado desde já, gostei mtu de programar em C e qria me aprofundar. E parabens plo o que vc faz aki, ajuda mtuu msm qm tah precisando!!
Abraçoss
Gustavo said,
Junho 11, 2008 @ 00:21
Tulio,
consegui contornar qse tds os meus problemas com o Allegro ai…
+ ainda não consegui fazer o scanf() no allegro
essa função não existe no allegro não eh?!
alem da readkey(), que obtem o caracter, tem outro comando para q eu possa obter um numero
ex: meu jogo é de cartas e preciso em algumas partes obter certos numeros digitados pelo usuario, como faço pra conseguir pegar o valor ‘2′, qdo o usuario digitar 2??
Ajudaaa por favorr… tô cansado de procurar e não achar resultados
Vlww… abraçuu
Tulio Faria said,
Junho 11, 2008 @ 09:38
Gustavo,
quando eu fiz o meu jogo como trabalho na faculdade (faz um tempo já :)) eu usei tudo com readkey, acabei quase que implementando um “input”/”scanf” , mas no meu caso era um pouco pior porque eu tinha que mostrar na tela o que estava sendo digitado…
Mas o readkey vai te ajudar
Forte abraço
Gustavo said,
Junho 13, 2008 @ 23:18
Tulio,
estudei mais e pesquisei também, e consegui fazer o que queria; no final das contas acabei fazendo uma função para transformar o caracter digitado em numeros efetivos, mas ela fica limitada a quantos numeros eu fazer a transformação e também até o numero 9 porque o readkey lê apenas um caracter. Ah, também tive que imprimir na tela o n° digitado, mas depois de transformar o caracter em n° ficou facil.
Viu, queria saber um pouco mais do allegro, principalmente em relação a strings, se eu posso lê-las e usá-las no allegro. Se possível post um tutorial sobre isso, strings no allegro.
Obrigadoo… abraçoss!!
Gustavo said,
Junho 17, 2008 @ 00:57
ps: Tulio, é possivel gerar um executavel do programa em C sem se fazer necessario o compilador?? Por exemplo, após ter o programa pronto, é possível de algum modo uma outra pessoa pegar o programa(ou o código, ou o aplicativo) e poder rodá-lo sem ter um compilador e biblioteca instaladas??
Marcos Maximo said,
Agosto 4, 2008 @ 22:34
Poxa, muito obrigado mesmo, havia feito um programa e esse problema deixava a sensação de rolagem de um texto terrível. Agora está bem mais suave.