Estas notas são da autoria do Prof. João Cardoso (jcard@fe.up.pt).
Um sprite é uma figura geométrica que pode ser criada, animada e destruída no ecrã de um computador. Um sprite é constituído por uma secção rectangular de pixéis de diferentes cores, assim como de uma cor de fundo “transparente”, o background.
Um sprite pode ser criado a partir de uma definição textual, correspondendo um carácter a um pixel, e estando cada tipo de carácter associado a uma determinada cor. No código que se segue define-se um sprite de nome pic1
, com 32 pixéis de resolução horizontal, 13 pixéis de resolução vertical e que contém quatro cores. O carácter '.'
representa pixéis transparentes de cor 0, preto, o símbolo 'x'
pixéis de cor 2, verdes, etc. Para mais detalhes ver o ficheiro pixmap.h
fornecido (e função em read_xpm.c
).
static char *pic1[] = { "32 13 4", /* número de pixels horizontais, verticais, e cores */ ". 0", /* símbolo ’.’ representa pixel de cor 0 */ "x 2", /* símbolo ’x’ representa pixel de cor 2 */ "o 14", "+ 4", "................................", /* pixels ... */ "..............xxx...............", "............xxxxxxx.............", ".........xxxxxx+xxxxxx..........", "......xxxxxxx+++++xxxxxxx.......", "....xxxxxxx+++++++++xxxxxxx.....", "....xxxxxxx+++++++++xxxxxxx.....", "......xxxxxxx+++++xxxxxxx.......", ".........xxxxxx+xxxxxx..........", "..........ooxxxxxxxoo...........", ".......ooo...........ooo........", ".....ooo...............ooo......", "...ooo...................ooo...." };
A função fornecida char *read_xpm(char *map[], int *width, int *height)
lê e processa uma descrição textual de um sprite a partir de uma estrutura residente em memória, obtida em tempo de compilação (essa informação podia também ser lida em tempo de execução a partir de um ficheiro), e devolve um apontador para uma zona de memória com a definição dos seus pixéis, um pixmap.
O pixmap que descreve o mapa de bits de um sprite pode ser copiado para uma área da memória gráfica, fazendo aparecer a figura no ecrã. Apagando o pixmap do ecrã e copiando-o para uma zona próxima, rapidamente e em sucessão, provoca a ilusão de que a figura se move.
Durante o processo de animação do sprite deve tratar-se a cor de fundo, o preto, como uma cor "transparente", isto é, os pixéis da memória gráfica correspondentes aos de cor negra do pixmap não devem ser copiados nem apagados no processo de animação, permitindo a existência de objectos gráficos parcialmente sobrepostos.
Cada sprite pode ter ainda associados vários pixmaps, em que cada um deles contém pequenas variações em relação ao anterior, e sendo usado de modo repetitivo um pixmap diferente em cada quadro da animação. Um sprite deste tipo representará portanto uma figura animada em si mesma.
Durante o processo de animação é necessário verificar se irá ocorrer colisão com outros objectos gráficos antes de efectuar a cópia do pixmap para a sua nova posição na memória gráfica. Se houver colisão a cópia não deverá ser efectuada, pois dará lugar à corrupção dos objectos gráficos já existentes.
Um processo simples de verificar se irá haver colisão é verificar se existe, na memória gráfica e no local de destino do sprite, algum pixel não negro correspondendo a um não negro do pixmap – se existir, isso quer dizer que nesse local da memória gráfica há já outro objecto que seria corrompido pela cópia.
Um algoritmo simples para fazer a animação, levando em conta os limites do ecrã e a colisão com outros objectos, poderá ser o seguinte:
No processo de construção da imagem no ecrã de um computador, o hardware lê os bytes da memória gráfica e envia para o ecrã os pixéis correspondentes da esquerda para a direita e de cima para baixo, no que se designa um frame ou quadro. Este processo é efectuado no mínimo 50 vezes por segundo, a frequência de refrescamento do ecrã. Assim, num dado instante, a parte do ecrã que está “abaixo” do pixel que acabou de ser escrito no ecrã representa o quadro anterior, isto é, a imagem que foi escrita na memória gráfica há 20ms. Se um sprite está a ser animado e este processo de refrescamento ocorrer a meio da animação, ocorrerá o chamado “efeito de neve” (snow effect) independentemente da velocidade com que a animação é efectuada.
Para minimizar este problema, deve utilizar-se a técnica de double-buffering, em que todo o processo de escrita na memória da placa gráfica é substituída pela escrita em memória normal, sendo esta copiada de uma só vez e regularmente para a memória da placa gráfica. Para eliminar completamente a possibilidade do efeito snow, deve efectuar-se a operação de cópia durante a fase de actualização vertical do ecrã, isto é, no intervalo de tempo que existe entre o envio do último pixel de um quadro e o envio do primeiro pixel do ecrã seguinte.
Como efeito secundário da técnica de double-buffering, e desde que se usem vários planos de memória e se efectue a sua cópia para o ecrã numa certa ordem e respeitando a cor “transparente”, é possível criar efeitos interessantes, desde a existência de um pano de fundo, à ilusão da existência de objectos tridimensionais.