C++ Creating & Drawing a Map

From TRCCompSci - AQA Computer Science
Jump to: navigation, search

Tileset & Map

You will need to declare a texture and use it to load in a tile sheet.

Then you can create a list of integers to identify the tile to display for each tile position.

        sf::Texture tileset;
		//this tile set is 14 x 14 tiles
		//each tile is 32 x 32
		tileset.loadFromFile("tileset.png"); 

		
		// this is a list, it is not a 2d structure
		// this is 10 x 10, 100 in total, each is a tile number
		vector<int> map{ 
			0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
			0, 0, 0, 0, 0, 0, 37, 37, 0, 0, 
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
			0, 0, 21, 21, 21, 0, 0, 0, 0, 0, 
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
		};

This tile set is 14 tiles by 14 tiles, so tile 16 will not be on the first row. This will be on the second row in position 3.

Drawing the map

We will need to know the size of the map declared above, and also the pixel dimensions of a single tile. Remember the 'map' structure is not 2d so we need a 'count' to cycle through each element.

So in between 'window.clear()' and 'window.display()' you need the following code:

		window.clear();
		int count = 0; // used to access the list
		for (int y = 0; y < 10; y++) 
		{
			for (int x = 0; x < 10; x++)
			{
				if (map[count] != 0) // 0 in the map represents no tile
				{
					int tx = map[count] % 14; // remainder should be the tilesheet column
					int ty = map[count] / 14; // integer division would give tilesheet row
					sf::Sprite tile{ tileset }; // create a tile
					tile.setTextureRect({ tx * 32, ty *32, 32, 32 }); // set the tile rectangle
					tile.setPosition({ x*32.f,y*32.f }); // set the tile position
					window.draw(tile); // draw the tile
				}
				count++;
			}
		}
		
		window.display();

This could be improved by also declaring:

int map_rows = 10;
int map_cols = 10;
int tile_rows = 14;
int tile_width = 32;
int tile_height = 32;

You can now change the code to use these new variables:

		window.clear();
		int count = 0; // used to access the list
		for (int y = 0; y < map_rows; y++) 
		{
			for (int x = 0; x < map_cols; x++)
			{
				if (map[count] != 0) // 0 in the map represents no tile
				{
					int tx = map[count] % tile_rows; // remainder should be the tilesheet column
					int ty = map[count] / tile_rows; // integer division would give tilesheet row
					sf::Sprite tile{ tileset }; // create a tile
					tile.setTextureRect({ tx * tile_width, ty *tile_height, tile_width, tile_height }); // set the tile rectangle
					tile.setPosition({(float)( x*tile_width),(float)(y*tile_height) }); //needs casting to float
					window.draw(tile); // draw the tile
				}
				count++;
			}
		}
		
		window.display();