Skip to content

Instantly share code, notes, and snippets.

@aneury1
Created November 3, 2017 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aneury1/388b20f0f24c0f5b7af09d5203f85cd4 to your computer and use it in GitHub Desktop.
Save aneury1/388b20f0f24c0f5b7af09d5203f85cd4 to your computer and use it in GitHub Desktop.
#include <SDL2/SDL.h>
#include <fstream>
#include <string.h>
#include <string>
#include <iostream>
SDL_Window *window;
SDL_Renderer *render;
bool run;
void init()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_CreateWindowAndRenderer(800,680,SDL_WINDOW_SHOWN|SDL_WINDOW_FULLSCREEN,&window, &render);
run = render != NULL;
}
enum {
NONE=0, GREEN , RED, BLUE, YELLOW
};
bool checkCollision( SDL_Rect a, SDL_Rect b );
int current_selection = GREEN;
#include <vector>
void draw_t(std::vector<SDL_Rect *> rect, SDL_Color color, bool filled = true)
{
if(rect.size()>0)
{
for(unsigned int i =0;i<rect.size();i++)
{
SDL_SetRenderDrawColor(render, color.r,color.g,color.b,color.a);
SDL_Rect *ptr = rect[i];
(filled == true)?SDL_RenderFillRect(render, ptr):SDL_RenderDrawRect(render, ptr);
}
}
}
struct grids
{
SDL_Rect *rect;
int selected;
grids(SDL_Rect *ptr, int slctd =NONE ):rect(ptr), selected(slctd)
{}
};
std::vector<grids *>generated_grids(int w, int h, int tilesize=30)
{
std::vector<grids *>ret;
for(int row =0; row < h/tilesize; row++)
{
for(int col=0;col < w/tilesize;col++)
{
SDL_Rect *rect = new SDL_Rect;
rect->x = col * tilesize;
rect->y = row * tilesize;
rect->w = tilesize;
rect->h = tilesize;
grids *temp = new grids(rect, NONE);
ret.push_back(temp);
}
}
return ret;
}
int dummy(){return NONE;}
void draw_grids(std::vector<grids *> rgrid)
{
if(rgrid.size()>0)
{
for(unsigned int i =0;i<rgrid.size();i++)
{
if(rgrid[i]->selected != NONE)
{
SDL_Rect *r = rgrid[i]->rect;
///NONE=0, GREEN , RED, BLUE, YELLOW
(rgrid[i]->selected == GREEN ) ? SDL_SetRenderDrawColor(render, 0x00, 255,0,0):dummy();
(rgrid[i]->selected == RED ) ? SDL_SetRenderDrawColor(render, 0xFF, 0,0,0):dummy();
(rgrid[i]->selected == BLUE ) ? SDL_SetRenderDrawColor(render, 0, 0,0XFF,0):dummy();
(rgrid[i]->selected == YELLOW ) ? SDL_SetRenderDrawColor(render, 0xFF, 0XFF,0,0):dummy();
SDL_RenderFillRect(render, const_cast<const SDL_Rect *>(r));
}
else
{
SDL_Rect *r = rgrid[i]->rect;
SDL_SetRenderDrawColor(render, 0xff,0,0,0xff);
SDL_RenderDrawRect(render, const_cast<const SDL_Rect *>(r));
}
}
}
}
void check_grids(std::vector<grids *>& ref, int x, int y, int tilesize)
{
for(unsigned int i=0; i<ref.size();i++)
{
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = tilesize;
rect.h = tilesize;
SDL_Rect *ptr = ref[i]->rect;
if(checkCollision( rect, *ptr ) == true)
{
ref[i]->selected = current_selection;
}
}
}
bool checkCollision( SDL_Rect a, SDL_Rect b )
{
//The sides of the rectangles
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;
//Calculate the sides of rect A
leftA = a.x;
rightA = a.x + a.w;
topA = a.y;
bottomA = a.y + a.h;
//Calculate the sides of rect B
leftB = b.x;
rightB = b.x + b.w;
topB = b.y;
bottomB = b.y + b.h;
//If any of the sides from A are outside of B
if( bottomA <= topB )
{
return false;
}
if( topA >= bottomB )
{
return false;
}
if( rightA <= leftB )
{
return false;
}
if( leftA >= rightB )
{
return false;
}
//If none of the sides from A are outside B
return true;
}
int main(int argc, char *argv[])
{
init();
int tilesize = 48;
std::vector<SDL_Rect *> tileset;
std::vector<grids *> grids;
grids = generated_grids(1200,480,tilesize);
while(run)
{
SDL_Event ev;
while(SDL_PollEvent(&ev))
{
if(ev.type ==SDL_QUIT)
{
std::cout <<"Alguien esta jugando con fuego";
run =false;
}
if(ev.key.keysym.sym == SDLK_q && ev.key.repeat != SDL_TRUE)
{
std::cout <<"Aqui";
run = false;
}
const Uint8 *key = SDL_GetKeyboardState(NULL);
if(key[SDL_SCANCODE_A])
{
///NONE=0, GREEN , RED, BLUE, YELLOW
current_selection =GREEN;
}
if(key[SDL_SCANCODE_S])
{
///NONE=0, GREEN , RED, BLUE, YELLOW
current_selection =RED;
}
if(key[SDL_SCANCODE_D])
{
///NONE=0, GREEN , RED, BLUE, YELLOW
current_selection =BLUE;
}
if(key[SDL_SCANCODE_F])
{
///NONE=0, GREEN , RED, BLUE, YELLOW
current_selection =YELLOW;
}
if(ev.type == SDL_MOUSEBUTTONDOWN)
{
int x,y;
SDL_GetMouseState(&x, &y);
/* SDL_Rect *rect= new SDL_Rect;
rect->x = x - 15;
rect->y = y - 15;
rect->w = 30;
rect->h = 30;
tileset.push_back(rect);*/
check_grids(grids, x, y, 1);
}
}
SDL_SetRenderDrawColor(render, 0,0,0,0xff);
SDL_RenderClear(render);
draw_grids(grids);
SDL_RenderPresent(render);
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(render);
SDL_Quit();
return 0;
}
struct Tile
{
SDL_Rect offset;
int type;
void draw()
{
if(type == 1)
SDL_SetRenderDrawColor(render, 255,255,255,255);
if(type == 3)
SDL_SetRenderDrawColor(render, 255,0,0,255);
SDL_RenderFillRect(render, &offset);
}
};
struct Tilemap
{
std::string tileset;
Tile *tiles;
int tile_quantity;
int w, h;
void draw()
{
for(int i =0; i< tile_quantity;i++)
tiles[i].draw();
}
~Tilemap()
{
std::cout <<"Destructor Invoket";
if(tiles != NULL)
delete []tiles;
tiles = NULL;
}
};
void load_text_tiles(const char *tilename, Tilemap *tilemap);
bool build_bin_map(const char *filename, Tilemap *buffer);
void load_text_tiles(const char *tilename, Tilemap *tilemap)
{
if(tilename!=NULL)
{
std::ifstream fs(tilename);
if(fs.is_open())
{
std::getline(fs,tilemap->tileset);
fs>>tilemap->w;
fs>>tilemap->h;
std::cout <<"---------------------------------------------"<<std::endl
<< "Tileset name "<< tilemap->tileset
<< "Tile map width"<< tilemap->w <<" Tilemap Height "<< tilemap->h <<std::endl;
if(tilemap->tiles != NULL)
delete []tilemap->tiles;
tilemap->tile_quantity = tilemap->w * tilemap->h;
tilemap->tiles = new Tile[tilemap->tile_quantity];
int idx = 0;
int type=-1 , x=0, y=0;
for(int i=0; i < tilemap->tile_quantity; ++i)
{
fs >> type;
if(fs.fail())
{
break;
}
tilemap->tiles[idx].offset.x = x;
tilemap->tiles[idx].offset.y = y;
tilemap->tiles[idx].offset.w = 30;
tilemap->tiles[idx].offset.h = 30;
tilemap->tiles[idx].type = type;
///std::cout <<"index "<< idx << " type " << tilemap->tiles[idx].type<<std::endl;
if(x >= tilemap->w*30)
{
y+=32;
x =0;
}
else
{
x+=32;
}
++idx;
}
fs.close();
}
}
}
bool build_bin_map(const char *filename, Tilemap *buffer)
{
std::ofstream fs(filename, std::ios::out|std::ios::binary);
if(fs.is_open())
{
struct pff_iter {
char tileset[256];
int quantity, w,h;
};
pff_iter obj;
obj.quantity = 0;
obj.h =0;
obj.w =0;
memset(obj.tileset, 0x00, 255);
strncpy(obj.tileset, buffer->tileset.c_str(), buffer->tileset.size());
obj.quantity = buffer->tile_quantity;
obj.w = buffer->w;
obj.h = buffer->h;
const char *signature = "ABINMAPV-1";
fs.write(signature, strlen(signature));
fs.write("\n\n", 2);
fs.write(reinterpret_cast<char *>(&obj), sizeof(obj));
const char *tile_beg="<TILES_BUFFER_BEG>";
const char *tile_end="<TILES_BUFFER_END>";
fs.write(tile_beg, strlen(tile_beg));
fs.write("\n\n", 2);
fs.write("@", 1);
for(int i=0;i<buffer->tile_quantity;i++)
fs.write((char *)buffer[i].tiles, sizeof(buffer[i].tiles));
fs.write(tile_end, strlen(tile_beg));
fs.write("\n\n", 2);
fs.write("@", 1);
fs.close();
std::cout <<"Map succefully created.";
return true;
}
return false;
}
@aneury1
Copy link
Author

aneury1 commented Nov 3, 2017

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include
#include <string.h>
#include
#include
#include
#include

enum
{
NONE=0, GREEN , RED, BLUE, YELLOW
};
const static int tilesize = 32;
SDL_Window *window;
SDL_Renderer *render;
SDL_Texture * global_tileset;
SDL_Rect * clipset_selected;
bool tile_selection= false;
bool run;
int current_selection = GREEN;
SDL_Rect current_image_offset;
std::vector<SDL_Rect *>grid_tileset;

bool checkCollision( SDL_Rect a, SDL_Rect b );
std::vector<SDL_Rect*> create_rect_grids_from_texture(SDL_Texture *texture, int tilesize);

struct grids
{
SDL_Rect *rect;
int selected;
SDL_Rect tile_set;
bool tile;
grids(SDL_Rect *ptr, int slctd =NONE ):rect(ptr), selected(slctd),tile(false)
{}
};

void save_grids_on_files(std::vector<grids *>grids, const char *filename)
{
std::ofstream fs(filename, std::ios::out|std::ios::trunc);
if(fs.is_open())
{
fs << "\n";
fs << "<map version="1.0">";
fs << "\t\t\n";
for(int i =0; i<grids.size(); i++)
{
std::stringstream file_struct;
file_struct <<"\t\t\t<tile type=""<< grids[i]->selected<<"" offset_x=""<<grids[i]->rect->x<<"" offset_y=""<<grids[i]->rect->y<<"" tilesize=""<<tilesize<<""/>\n";
fs << file_struct.str();
}
fs << "\t\t\n";
fs << "\t\n";
fs.flush();
fs.close();
}
}

SDL_Rect* offset_touched(std::vector<SDL_Rect >rect, int x, int y, int tilesize)
{
SDL_Rect
ret=NULL;
for(unsigned int i=0; i<rect.size();i++)
{
SDL_Rect *ptr = rect[i];
SDL_Rect test;
test.x = x;
test.y = y;
test.w = tilesize;
test.h = tilesize;
if(checkCollision(*ptr, test ))
{
ret = new SDL_Rect;
ret->x = ptr->x;
ret->y = ptr->y;
ret->w = ptr->w;
ret->h = ptr->h;
break;
}
}
return ret;
}

void init()
{
SDL_Init(SDL_INIT_EVERYTHING);
IMG_Init(IMG_INIT_PNG);
SDL_CreateWindowAndRenderer(800,680,SDL_WINDOW_SHOWN|SDL_WINDOW_FULLSCREEN,&window, &render);
run = render != NULL;
global_tileset = IMG_LoadTexture(render, "C:\Users\aperez\Desktop\best-resume-ever-master\mountain_landscape.png");
tile_selection= false;
grid_tileset = create_rect_grids_from_texture(global_tileset , tilesize);
}

void draw_t(std::vector<SDL_Rect *> rect, SDL_Color color, bool filled = true)
{
if(rect.size()>0)
{
for(unsigned int i =0;i<rect.size();i++)
{
SDL_SetRenderDrawColor(render, color.r,color.g,color.b,color.a);
SDL_Rect *ptr = rect[i];
(filled == true)?SDL_RenderFillRect(render, ptr):SDL_RenderDrawRect(render, ptr);
}
}
}

std::vector<SDL_Rect*> create_rect_grids_from_texture(SDL_Texture texture, int tilesize)
{
std::vector<SDL_Rect >ret;
if(texture != NULL)
{
int w; int h;
SDL_QueryTexture(texture, NULL, NULL, &w, &h);
for(int row=0; row
tilesize <h; row++)
{
for(int col=0; col
tilesize<w; col++)
{
SDL_Rect *rect= new SDL_Rect;
rect->x = col * tilesize;
rect->y = row * tilesize;
rect->w = tilesize;
rect->h = tilesize;
ret.push_back(rect);
}
}
}
return ret;
}

std::vector<grids *>generated_grids(int w, int h, int tilesize=30)
{
std::vector<grids *>ret;

for(int row =0; row < h/tilesize; row++)
{
	for(int col=0;col < w/tilesize;col++)
	{
	    SDL_Rect *rect = new SDL_Rect;
	    rect->x = col * tilesize;
	    rect->y = row * tilesize;
	    rect->w = tilesize;
	    rect->h = tilesize;
		grids *temp = new grids(rect, NONE);
		ret.push_back(temp);
	}
}
return ret;

}

int dummy(){return NONE;}

void draw_grids(std::vector<grids *> rgrid)
{
if(rgrid.size()>0)
{
for(unsigned int i =0;i<rgrid.size();i++)
{
if(rgrid[i]->selected != NONE)
{
SDL_Rect *r = rgrid[i]->rect;

         if(rgrid[i]->tile == false)
         {
    	    (rgrid[i]->selected == GREEN ) ? SDL_SetRenderDrawColor(render, 0x00, 255,0,0):dummy();
            (rgrid[i]->selected == RED ) ? SDL_SetRenderDrawColor(render, 0xFF, 0,0,0):dummy();
            (rgrid[i]->selected == BLUE ) ? SDL_SetRenderDrawColor(render, 0, 0,0XFF,0):dummy();
            (rgrid[i]->selected == YELLOW ) ? SDL_SetRenderDrawColor(render, 0xFF, 0XFF,0,0):dummy();
            SDL_RenderFillRect(render, const_cast<const SDL_Rect *>(r));
         }
         else
         {
        	 SDL_Rect *r = rgrid[i]->rect;
        	 const SDL_Rect *c = ::clipset_selected;
        	 if(global_tileset!=NULL)
        	   SDL_RenderCopy(render,global_tileset,&rgrid[i]->tile_set,r);

         }
       }
       else
       {
    	   SDL_Rect *r = rgrid[i]->rect;
    	   SDL_SetRenderDrawColor(render, 0xff,0,0,0xff);
    	   SDL_RenderDrawRect(render, const_cast<const SDL_Rect *>(r));
       }
   }

}
}

void check_grids(std::vector<grids *>& ref, int x, int y, int tilesize)
{
for(unsigned int i=0; i<ref.size();i++)
{
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = tilesize;
rect.h = tilesize;
SDL_Rect *ptr = ref[i]->rect;
if(checkCollision( rect, ptr ) == true)
{
ref[i]->selected = current_selection;
if(::clipset_selected != NULL)
{
ref[i]->tile=true;
ref[i]->tile_set =
::clipset_selected;
}
}
}
}

bool checkCollision( SDL_Rect a, SDL_Rect b )
{
//The sides of the rectangles
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;

//Calculate the sides of rect A
leftA = a.x;
rightA = a.x + a.w;
topA = a.y;
bottomA = a.y + a.h;

//Calculate the sides of rect B
leftB = b.x;
rightB = b.x + b.w;
topB = b.y;
bottomB = b.y + b.h;
//If any of the sides from A are outside of B
    if( bottomA <= topB )
    {
        return false;
    }

    if( topA >= bottomB )
    {
        return false;
    }

    if( rightA <= leftB )
    {
        return false;
    }

    if( leftA >= rightB )
    {
        return false;
    }

    //If none of the sides from A are outside B
    return true;

}
int main(int argc, char *argv[])
{

init();

std::vector<SDL_Rect *> tileset;
std::vector<grids *> grids;
grids = generated_grids(480,480,tilesize);

while(run)
{
SDL_Event ev;
while(SDL_PollEvent(&ev))
{
if(ev.type ==SDL_QUIT)
{
std::cout <<"Alguien esta jugando con fuego";
run =false;
}

	  const Uint8 *key = SDL_GetKeyboardState(NULL);

	  if(key[SDL_SCANCODE_ESCAPE])
	  {
		  run = false;
	  }
	  if(key[SDL_SCANCODE_A])
	  {
		  ///NONE=0, GREEN , RED, BLUE, YELLOW
		  current_selection =GREEN;
	  }
	  if(key[SDL_SCANCODE_S])
	  {
		  ///NONE=0, GREEN , RED, BLUE, YELLOW
		  current_selection =RED;
	  }
	  if(key[SDL_SCANCODE_D])
	  {
		  ///NONE=0, GREEN , RED, BLUE, YELLOW
		  current_selection =BLUE;
	  }
	  if(key[SDL_SCANCODE_F])
	  {
		  ///NONE=0, GREEN , RED, BLUE, YELLOW
		  current_selection =YELLOW;
	  }

	  if(key[SDL_SCANCODE_P])
	  {
	     tile_selection = true;
	  }
	  if(key[SDL_SCANCODE_L])
	  {
	     tile_selection = false;
	  }



	  if(ev.type ==  SDL_MOUSEBUTTONDOWN)
	  {
		  int x,y;
		  SDL_GetMouseState(&x, &y);
		 /* SDL_Rect *rect= new SDL_Rect;
		  rect->x = x - 15;
		  rect->y = y - 15;
		  rect->w = 30;
		  rect->h = 30;
		  tileset.push_back(rect);*/

		  if(tile_selection==true)
		  {
			  clipset_selected =offset_touched( grid_tileset ,  x, y, 1);
		  }
		  check_grids(grids, x, y, 1);



	  }


  }
  SDL_SetRenderDrawColor(render, 0,0,0,0xff);
  SDL_RenderClear(render);
  if(::tile_selection == false)
  {
	  draw_grids(grids);
  }
  else
  {
	  SDL_Rect first_;
	  first_.x = 0;
	  first_.y = 0;
	  first_.w = 512;
	  first_.h = 512;
	  SDL_RenderCopy(render, ::global_tileset, NULL, &first_);
	  SDL_Color yellow ;
	  yellow.r =0xff;
	  yellow.g =0xff;
	  yellow.b =0;
	  yellow.a =0xff;
	  draw_t(::grid_tileset, yellow, false);
  }

  SDL_RenderPresent(render);

}

save_grids_on_files( grids, "C:\Users\aperez\Desktop\testmap.xml");

SDL_DestroyWindow(window);
SDL_DestroyRenderer(render);
SDL_Quit();
return 0;
}

struct Tile
{
SDL_Rect offset;
int type;
void draw()
{
if(type == 1)
SDL_SetRenderDrawColor(render, 255,255,255,255);
if(type == 3)
SDL_SetRenderDrawColor(render, 255,0,0,255);
SDL_RenderFillRect(render, &offset);
}

};

struct Tilemap
{
std::string tileset;
Tile *tiles;
int tile_quantity;
int w, h;

void draw()
{
	for(int i =0; i< tile_quantity;i++)
			tiles[i].draw();
}

~Tilemap()
{
std::cout <<"Destructor Invoket";
if(tiles != NULL)
delete []tiles;
tiles = NULL;
}

};

void load_text_tiles(const char *tilename, Tilemap *tilemap);
bool build_bin_map(const char *filename, Tilemap *buffer);
void load_text_tiles(const char *tilename, Tilemap *tilemap)
{
if(tilename!=NULL)
{
std::ifstream fs(tilename);
if(fs.is_open())
{
std::getline(fs,tilemap->tileset);
fs>>tilemap->w;
fs>>tilemap->h;
std::cout <<"---------------------------------------------"<<std::endl
<< "Tileset name "<< tilemap->tileset
<< "Tile map width"<< tilemap->w <<" Tilemap Height "<< tilemap->h <<std::endl;
if(tilemap->tiles != NULL)
delete []tilemap->tiles;
tilemap->tile_quantity = tilemap->w * tilemap->h;
tilemap->tiles = new Tile[tilemap->tile_quantity];

    	int idx = 0;
        int type=-1 , x=0, y=0;
        for(int i=0; i < tilemap->tile_quantity; ++i)
        {
        	fs >> type;
        	if(fs.fail())
        	{
        		break;
        	}
        	tilemap->tiles[idx].offset.x = x;
        	tilemap->tiles[idx].offset.y = y;
        	tilemap->tiles[idx].offset.w = 30;
        	tilemap->tiles[idx].offset.h = 30;
        	tilemap->tiles[idx].type     = type;

        	///std::cout <<"index "<< idx << "  type " << tilemap->tiles[idx].type<<std::endl;
        	if(x >= tilemap->w*30)
        	{
        		y+=32;
        		x =0;
        	}
        	else
        	{
        		x+=32;
        	}
        	++idx;
        }
    	 fs.close();
    }
}

}

bool build_bin_map(const char *filename, Tilemap *buffer)
{
std::ofstream fs(filename, std::ios::out|std::ios::binary);
if(fs.is_open())
{
struct pff_iter {
char tileset[256];
int quantity, w,h;
};

	pff_iter obj;
	obj.quantity = 0;
	obj.h =0;
	obj.w =0;
    memset(obj.tileset, 0x00, 255);
	strncpy(obj.tileset, buffer->tileset.c_str(), buffer->tileset.size());
	obj.quantity = buffer->tile_quantity;
	obj.w = buffer->w;
	obj.h = buffer->h;
	const char *signature = "ABINMAPV-1";
	fs.write(signature, strlen(signature));
    fs.write("\n\n", 2);
    fs.write(reinterpret_cast<char *>(&obj), sizeof(obj));
    const char *tile_beg="<TILES_BUFFER_BEG>";
    const char *tile_end="<TILES_BUFFER_END>";
    fs.write(tile_beg, strlen(tile_beg));
    fs.write("\n\n", 2);
    fs.write("@", 1);
    for(int i=0;i<buffer->tile_quantity;i++)
    	fs.write((char *)buffer[i].tiles, sizeof(buffer[i].tiles));
    fs.write(tile_end, strlen(tile_beg));
    fs.write("\n\n", 2);
    fs.write("@", 1);
    fs.close();
    std::cout <<"Map succefully created.";
    return true;
}
return false;

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment