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 XDAntes 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):
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