Ontem a noite eu resolvir tentar programa um jogo... sim depois de muito tempo. XD
O jogo é da cobrinha no estilo mini game... Aqueles 50K jogos em 1.
Um imagem do jogo funcionando:
Você pode baixar o código fonte aqui:
Eu meio q super exageradamente dividir o código em varios arquivos:
allegro.h:
/* * allegro.h * * Created on: 12/10/2014 * Author: paulo * #ifndef ALLEGRO_H_ #define ALLEGRO_H_ #includeallegro.c :#include #include #include #include #include //Inicializa a biblioteca allegro void allegro_inicializar(ALLEGRO_DISPLAY **janela, ALLEGRO_EVENT_QUEUE **fila_eventos, ALLEGRO_FONT **fonte); //Fecha a bibliote allegro void allegro_fechar(ALLEGRO_DISPLAY *janela, ALLEGRO_EVENT_QUEUE *fila_eventos, ALLEGRO_FONT *fonte); #endif /* ALLEGRO_H_ *
/*
* allegro.c
*
* Created on: 12/10/201
* Author: paulo
*
#include "allegro.h"
//Inicializa a biblioteca allegro
void allegro_inicializar(ALLEGRO_DISPLAY **janela, ALLEGRO_EVENT_QUEUE **fila_eventos, ALLEGRO_FONT **fonte)
{
if (!al_init())
{
fprintf(stderr, "Falha ao inicializar a biblioteca Allegro.\n");
exit(-1);
}
if (!al_init_primitives_addon())
{
fprintf(stderr, "Falha ao inicializar add-on de primitivas.\n");
exit(-1);
}
al_init_font_addon();
if (!al_init_ttf_addon())
{
fprintf(stderr, "Falha ao inicializar add-on allegro_ttf.\n");
exit(-1);
}
if (!al_install_keyboard())
{
fprintf(stderr, "Falha ao inicializar o teclado.\n");
exit(-1);
}
*janela = al_create_display(480, 640);
if (!(*janela))
{
fprintf(stderr, "Falha ao criar janela.\n");
exit(-1);
}
*fila_eventos = al_create_event_queue();
if (!(*fila_eventos))
{
fprintf(stderr, "Falha ao criar fila de eventos.\n");
al_destroy_display((*janela));
exit(-1);
}
al_register_event_source((*fila_eventos), al_get_keyboard_event_source());
al_register_event_source((*fila_eventos), al_get_display_event_source((*janela)));
*fonte = al_load_font("Action Man Bold.ttf", 16, 0);
if (!(*fonte))
{
fprintf(stderr, "Falha ao carregar \"Action Man Bold.ttf\".\n");
al_destroy_display((*janela));
al_destroy_event_queue((*fila_eventos));
exit(-1);
}
al_set_window_title((*janela), "Cobra (Snake)");
}
//Fecha a bibliote allegro
void allegro_fechar(ALLEGRO_DISPLAY *janela, ALLEGRO_EVENT_QUEUE *fila_eventos, ALLEGRO_FONT *fonte)
{
al_destroy_display(janela);
al_destroy_event_queue(fila_eventos);
al_destroy_font(fonte);
}
desenho.h
/* * desenhos.h * * Created on: 12/10/2014 * Author: paulo */ #ifndef DESENHOS_H_ #define DESENHOS_H_ #includedesenho.c:#include //Desenha "pixel" de um LCD grafico de um mini-game void desenha_pixel(int _x, int _y, ALLEGRO_COLOR cor, ALLEGRO_COLOR cor_fundo); #endif /* DESENHOS_H_ */
/*
* desenhos.c
*
* Created on: 12/10/2014
* Author: paulo
*/
#include "desenhos.h"
//Desenha "pixel" de um LCD grafico de um mini-game
void desenha_pixel(int _x, int _y, ALLEGRO_COLOR cor, ALLEGRO_COLOR cor_fundo)
{
int x = 32 * _x;
int y = 32 * _y;
// Retângulo preenchido: x1, y1, x2, y2, cor
al_draw_filled_rectangle(x, y, x + 32, y + 32, cor);
al_draw_filled_rectangle(x + 4, y + 4, x + 28, y + 28, cor_fundo);
al_draw_filled_rectangle(x + 8, y + 8, x + 24, y + 24, cor);
}
coord_int.h
/*
* TAD que simula uma coordenada inteira
* Created on: 12/10/2014
* Author: paulo
*/
#ifndef COORD_INT_H_
#define COORD_INT_H_
#include <stdbool.h>
typedef struct tipo_coord_int
{
int x; //0 - 9
int y; //0 - 19
} tipo_coord_int;
tipo_coord_int coord_int(int x, int y);
//Compara duas coordenadas
bool coord_int_comp(tipo_coord_int A, tipo_coord_int B);
#endif /* COORD_INT_H_ *
coord_int.c
/*
* coord_int.c
*
* Created on: 12/10/2014
* Author: paulo
*
#include "coord_int.h"
tipo_coord_int coord_int(int x, int y)
{
tipo_coord_int novo;
novo.x = x;
novo.y = y;
return novo;
}
//Compara duas coordenadas
bool coord_int_comp(tipo_coord_int A, tipo_coord_int B)
{
return ((A.x == B.x) && (A.y == B.y));
}
cobra.h :
/*
* TAD para manipulação da cobra do jogo
*
* Created on: 12/10/2014
* Author: paulo
*/
#include <stdbool.h>
#include "desenhos.h"
#include "coord_int.h"
#ifndef COBRA_H_
#define COBRA_H_
typedef enum direcao {CIMA, BAIXO, ESQUERDA, DIREITA, NENHUM} direcao;
//Estrutura da cobra
typedef struct tipo_cobra
{
int tamanho;
direcao dir;
tipo_coord_int coord[200]; // 20 x 10
} tipo_cobra;
//Inicializa a cobra
void cobra_inicializa(tipo_cobra *c);
//Atualiza a cobra
void cobra_atualiza(tipo_cobra *c);
//Aumenta o tamanho da cobra
void cobra_cresce(tipo_cobra *c);
//Desenha a cobra
void cobra_desenha(tipo_cobra *c, ALLEGRO_COLOR cor_fundo);
//Verifica se a cobra esta em uma determinada coordenada começando p
bool cobra_ver_coord(tipo_cobra *c, tipo_coord_int p, bool cabeca);
//Altera a direcao da cobra
void cobra_direcao(tipo_cobra *c, direcao dir);
//Retorna a coordenada da cabeça da cobra
tipo_coord_int cobra_coord (tipo_cobra *c);
#endif /* COBRA_H_ *
comida.h :
/*
* comida.h
*
* Created on: 12/10/2014
* Author: paulo
*/
#ifndef COMIDA_H_
#define COMIDA_H_
#include "coord_int.h"
#include "cobra.h"
#include "desenhos.h"
typedef struct tipo_comida
{
tipo_coord_int coord;
} tipo_comida;
//Muda a posicao da comida (Onde não tem a cobra)
void comida_novo(tipo_comida *comida, tipo_cobra *cobra);
//Desenha a comida
void comida_desenha(tipo_comida *comida, ALLEGRO_COLOR cor_fundo);
//Coordenada da comida
tipo_coord_int comida_coord(tipo_comida *comida);
#endif /* COMIDA_H_ */
comida.c :
/*
* comida.c
*
* Created on: 12/10/2014
* Author: paulo
*/
#include "comida.h"
//Muda a posicao da comida
void comida_novo(tipo_comida *comida, tipo_cobra *cobra)
{
//De maneira aleatoira escolhe um local para a comida
//Esse local não pode esta com a cobra
int x = rand()%10;
int y = rand()%20;
while(cobra_ver_coord(cobra, coord_int(x,y), false))
{
x = rand()%10;
y = rand()%20;
}
comida->coord.x = x;
comida->coord.y = y;
}
void comida_desenha(tipo_comida *comida, ALLEGRO_COLOR cor_fundo)
{
desenha_pixel(comida->coord.x, comida->coord.y, al_map_rgb(0,127,0), cor_fundo);
}
//Coordenada da comida
tipo_coord_int comida_coord(tipo_comida *comida)
{
return comida->coord;
}
jcobra_colisao.h:
/* * jcobra_colisao.h * * Created on: 12/10/2014 * Author: paulo */ #ifndef JCOBRA_COLISAO_H_ #define JCOBRA_COLISAO_H_ #include "cobra.h" #include "comida.h" bool colisao_cobra_comida(tipo_cobra *cobra, tipo_comida *comida); bool colisao_cobra_cobra (tipo_cobra *cobra); #endif /* JCOBRA_COLISAO_H_ */jcobra_colisao.c:
/*
* jcobra_colisao.c
*
* Created on: 12/10/2014
* Author: paulo
*/
#include "jcobra_colisao.h"
bool colisao_cobra_comida(tipo_cobra *cobra, tipo_comida *comida)
{
return coord_int_comp(cobra_coord(cobra), comida_coord(comida));
}
bool colisao_cobra_cobra (tipo_cobra *cobra)
{
return cobra_ver_coord(cobra, cobra_coord(cobra), true);
}
main.c:
/*
* File: main.c
* Author: paulo
*
* Created on 12 de Outubro de 2014, 13:08
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <math.h>
#include "allegro.h"
#include "cobra.h"
#include "comida.h"
#include "jcobra_colisao.h"
#define cor_fundo al_map_rgb(236, 236, 236)
//Modo classico do jogo da cobra
void jcobra_classico(ALLEGRO_EVENT_QUEUE *fila_eventos, ALLEGRO_FONT *fonte, int nivel);
int main()
{
ALLEGRO_DISPLAY *janela = NULL;
ALLEGRO_EVENT_QUEUE *fila_eventos = NULL;
ALLEGRO_FONT *fonte = NULL;
allegro_inicializar(&janela, &fila_eventos, &fonte);
jcobra_classico( fila_eventos, fonte, 2);
allegro_fechar(janela, fila_eventos, fonte);
return 0;
}
void jcobra_desenha_dados(ALLEGRO_FONT *fonte,float pontos, int nivel)
{
/*
* Desenhas os dados do jogo: Ponto, nivel
* Desenha o retangulo
*/
al_draw_rectangle(0, 0, 320, 640, al_map_rgb(0, 0, 0), 2);
al_draw_textf(fonte, al_map_rgb(0, 0, 0), 324, 4, ALLEGRO_ALIGN_LEFT, "Pontos: %.2f", pontos);
al_draw_textf(fonte, al_map_rgb(0, 0, 0), 324, 24, ALLEGRO_ALIGN_LEFT, "Nivel: %i", nivel);
}
direcao jcobra_direcao(ALLEGRO_EVENT evento)
{
switch(evento.keyboard.keycode)
{
case ALLEGRO_KEY_UP:
return CIMA;
case ALLEGRO_KEY_DOWN:
return BAIXO;
case ALLEGRO_KEY_LEFT:
return ESQUERDA;
case ALLEGRO_KEY_RIGHT:
return DIREITA;
case ALLEGRO_KEY_P: //Pausa o jogo
//parado = true;
return NENHUM;
}
return NENHUM;
}
void jcobra_pause(ALLEGRO_EVENT_QUEUE *fila_eventos, ALLEGRO_FONT *fonte)
{
ALLEGRO_EVENT evento;
al_draw_text(fonte, al_map_rgb(0, 0, 0), 360, 320, ALLEGRO_ALIGN_LEFT, "PAUSE");
al_flip_display();
for(;;)
{
if(!al_event_queue_is_empty(fila_eventos))
{
al_wait_for_event(fila_eventos, &evento);
if(evento.type == ALLEGRO_EVENT_KEY_DOWN)
{
if(evento.type == ALLEGRO_EVENT_KEY_DOWN)
{
if(evento.keyboard.keycode == ALLEGRO_KEY_P)
{
//parado = false;
return;
}
}
}
else if (evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
{
exit(0);
}
}
al_rest(0.01);
}
}
void jcobra_classico(ALLEGRO_EVENT_QUEUE *fila_eventos, ALLEGRO_FONT *fonte, int nivel)
{
ALLEGRO_EVENT evento;
tipo_cobra cobra;
tipo_comida comida;
cobra_inicializa(&cobra);
comida_novo(&comida, &cobra);
direcao dir_novo = NENHUM;
float pontos = 0;
float velocidade = 1/(pow(2,nivel));
al_clear_to_color(cor_fundo); //Preenche com a cor do fundo
srand(time(NULL)); //Chave aleatoria
while (1)
{
if(!al_event_queue_is_empty(fila_eventos))
{
al_wait_for_event(fila_eventos, &evento);
if(evento.type == ALLEGRO_EVENT_KEY_DOWN)
{
switch(evento.keyboard.keycode)
{
case ALLEGRO_KEY_UP:
dir_novo = CIMA;
break;
case ALLEGRO_KEY_DOWN:
dir_novo = BAIXO;
break;
case ALLEGRO_KEY_LEFT:
dir_novo = ESQUERDA;
break;
case ALLEGRO_KEY_RIGHT:
dir_novo = DIREITA;
break;
case ALLEGRO_KEY_P:
jcobra_pause(fila_eventos, fonte); //Pausa o jogo
break;
}
}
if (evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
{
break;
}
}
else
{
cobra_direcao(&cobra, dir_novo);
dir_novo = NENHUM;
al_clear_to_color(cor_fundo); //Preenche com a cor do fundo
cobra_atualiza(&cobra);
if(colisao_cobra_comida(&cobra, &comida))
{
pontos+=(pow(2,nivel));
comida_novo(&comida, &cobra);
cobra_cresce(&cobra);
}
else if(colisao_cobra_cobra(&cobra))
{
pontos = 0;
cobra_inicializa(&cobra);
}
cobra_desenha(&cobra,cor_fundo);
comida_desenha(&comida, cor_fundo);
jcobra_desenha_dados(fonte, pontos, nivel);
al_flip_display();
al_rest(velocidade); //Pausa
}
}
}
No proximo post comento sobre a implementação. Ate mais pessoas XD



















