Jump to content
  • Advertisement
Sign in to follow this  
fragbear

2D randomly generated tile-based map not rendering correctly

This topic is 2406 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I am making a 2D roguelike and I'm doing the rendering of randomly generated tile-based maps with SDL.

I have two classes that my generating function uses from "mapgen.h":
 




extern int worldArray[][50]; //2D map of the world // 0 = space, 1 = solid



extern SDL_Rect tile[];



int generate_map();



class tileTemplate

{

public:



int type;

int xPos;

int yPos;

int tileNo;



tileTemplate();

}extern tileData[];



class dimensionData

{

public:

bool sideOpen[4];

int sideSpace[4];

};

Then I have variables declared in "mapgen.cpp" that are used in the map generating function:


SDL_Rect tile[2];

int worldArray[50][50]; //2D map of the world // 0 = space, 1 = solid

tileTemplate tileData[2500];

dimensionData dimensions;



tileTemplate::tileTemplate()

{

type;

xPos;

yPos;

tileNo;

occupied;

}

Then comes the function which I use to generate my maps, this is still in "mapgen.cpp"


int generate_map()

{

int slot = 0;

int line = 0;



//set the initial information for tiles and world construction

for (int i = 0; i < 2500; i++)

{

tileData[i].tileNo = i;

tileData[i].xPos = slot*96;

tileData[i].yPos = line*96;

tileData[i].occupied = 1;

worldArray[slot][line] = 1;



slot++;

if (slot == 50)



{

slot = 0;

line++;

}

}





int lastGeneratedTileX = genStartPointX;

int lastGeneratedTileY = genStartPointY;

int nextDirection = 0;

int comingDirection = 5;



int amountToGenerate = 0;



for (int s = 0; s < 1000;)

{



//top

if(lastGeneratedTileY == 0)

dimensions.sideOpen[0] = false;

else

dimensions.sideOpen[0] = true;

//right

if(lastGeneratedTileX == 50)

dimensions.sideOpen[1] = false;

else

dimensions.sideOpen[1] = true;

//down

if(lastGeneratedTileY == 50)

dimensions.sideOpen[2] = false;

else

dimensions.sideOpen[2] = true;

//left

if(lastGeneratedTileX == 0)

dimensions.sideOpen[3] = false;

else

dimensions.sideOpen[3] = true;



dimensions.sideSpace[0] = lastGeneratedTileY;

dimensions.sideSpace[1] = (50 - lastGeneratedTileX);

dimensions.sideSpace[2] = (50 - lastGeneratedTileY);

dimensions.sideSpace[3] = lastGeneratedTileX;



do

nextDirection = rand() % 4;

while(dimensions.sideOpen[nextDirection] == false || nextDirection == comingDirection);

comingDirection = nextDirection;

amountToGenerate = rand() % (dimensions.sideSpace[nextDirection]) + 1;

s += amountToGenerate - 1;



switch(nextDirection)

{

case 0:

for(int g = 1; g < amountToGenerate + 1; g++)

worldArray[lastGeneratedTileX][lastGeneratedTileY - g] = 0;

lastGeneratedTileY -= amountToGenerate;

break;

case 1:

for(int g = 1; g < amountToGenerate + 1; g++)

worldArray[lastGeneratedTileX + g][lastGeneratedTileY] = 0;

lastGeneratedTileX += amountToGenerate;

break;

case 2:

for(int g = 1; g < amountToGenerate + 1; g++)

worldArray[lastGeneratedTileX][lastGeneratedTileY + g] = 0;

lastGeneratedTileY += amountToGenerate;

break;

case 3:

for(int g = 1; g < amountToGenerate + 1; g++)

worldArray[lastGeneratedTileX - g][lastGeneratedTileY] = 0;

lastGeneratedTileX -= amountToGenerate;

break;

}

}

slot = 0;

line = 0;

//put the generated areas in game world data

for (int i = 0; i < 2500; i++)

{

tileData[i].type = worldArray[slot][line];

slot++;

if (slot == 50)

{

slot = 0;

line++;

}

}



return 0;

}

So the 2D array representing the game world is first filled with "solid" tiles, then the areas where the player can move are placed into it.
The data from the modified 2D map is then copied to the 2500 tileTemplate instances, which are used to render the map in the main.cpp, like this:
 


int draw_map()

{

int slot = 0;

int line = 0;

SDL_FillRect(screen,NULL,0x000000);



for (int i = 0; i < 2500; i++)

{

apply_surface(slot*96, line*96, tilemap, map, &tile[tileData[i].type]);

slot++;

if (slot == 50)

{

slot = 0;

line++;

}

}

apply_surface(0, 0, map, screen, &camera); //map

apply_surface(0, 0, GUI, screen, NULL); //GUI

SDL_Flip(screen);

return 0;

}

The surface "tilemap" is where all the different tiles are, the surface "map" is where all the tiles are drawn, and then this map surface is drawn to screen surface.

Most of the time all this works as it's supposed to, but sometimes the solid tiles (the ones that have value 1 in 2D map) don't get drawn at all, and you can see the map surface. Sometimes none of the tiles are drawn.

When I tried debugging this everything was seemingly going as it was supposed to, every time. Also even when no tiles are drawn the tileTemplate instances still have the correct values.

I still think the problem is in the map generating function because this didn't happen when I wasn't randomizing the tiles.

I also attached a picture of what the generated map looks like when it works, if it helps.

 

Share this post


Link to post
Share on other sites
Advertisement

if(lastGeneratedTileY == 0)
dimensions.sideOpen[0] = false;
else
dimensions.sideOpen[0] = true;
//right
if(lastGeneratedTileX == 50)
dimensions.sideOpen[1] = false;
else
dimensions.sideOpen[1] = true;
//down
if(lastGeneratedTileY == 50)
dimensions.sideOpen[2] = false;
else
dimensions.sideOpen[2] = true;
//left
if(lastGeneratedTileX == 0)
dimensions.sideOpen[3] = false;
else
dimensions.sideOpen[3] = true;


Either ==0 or ==50 is off by one. Valid indexes are 0 to 49 inclusive.


dimensions.sideSpace[0] = lastGeneratedTileY;
dimensions.sideSpace[1] = (50 - lastGeneratedTileX);
dimensions.sideSpace[2] = (50 - lastGeneratedTileY);
dimensions.sideSpace[3] = lastGeneratedTileX;

50-... is off by one: at row/column 49 there is no "side space", exactly like on row/column 0.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!