quinta-feira, 17 de dezembro de 2009
quarta-feira, 16 de dezembro de 2009
terça-feira, 15 de dezembro de 2009
quarta-feira, 2 de dezembro de 2009
Como fazer um jogo com Html.
1. Visão Geral do Jogo
O objetivo do jogo que iremos montar é fazer desaparecer todos os monstros que andam pela tela; para isso, basta clicá-los com o ponteiro do mouse.
Como os monstros têm velocidades diferentes, a pontuação deve variar de acordo com a velocidade (quanto maior, mais pontos). Ao errar o clique (não clicar em nenhum monstro), o jogador perde pontos. Ao final da partida, depois que todos os monstros desaparecerem, é descontado do total de pontos um valor proporcional ao tempo transcorrido desde o início da partida.
2. Definições e Outras Funções
O cenário do jogo consistirá de duas partes: a parte esquerda da tela é onde os monstros se movimentam, e a parte direita é onde está o placar, o contador de monstros e o tempo transcorrido. Definiremos que, do total de 800x600 da tela, 600x600 sejam da parte esquerda, e o resto, naturalmente, da direita. Para isso, escrevemos
- #define ESP_PONTOS 200
#define ARENA_X (MAX_X) - (ESP_PONTOS)
#define ARENA_Y (MAX_Y)
Devemos definir, também, o número de monstros que aparecerão inicialmente, bem como os tamanhos horizontal e vertical de seu bitmap e os máximos deslocamentos horizontal e veritcal possíveis. Para tanto, fazemos
- #define MAX_MONSTRO 30
#define MONSTRO_X 32
#define MONSTRO_Y 32
#define MAX_DX 5
#define MAX_DY 5
Utilizaremos um sprite denominado MONSTRO, definido da seguinte maneira:
- typedef struct _MONSTRO
{
- int x, y;
int dx, dy;
int show;
Além dos #define's, precisamos escrever a função que será chamada pelo temporizador para incrementar o tempo. Note que, devido ao uso que se faz desta função (temporizador), é necessário o uso da macro que se encontra no final daquela.
- void aumenta_tempo (void)
{
- tempo++;
END_OF_FUNCTION(aumenta_tempo);
Precisamos, ainda, incluir algum código na função inicia do esqueleto do programa, para que seja inicializado o arquivo de recordes
- set_config_file("jogo.rec");
- LOCK_VARIABLE(tempo);
LOCK_FUNCTION(aumenta_tempo);
3. As Inicializações
Devemos, primeiramente, declarar as variáveis que vamos utilizar no jogo. Para tal, dentro da função principal, escrevemos
- MONSTRO monstro[MAX_MONSTRO];
BITMAP *bmp_monstro;
BITMAP *tela;
PALETTE pal;
SAMPLE *certo, *errado;
MIDI *musica;
int mx, my;
int num_monstros;
int pontos, maior;
int acertou;
int i;
- volatile int tempo;
Podemos, então, fazer as inicializações necessárias. Primeiro, criamos o bitmap de double buffering, declarado como a variável tela,
- tela = create_bitmap(MAX_X, MAX_Y);
- bmp_monstro = load_bitmap("monstro.bmp", pal);
- certo = load_sample("certo.wav");
errado = load_sample("errado.wav");
musica = load_midi("caverns.mid");
Após isso, inicializamos com valores aleatórios o vetor de elementos do tipo MONSTRO, da seguinte forma:
- srand(time(0));
for (i = 0; i < MAX_MONSTRO; i++)
{
- monstro[i].x = rand() % (ARENA_X - MONSTRO_X);
monstro[i].y = rand() % (ARENA_Y - MONSTRO_Y);
do
{
- monstro[i].dx = (rand() % (MAX_DX * 2)) - MAX_DX;
do
{
- monstro[i].dy = (rand() % (MAX_DY * 2)) - MAX_DY;
monstro[i].show = TRUE;
- num_monstros = MAX_MONSTRO;
Para terminar, inicializamos as variáveis mx e my, que guardarão os valores da última posição do mouse
- mx = my = -1;
- pontos = 0;
maior = get_config_int(NULL, "HighScore", 0);
Devemos, também, adicionar algumas linhas ao final da função inicia (antes do último return) para que possamos utilizar algumas outras funções.
- set_config_file("jogo.rec");
LOCK_VARIABLE(tempo);
LOCK_FUNCTION(aumenta_tempo);
4. O Loop Principal
Antes de iniciarmos o loop principal do jogo, fazemos algumas chamadas de inicialização que, por certos motivos, foram preferencialmente deixadas para esta parte. Assim, podemos chamar uma função de fade
- fade_in(pal, 4);
- play_midi(musica, TRUE);
- tempo = 0;
install_int(aumenta_tempo, 1000);
Após isso, vamos, finalmente, ao loop principal. A parte do-while consiste de
- clear_keybuf();
do
{
/* Loop Principal */
Então, dentro do loop principal, inserimos o restante do código. Primeiro, as rotinas que irão gerenciar o clique com o botão do mouse
- if ((mouse_b & 1) && ((mouse_x != mx) || (mouse_y != my)))
{
- mx = mouse_x;
my = mouse_y;
for (i = 0, acertou = FALSE; i < MAX_MONSTRO; i++)
{
- if ((mouse_x >= monstro[i].x) && (mouse_x <= (monstro[i].x + MONSTRO_X)) &&
(mouse_y >= monstro[i].y) && (mouse_y <= (monstro[i].y + MONSTRO_Y)) &&
(monstro[i].show))
{
- monstro[i].show = FALSE;
acertou = TRUE;
pontos += (abs(monstro[i].dx) + abs(monstro[i].dy)) * 50;
num_monstros--;
if (acertou)
{
- play_sample(certo, 255, 128, 1000, FALSE);
else
{
- play_sample(errado, 255, 128, 1000, FALSE);
pontos -= 100;
- show_mouse(NULL);
clear(tela);
for (i = 0; i < MAX_MONSTRO; i++)
{
- if (monstro[i].show)
{
- monstro[i].x += monstro[i].dx;
monstro[i].y += monstro[i].dy;
if ((monstro[i].x <> (ARENA_X - MONSTRO_X)))
{
- monstro[i].dx = -monstro[i].dx;
if ((monstro[i].y <> (ARENA_Y - MONSTRO_Y)))
{
- monstro[i].dy = -monstro[i].dy;
draw_sprite(tela, bmp_monstro, monstro[i].x, monstro[i].y);
imprime_placar(tela, pontos, maior, num_monstros);
show_mouse(tela);
blit(tela, screen, 0, 0, 0, 0, MAX_X, MAX_Y);
Com isso, terminamos o loop principal do jogo.
5. As Finalizações
Quando saímos do loop principal, não podemos apenas terminar o programa. É necessário fazer uma série de chamadas, tais como a de parar a música
- stop_midi();
- remove_int(aumenta_tempo);
Além disso, precisamos calcular os pontos do jogador e, se for o caso, armazenar essa pontuação como a maior até o momento. Qualquer que seja a situação, devemos, também, imprimir esta pontuação final obtida. Para isso,
- pontos -= num_monstros * 50;
pontos -= (tempo - 30) * 5 / 3;
if (pontos > maior)
{
- maior = pontos;
set_config_int(NULL, "HighScore", pontos);
clear(tela);
imprime_placar(tela, pontos, maior, num_monstros);
blit(tela, screen, 0, 0, 0, 0, MAX_X, MAX_Y);
- while (key[KEY_ESC]);
clear_keybuf();
textout_centre(screen, font, "Pressione qualquer tecla para continuar", (ARENA_X) / 2,
(ARENA_Y) / 2 - 8, 8);
while (!keypressed());
Apenas para finalizar de uma boa forma, utilizamos uma função de fade
- fade_out(4);