Nota

Estas notas são da autoria do Prof. João Cardoso (jcard@fe.up.pt).

Utilização de "Sprites"

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.

Animação

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.

Colisão entre Sprites

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:

  1. Calcular a nova posição do sprite
  2. Se os limites do ecrã forem ultrapassados, mudar a componente apropriada da velocidade do sprite e terminar
  3. Na posição actual do sprite, apagar no ecrã os pixéis não negros do pixmap
  4. Verificar se no ecrã, na nova posição do sprite, existe algum pixel não negro correspondendo a um pixel não negro do pixmap
    1. Se existir, reescrever na posição antiga do ecrã os pixéis não negros do pixmap, perturbar a velocidade do sprite e terminar
    2. Se não existir, escrever os pixéis não negros do pixmap na nova posição do sprite

Double-buffering

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.

Interfaces