sexta-feira, 10 de outubro de 2014

Allegro5.h

Finalmente  (ate parece que foi muito tempo)... Vou mostrar o código da versão 1.04...
A arte de programação em geral tem que ser algo planejado... Principalmente a programação de jogos sejam ele 2D e 3D... Mas como eu não sigo essa filosofia eu so sento no pc e vou escrevendo linhas de codigo e vejo no que vai dar XD

Antes de mostra o código... que não viu a postagem Allegro5.h veja pois o código de muitas funções que vou usar estão lá.

Para fazer o download do código (o que eu recomendo):

DOWNLOAD



estrutuas.h:
#include <stdio.h>
// Inclui o cabeçalho da bibilioteca Allegro 5
#include "allegro5.h"
//Definicoes
#define MAX_CARROS 4

//------------------------Carro inimigo--------------------------------
typedef struct tipo_carro_inimigo
{
 ALLEGRO_BITMAP *imagem;
 short ativo;
 int x;
 int y;
 int dir; // 0 - parado, 1 - Esquerda(left),  2 - direita

} tipo_carro_inimigo;

//Carrega a imagem do carro
void carrega_carro_inimigo (tipo_carro_inimigo* carro_inimigo, char endereco[100]);

//Atualiza a posicao do carro
void atualiza_carro_inimigo (tipo_carro_inimigo* carro_inimigo, int velocidade);

//Desenha o carro na tela
void desenha_carro_inimigo (tipo_carro_inimigo* carro_inimigo);

//Verifica se o carro esta ativo
int status_carro_inimigo  (tipo_carro_inimigo* carro_inimigo);

//Adiciona um carro no "jogo"
void add_carro_inimigo (tipo_carro_inimigo* carro_inimigo);

//Desativa um carro
void des_carro_inimigo (tipo_carro_inimigo* carro_inimigo);


//-------------------------bandeira---------------------------------

typedef struct tipo_bandeira
{
 ALLEGRO_BITMAP *imagem;
 int x;
 int y;

} tipo_bandeira;

//Carrega a imagem da bandeira
void carrega_bandeira(tipo_bandeira *bandeira, char endereco[100]);

//Atualiza a posicao da bandeira
void atualiza_bandeira(tipo_bandeira *bandeira, int velocidade);

//Desenha bandeira
void desenha_bandeira(tipo_bandeira *bandeira);

//Volta a bandeira para sua posição "inicial"
void reset_posicao_inical_bandeira(tipo_bandeira *bandeira);

//-------------------------jogador---------------------------------
typedef struct tipo_jogador
{
 ALLEGRO_BITMAP *imagem;
 int x;
 int y;

} tipo_jogador;

//Carrega a imagem do jogador
void carrega_jogador(tipo_jogador *jogador, char endereco[100]);

//Atualiza a posicao do jogador
void atualiza_jogador(tipo_jogador *jogador, tipo_allegro5 *DATA);
//Desenha o jogador na tela
void desenha_jogador(tipo_jogador *jogador);
//verifica se o jogador colidiu com algum carro
int colicao_jogador_carro_inimigo (tipo_jogador *jogador, tipo_carro_inimigo* carro_inimigo);
//verifica se o jogador colidiu com a bandeira
int colicao_jogador_bandeira (tipo_jogador *jogador, tipo_bandeira *bandeira);

//Volta o jogador para sua posição "inicial"
void reset_posicao_inical_jogador(tipo_jogador *jogador);
estrutuas.c:
#include "estruturas.h"

void carrega_carro_inimigo (tipo_carro_inimigo* carro_inimigo, char endereco[100])
{
 //Carrega a imagem do carro
 carro_inimigo->imagem = al_load_bitmap(endereco);
 if(!(carro_inimigo->imagem))
 {
  fprintf(stderr, "Falha ao carregar a imagem %sn", endereco);
  exit(-1);
 }

 carro_inimigo->ativo = 0;
}

void atualiza_carro_inimigo (tipo_carro_inimigo* carro_inimigo, int velocidade)
{
 //O movimento do carros são aleatorios mais se eles estão se movimentando em uma dada direcao
 //a probabilidade deles continuar nelas é maior

 int numero_rand = rand()%20;
 carro_inimigo->y += velocidade;

 if(carro_inimigo->dir == 0) //O carro não esta com um movimento inclinado
 {
  if(numero_rand < 17) //O carro continua sem um movimento inclinado
  {
   return;
  }
  else if(numero_rand < 19)
  {
   carro_inimigo->dir = 1;
  }
  else
  {
   carro_inimigo->dir = 2;
  }
 }
 else // O carro esta se movimentando para uma direcao
 {
  if (numero_rand < 5) // O carro fica "parado"
  {
   carro_inimigo->dir = 0;
   return;
  }
  else if (numero_rand == 20) // O carro muda de direcao
  {
   if (carro_inimigo->dir == 1)
   {
    carro_inimigo->dir = 2;
   }
   else
   {
    carro_inimigo->dir = 1;
   }
  }
 }

 //Movimenta o carro
 if(carro_inimigo->dir == 1)
 {
  carro_inimigo->x -= velocidade;
  if(carro_inimigo->x < 160) //Limite da pista
  {
   carro_inimigo->x = 160;
   carro_inimigo->dir = 2; //Muda a direcao
  }
 }
 else
 {
  carro_inimigo->x += velocidade;
  if(carro_inimigo->x > 440) //Limite da pista
  {
   carro_inimigo->x = 440;
   carro_inimigo->dir = 1; //Muda a direcao
  }
 }

}

//Desenha o carro na tela
void desenha_carro_inimigo (tipo_carro_inimigo* carro_inimigo)
{
 al_draw_bitmap(carro_inimigo->imagem,  carro_inimigo->x, carro_inimigo->y, 0);
}

void carrega_jogador(tipo_jogador *jogador, char endereco[100])
{
 //Carrega a imagem
 jogador->imagem = al_load_bitmap(endereco);
 if(!(jogador->imagem))
 {
  fprintf(stderr, "Falha ao carregar a imagem %sn", endereco);
  exit(-1);
 }

 //Coloca a posição inicial do jogador
 jogador->x = 208;
 jogador->y = 400;
}


//Verifica se o carro esta ativo
int status_carro_inimigo  (tipo_carro_inimigo* carro_inimigo)
{
 return carro_inimigo->ativo;
}


//Adiciona um carro no "jogo"
void add_carro_inimigo (tipo_carro_inimigo* carro_inimigo)
{

 carro_inimigo->y = -60;
 carro_inimigo->x = rand()%280 + 160;
 carro_inimigo->ativo = 1;
 carro_inimigo->dir = rand()%3; //Direcao inicial aleatoria
}

void des_carro_inimigo (tipo_carro_inimigo* carro_inimigo)
{
 carro_inimigo->ativo = 0;
}

void atualiza_jogador(tipo_jogador *jogador, tipo_allegro5 *DATA)
{
 allegro_atualiza_teclado_estatus (DATA);

 if (allegro_tecla(DATA, ALLEGRO_KEY_UP))
 {
        if(jogador->y - 8 > 0)
        {
         jogador->y -= 8;
        }
        else
        {
         jogador->y = 0;
        }
 }
 if (allegro_tecla(DATA, ALLEGRO_KEY_DOWN))
 {
        if(jogador->y + 8 < 416)
        {
         jogador->y += 8;
        }
        else
        {
         jogador->y = 416;
        }
 }
 if (allegro_tecla(DATA, ALLEGRO_KEY_LEFT))
 {
        if(jogador->x - 8 > 160)
        {
         jogador->x -= 8;
        }
        else
        {
         jogador->x = 160;
        }
 }
 if (allegro_tecla(DATA, ALLEGRO_KEY_RIGHT))
 {
        if(jogador->x + 8 <  440)
        {
         jogador->x += 8;
        }
        else
        {
         jogador->x = 440;
        }
 }


}

void desenha_jogador(tipo_jogador *jogador)
{
 al_draw_bitmap(jogador->imagem, jogador->x, jogador->y, 0);
}

//verifica se o jogador colidiu com algum carro
int colicao_jogador_carro_inimigo (tipo_jogador *jogador, tipo_carro_inimigo* carro_inimigo)
{
 if(jogador->x >= carro_inimigo->x + 40)
 {
  return 0;
 }
 if (jogador->x + 40 <= carro_inimigo->x)
 {
  return 0;
 }
 if(jogador->y >= carro_inimigo->y + 64)
 {
  return 0;
 }
 if (jogador->y + 64 <= carro_inimigo->y)
 {
  return 0;
 }
 return 1;

}

int colicao_jogador_bandeira (tipo_jogador *jogador, tipo_bandeira *bandeira)
{
 if(jogador->x >= bandeira->x + 32)
 {
  return 0;
 }
 if (jogador->x + 40 <= bandeira->x)
 {
  return 0;
 }
 if(jogador->y >= bandeira->y + 32)
 {
  return 0;
 }
 if (jogador->y + 40 <= bandeira->y)
 {
  return 0;
 }

 bandeira->y = -60;
 bandeira->x = rand()%280 + 160;

 return 1;
}

//Carrega a imagem da bandeira
void carrega_bandeira(tipo_bandeira *bandeira, char endereco[100])
{
 bandeira->imagem = al_load_bitmap(endereco);
 if(!(bandeira->imagem))
 {
  fprintf(stderr, "Falha ao carregar a imagem %sn", endereco);
  exit(-1);
 }
 bandeira->y = -60;
 bandeira->x = rand()%280 + 160;
}

//Atualiza a posicao da bandeira
void atualiza_bandeira(tipo_bandeira *bandeira, int velocidade)
{
 bandeira->y += velocidade;

 if(bandeira->y > 480)
 {
  bandeira->y = -60;
  bandeira->x = rand()%280 + 160;
 }
}

void desenha_bandeira(tipo_bandeira *bandeira)
{
 al_draw_bitmap(bandeira->imagem, bandeira->x, bandeira->y, 0);
}


void reset_posicao_inical_bandeira(tipo_bandeira *bandeira)
{
 bandeira->y = -60;
 bandeira->x = rand()%280 + 160;
}

//Volta o jogador para sua posição "inicial"
void reset_posicao_inical_jogador(tipo_jogador *jogador)
{
 //Coloca a posição inicial do jogador
 jogador->x = 208;
 jogador->y = 400;
}

main.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//Estruturas usasdas no jogo
#include "estruturas.h"


//Principal funcao do jogo
void jogo_main (tipo_allegro5 *DATA);
int jogo_menu(tipo_allegro5 *DARA,  int recorde);

int main ()
{
 //Cria as estruturas usadas no Allegro 5
 tipo_allegro5 DATA;

 //Inicializa o Allegro
 //Janela de 640 x 480

 allegro_inicializa (&DATA, 640, 480);

 //Carrega a musica ARPE.ogg
 allegro_add_musica(&DATA, 0, "ARPE.ogg");

 //Carrega sample
 allegro_add_sample(&DATA, 0, "Bip.wav");

 //Carrega a fonte adinekir.ttf
 allegro_add_fonte(&DATA, 0, "Ubuntu-L.ttf", 24);

 //Gera uma chave aleatoria;
 srand(time(NULL));

 //Titulo da Janela
 allegro_titulo_janela (&DATA, "Carros 1.04");


 //Inicia o jogo
 jogo_main(&DATA);

 return 0;
}

void jogo_main (tipo_allegro5 *DATA)
{
 char texto[100];
 int velocidade;
 int pontuacao;
 int nivel;
 int recorde = 0;
 int distancia;
 int i;
 int indicie_carro;
 int menu = 0;
 const int CARRO_MAX = 5; //Numero maximo de carro
 ALLEGRO_EVENT evento;

 tipo_jogador jogador;
 tipo_carro_inimigo carro_inimigo[CARRO_MAX];
 tipo_bandeira bandeira;

 //inicia o jogador
 carrega_jogador(&jogador, "jogador.png");

 //Carrega inimigos
 for(i = 0; i < CARRO_MAX; i++)
 {
  carrega_carro_inimigo(&carro_inimigo[i], "inimigo.png");
 }

 //Carrega a bandeira
 carrega_bandeira(&bandeira, "bandeira.png");


    while(1)
 {
     //Configuracao inicial
  velocidade = 0;
  pontuacao = 0;
  nivel = 0;
  distancia = 0;
  indicie_carro = 0;
  menu = 0;

  //Desativa todos os carros do inimigos
  for(i = 0; i < CARRO_MAX; i++)
  {
   des_carro_inimigo(&carro_inimigo[i]);
  }

  //inicia o menu;
  if(!jogo_menu(DATA, recorde))
  {
   return;
  }

  //Toca a musica
  allegro_controle_musica(DATA,0,START);

  while(1)
  {
   while(allegro_novo_evento(DATA, &evento)) //Verifica se tem eventos
   {
    if (evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE) //Fecha a janela
    {
     return;
    }
   }

   //Atualiza jogador
   atualiza_jogador(&jogador, DATA);

   //Adiciona carros
   if(distancia >= 150)
   {
    add_carro_inimigo(&carro_inimigo[indicie_carro]);
    indicie_carro++;
    indicie_carro %= CARRO_MAX;
    distancia = 0;
   }
   else
   {
    distancia += velocidade;
   }

   //Limpa a tela
   al_clear_to_color(al_map_rgb(0, 0, 0));

   //Desenha um retangulo
   al_draw_filled_rectangle(160, 0, 480, 480, al_map_rgb(125, 125, 125));

   //Pontos e nivel
   sprintf(texto, "Nivel: %i", nivel);
   allegro_escreve_texto(DATA, 0, 10, 10, al_map_rgb(255, 255, 255), texto);
   sprintf(texto, "pontuacao: %i", pontuacao);
   allegro_escreve_texto(DATA, 0, 10, 34, al_map_rgb(255, 255, 255), texto);

   //Desenha o jogador
   desenha_jogador(&jogador);

   //Atualiza os carros inimigos
   for(i = 0; i < CARRO_MAX; i++)
   {
    if(status_carro_inimigo(&carro_inimigo[i]))
    {
     atualiza_carro_inimigo(&carro_inimigo[i], velocidade);
     //Desenha o carro
     desenha_carro_inimigo(&carro_inimigo[i]);
     if(colicao_jogador_carro_inimigo(&jogador, &carro_inimigo[i]))
     {
      allegro_controle_musica(DATA,0,STOP); //Para a musica
      reset_posicao_inical_jogador(&jogador);
      reset_posicao_inical_bandeira(&bandeira);
      menu = 1; //Volta para o menu inicial
     }
    }
   }
   if(menu) break; //Volta para o menu inicial

   //Atualiza a bandeira
   atualiza_bandeira(&bandeira, 2 * velocidade);
   desenha_bandeira(&bandeira);

   if(colicao_jogador_bandeira(&jogador, &bandeira))
   {
    allegro_start_sample(DATA, 0);
    pontuacao++;
   }



    nivel = pontuacao/5;
    velocidade = nivel + 4;


   //Atualiza a tela
   al_flip_display();
   al_rest(0.06);

  }
  //Muda o record
  if(recorde < pontuacao)
  {
   recorde = pontuacao;
  }
 }

}

int jogo_menu(tipo_allegro5 *DATA,  int recorde)
{
 //Limpa a tela
 char texto[100];

 allegro_escreve_texto(DATA, 0, 220, 100, al_map_rgb(255, 255, 0), "Carros 1.04");
 allegro_escreve_texto(DATA, 0, 220, 124, al_map_rgb(255, 255, 255), "ENTER - Novo jogo");
 allegro_escreve_texto(DATA, 0, 220, 148, al_map_rgb(255, 255, 255), "ESC - sair");
 sprintf(texto,"Recorde: %i", recorde);
 allegro_escreve_texto(DATA, 0, 220, 172, al_map_rgb(255, 255, 255), texto);
 al_flip_display();
 ALLEGRO_EVENT evento;

 while(1) //Verifica se tem eventos
 {
  if(allegro_novo_evento(DATA, &evento))
  {

   if (evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE) //Fecha a janela
   {
    return 0;
   }
   if(evento.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
   {
    return 0;
   }
   if (evento.keyboard.keycode == ALLEGRO_KEY_ENTER)
   {
    return 1;
   }

  }
  al_rest(1/15);
 }
 return 0;
}
Como pode ser vistos no código houve algumas mudanças... Tudo relacionando a inicialização carregamento da biblioteca Allegro5 está sendo feito na funcao main.
Algumas variações:

Movimentos dos Carros Inimigos

Os carros inimigos continuam se movimentando aleatoriamente. Mas não é um movimento aleatório com pesos iguais. Agora o movimento tem um peso maior para ele continuar na direção que ele se encontra. Sendo assim a chance dele percorrer a pista toda é bem maior... Na versão 1.00 os Carros ficavam fazendo zig-zag  mais continuavam praticalmente no mesmo lugar

Mudança da distancia minima

A distancia mínima entre os carros inimigos foi algo que eu fiz na versão 1.00 mas não mencionei. A distancia mínima garante que não seja adicionado 2 carros... ao mesmo tempo, como nesse programa não estamos tratando da colisão entre carros inimigos isso ajuda. A distancia minima passou de 200 para 150... Aumentando assim na minha opinião a dificuldade.

Nivel e Pontos

Como vocês devem ter lido na outra postagem estava com uma dificuldade com relação ao aumento do nivel. Foi feito uma mudança bem simples...  O nível é definido da seguinte forma: nível = pontuacao/5... Algo bem simples neh XD

Jogo funcionando no Linux




Jogo funcionando no Linux

Vejam o vídeo:

Nenhum comentário:

Postar um comentário

Related Posts Plugin for WordPress, Blogger...