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