Projeto de MAC211 -- 2010
Náufragos

Fabio Kon - Marcelo Reis

Nos capítulos anteriores....

Vamos iniciar agora a segunda parte deste emocionante resgate! [modo locutor da Sessão da Tarde off]

Segunda Fase: Visualização Gráfica

Agora que a geração dos passageiros está funcionando, vamos apresentá-los em uma janela gráfica, no gerenciador de janelas de sua preferência (Gnome, KDE, Xwindows, etc.); ou seja, você deverá adaptar o código que escreveu na fase anterior para que o mesmo utilize elementos gráficos ao invés de usar caracteres em modo texto, na representação do oceano, dos passageiros, dos recifes de corais, da R.M.S. Asimov e dos botes. Além disso, você deve fazer a sua simulação ser executada em tempo real: ou seja, os botes e os passageiros devem se movimentar na tela com o passar do tempo numa velocidade "razoável". Assim, 1 segundo simulado será bem próximo de 1 segundo do tempo real (aquele tempo que o seu relógio de pulso mostra). Você ainda não precisa se preocupar com o controle dos botes nem com a interação com o usuário: esses aspectos serão desenvolvidos na próxima fase.

Passageiros e os recifes de corais

Cada passageiro será representado por um quadrado ou círculo na tela; se quiser, você pode usar formas irregulares para dar mais realismo ao formato dos objetos, mas é desejável que seu formato sempre se aproxime de um quadrado ou de um círculo. Não use um formato muito esdrúxulo pois isso dificultará a detecção de colisões.

O número de pixels que representam cada passageiro na tela poderá ser constante, embora, se você preferir, poderá variar um pouco, para distinguir adultos de crianças, gordinhos de magrinhos, etc.

Agora o número de pixels os recifes de corais deve variar de acordo com a extensão do mesmo, mas deve sempre ser próximo ao valor D, que deve ser uma constante definida no programa (ou seja, corais de tamanho "médio" são representados com D pixels, corais "grandes" com mais de D pixels, e corais "pequenos", com menos de D pixels). Inicialmente o valor de D será 10, mas poderá ser alterado em função da resolução e da velocidade do programa final. Fica a seu critério escolher valores para as constantes de forma a favorecer a "jogabilidade" do seu jogo.

Importante: observe que não modelamos os recifes na primeira fase: para o tratamento das colisões, tanto dos botes quanto dos passageiros, considerem que os recifes são uma "parede", e que a colisão contra eles (ao menos nesta fase) é totalmente elástica. Cada grupo fique à vontade para especificar como os recifes são gerenciados pelas EDs / rotinas do jogo.

R.M.S. Asimov e os botes

A R.M.S. Asimov pode ser desenhada em algum ponto aleatório da tela, ou então em algum canto, caso você ache que colocá-la no meio da tela possa afetar a jogabilidade futura. O navio precisa ser grande o bastante para claramente o distinguir dos botes, porém não tão grande a ponto de comprometer o jogo. O navio, para todos os efeitos, não se move em relação à janela de jogo.

Os botes deverão ser representados por triângulos isósceles, uma de cada cor; o tamanho dos botes deve ser maior que o tamanho do maior dos passageiros, porém não muito maior ("licença poética" para não inviabilizar o jogo). Um dos lados do triângulo é a popa do bote, portanto a proa é o vértice oposto.

A implementação do controle dos botes ficará para a próxima fase; por hora, vamos apenas simular a movimentação dos barquinhos pelo oceano. A simulação será feita da seguinte forma:

Biblioteca Gráfica

Os desenhos e a animação serão feitos com base na biblioteca Allegro. Trata-se de uma biblioteca bastante abrangente, voltada para o desenvolvimento de jogos 2D em C/C++; a biblioteca não só conta com recursos gráficos, como também de som, gerenciamento de teclado, mouse e joysticks, etc. Veja abaixo a seção Allegro.

Lembretes




Biblioteca Allegro

Esta seção apresenta um pequeno resumo das funções da Allegro. Para mais detalhes, veja a página oficial da biblioteca, no SourceForge, especialmente os tutoriais que ensinam como utilizar as funções gráficas.

Seguem abaixo algumas instruções para se dar o pontapé inicial na utilização desta biblioteca.

Inicialização e finalização.

Para inicializar a biblioteca, use a função:

Para definir o número de cores, use a função: Para inicializar o modo gráfico, use a função:

Para encerrar e liberar os recursos alocados, use:

Bitmaps

A Allegro trabalha com objetos do tipo BITMAP. Bitmaps são matrizes de pixels, onde cada pixel representa uma cor. A tela é um tipo especial de BITMAP, chamado screen. Para alocar um objeto do tipo BITMAP:

Para desalocar um objeto do tipo BITMAP:

Desenhando

Dado um objeto do tipo BITMAP, você pode criar figuras nele; seguem abaixo algumas das várias funções de desenho:

A biblioteca Allegro oferece muitas outras funções além das aqui descritas, incluindo mais funções de desenho, manipulação de paleta de cores, de fontes, etc. Existem diversos tutoriais (inclusive em português) e exemplos pela Internet que as explicam em detalhes.

Download da biblioteca

A Allegro pode ser baixada na página oficial da biblioteca ou, dependendo da distro, através de algum gerenciador de pacotes (e.g. em Debian ou Ubuntu, utilizando o apt). Utilizem a última versão estável disponível (4.4.X), pois ela conta com suporte nativo a arquivos PNG.


Tempo Real

Para controle do tempo real você poderá utilizar a seguinte função POSIX:

#include <time.h> 
int nanosleep(const struct timespec *requested, struct timespec *remaining);
Dê uma olhada na página de manual do nanosleep para ver como ele funciona.

Nesta fase do projeto, você pode iniciar o desenvolvimento gerando uma "foto" ou quadro por segundo, chamando a função nanosleep para dormir 1 bilhão de nanosegundos entre um quadro e outro. Depois que o seu programa estiver funcionando bem, você deve reconfigurá-lo para gerar 10 quadros por segundo para dar impressão de movimento (dormindo 100 milhões nanosegundos entre um quadro e outro). Lembre-se que 10 quadros por segundo é o número mínimo de vezes necessário que você deve redesenhar os botes (os passageiros, que se movem mais lentamente, podem ser atualizados pelo menos 1 vez por segundo). Se o programa estiver funcionando muito bem, você pode ainda tentar 30 quadros por segundo, que é uma taxa comumente utilizada em vídeos e jogos.

Otimização do Joguinho:

Melhorar a simulação do tempo real medindo o tempo gasto no processamento de cada quadro e descontar esse tempo no tempo em que o programa dorme (com o nanosleep). Essa melhoria é importante quando se tem muitos quadros por segundo e muita coisa acontecendo (por exemplo, muitos passageiros na tela, os botes se mexendo, música tocando etc.). Se você não implementar essa melhoria (que é obrigatória neste EP), há o perigo do seu jogo ficar muito lento caso tenha muita coisa acontecendo ou outros programas sendo executados na mesma máquina.

Para medir o tempo gasto no processamento de cada quadro, você pode usar, por exemplo:

   #include <sys/time.h>
   int gettimeofday(struct timeval *tv, struct timezone *tz);
Dê uma olhada na página de manual para aprender como ela funciona. Cuidado, pois ela devolve o tempo em microsegundos (10^-6 seg) e não em nanosegundos (10^-9 seg).


Data de entrega

A segunda fase deverá ser entregue até o dia 9 de junho (quarta-feira). Dúvidas podem ser discutidas no fórum da disciplina no Moodle, para o aproveitamento de todos.



Página de MAC211
Página do Fabio
Página do DCC