sexta-feira, 10 de outubro de 2014

TileMap

Fala Galeria... Quem é vivo sempre aparece... Como o meu roteador queimou, agora apenas 1 pc tem Internet aqui em casa.. E fica complicado eu escrever coisas pois meus irmãos também querem entrar na net..

Já tem um tempo que fiz esse programa, e foi a ultima coisa q eu fiz... Estou tentando pensar em uma lógica que consegue juntar os cenários e os objetos. Mais esta difícil =/...

Bom... A minha ideia de TileMap é o seguinte: Existe um conjunto de tiles (que pode esta em uma imagem ou separados) e um arquivo com os dados de onde deve posicionar os tiles.

Para fazer o arquivo que contem os dados onde cada Tiles vão ficar...  Eu usei o programa Tiled



E exporto para o formato .txt. O que sai um arquivo assim:


 [header]  
 width=10  
 height=7  
 tilewidth=64  
 tileheight=64  
 [tilesets]  
 tileset=../workspace/TilesMap/BLOCOS.png,64,64,0,0  
 tileset=../workspace/TilesMap/pipes.png,64,64,0,0  
 tileset=../workspace/TilesMap/Terreno.png,64,64,0,0  
 [layer]  
 type=Camada de Tiles 1  
 data=  
 1,0,0,2,0,0,107,108,0,0,  
 1,0,2,2,0,0,107,108,1,1,  
 1,0,0,2,0,0,113,114,1,1,  
 1,0,2,2,2,0,0,0,1,1,  
 193,194,194,194,194,195,97,98,1,1,  
 199,200,200,200,200,201,103,104,1,1,  
 199,200,200,200,200,201,103,104,1,1  

Modifiquei um pouco (na verdade muito) para facilitar minha vida...


 10 7 64  
 1 0 0 2 0 0 107 108 0 0   
 1 0 2 2 0 0 107 108 1 1   
 1 0 0 2 0 0 113 114 1 1   
 1 0 2 2 2 0 0 0 1 1   
 193 194 194 194 194 195 97 98 1 1   
 199 200 200 200 200 201 103 104 1 1   
 199 200 200 200 200 201 103 104 1 1  

Bom os 2 primeiros números representam o numero de tiles horizontais e verticais.  O terceiro numero representa o tamanhos dos tiles (é so um pq eu definir que os tiles serão todos quadrados), e na sequencia estão os dados do mapa.

Uma duvida natural seria: Como existe mais de um tileset (é esse o termo?), qual seria a ordem dos números? A Resposta é bem simples, é a ordem que eu add os tileset no Tiled. No caso do nosso exemplo a ordem foi: BLOCOS, pipes, Terreno. Essa ordem é muito importante...  Por isso que essa ordem foi mantido ao abrir os arquivos da imagem no programa.


 add_tileset(mapa, "BLOCOS.png", 0);
 add_tileset(mapa, "pipes.png", 1);
 add_tileset(mapa, "Terreno.png", 2);

Outro detalhe que padronizei é que cada tileset tera dimensão 384 x 1024 (para tiles de tamanho de dimensão 64x64)... Com base nisso podemos fazer um simples calculo para calcular o numeros de tiles que tem em um tileset... (384/64) * (1024/64) = 96... Guarde esse numero pois ele vai aparecer no codigo =P



Mais uma coisa vou usar congruência modular e o Tiled usa 0 para definir espaço vazio, vou diminuir 1 unidade desses valores... E usar -1 para espaço vazio... Isso vai facilitar e muito a logica do código... Sem mais enrolacao o codigo pode ser baixado aqui:



(o arquivo level1.txt é diferente do exemplo mostrado)





main.c:
#include "mapa.h"
int main()
{
 tipo_allegro5 DATA;


 //Inicializa o Allegro e cria uma janela 640 x 480
 tipo_mapa mapa;
 allegro_inicializa(&DATA, 640, 480);
 load_mapa(&mapa, "level1.txt");
        
        desenha_level(&mapa,0,0);
        al_flip_display();

 al_rest(3);
 return 0;
}



mapa.h:
#ifndef MAPA_H_
#define MAPA_H_

#include "allegro5.h"
#define TOTAL_TILESET 3

typedef struct tipo_tilemapa
{
 int *mapa;
 int tamanho_tiles;
 int num_tiles_vert;
 int num_tiles_horizontal;

} tipo_tilemapa;

typedef struct tipo_mapa
{
 ALLEGRO_BITMAP *tileset[TOTAL_TILESET];
 tipo_tilemapa camada_principal;

} tipo_mapa;

//Carrega um mapa
void load_mapa(tipo_mapa *mapa, char endereco[100]);

//Desenha o mapa na tela
void desenha_level(tipo_mapa *mapa, int x, int y);

void add_tileset (tipo_mapa *mapa, char endereco[100], int id);

#endif /* MAPA_H_ */



mapa.c
#include "mapa.h"

void load_mapa(tipo_mapa *mapa, char endereco[100])
{
 int num_tiles_vert;
 int num_tiles_horizontal;
 int tiles_tamanho;
 int i, j;
 FILE *level;
 int valor;

 add_tileset(mapa, "BLOCOS.png", 0);
 add_tileset(mapa, "pipes.png", 1);
 add_tileset(mapa, "Terreno.png", 2);

 //Abri o arquivo com o mapa
 level = fopen(endereco, "r");



 //Ler o tamanho do tilemap
 fscanf(level, "%i %i", &num_tiles_horizontal, &num_tiles_vert);
 mapa->camada_principal.num_tiles_horizontal = num_tiles_horizontal;
 mapa->camada_principal.num_tiles_vert = num_tiles_vert;


 //Ler o tamanho dos tiles
 fscanf(level,"%i", &tiles_tamanho);
 mapa->camada_principal.tamanho_tiles = tiles_tamanho;

 //Aloca memoria para o mapa
 mapa->camada_principal.mapa = (int *) malloc (sizeof(int) * num_tiles_vert * num_tiles_horizontal);

 //Ler os dados do mapa
 for(i = 0; i < num_tiles_vert; i++)
 {
  for(j = 0; j < num_tiles_horizontal; j++)
  {
   fscanf(level, "%i", &valor);
   valor--;
   mapa->camada_principal.mapa[i * num_tiles_horizontal + j] = valor;
  }
 }

 //Fecha o arquivo com o level
 fclose(level);

}

//Desenha o mapa na tela
void desenha_level(tipo_mapa *mapa, int x, int y)
{
 int i, j;

 int num_vert = mapa->camada_principal.num_tiles_vert;
 int num_horiz = mapa->camada_principal.num_tiles_horizontal;
 int * MAPA = mapa->camada_principal.mapa;
 int valor;
 for(i = 0; i < num_vert; i++)
 {
  for(j = 0; j < num_horiz; j++)
  {
   //Por padrão todos os tileset terão 96 tiles distribuido
   //em 6 colunas e 16 linhas. todos os tiles Serão quadrados 64x64

   valor = MAPA[i * num_horiz + j];
   printf("%i ", valor);

   if(valor < 0) continue;
   al_draw_bitmap_region(mapa->tileset[valor/96],64 * ((valor%96)%6) , 64 * ((valor%96)/6), 64, 64, j * 64 + x, i * 64 + y, 0);

  }
 }
}


void add_tileset (tipo_mapa *mapa, char endereco[100], int id)
{

 mapa->tileset[id] = al_load_bitmap(endereco);
 if(!(mapa->tileset[id]))
 {
  fprintf(stderr, "Falha ao carregar a imagem %s\n", endereco);
  exit(-1);
 }
}


 
 
É apenas uma ideia e tem muita coisa ainda para melhorar...

Nenhum comentário:

Postar um comentário

Related Posts Plugin for WordPress, Blogger...