Tile Map - Hapaxia/SelbaWard GitHub Wiki
A fully templated class to draw a tile map.
To use Tile Map, a tileset texture and some level data are required. Tile Map automatically uses the correct part of the data based on its "camera" position.
The level data is a collection of values (some type of integer) that specifies which tile image to use in that cell.
If the camera is moved to a position that shows past the extremes of the level data, the tiles that are outside of the level data's range default to a tile position of zero (by default). For this reason, you should be aware of the first tile in your tileset texture. However, you can change this default to use any tile for when there is no level data for that tile.
sw::TileMap<T> tileMap;
creates a Tile Map. The T type specified is the data type used for the level data; this should be an integer type and match the original level data.
This class inherits from sf::Drawable so it is drawn in the same way as all SFML drawables:
window.draw(tileMap);
where window is an sf::RenderWindow.
Note: actually, window could be any [sf::RenderTarget].
This class inherits from sf::Transformable so it has all the usual SFML transformations available.
The level definition should be stored in a supported container or raw memory of type T, which should be an integer type (preferably an unsigned integer type); negative values are not allowed.
-
setLevel()
resets the internal pointer so that it is no longer connected to level data. Note that this also resets the level width to zero. -
setLevel(std::vector<T>& level, std::size_t width)
sets the internal pointer so that it is connected to the level data stored in the passed vector of T. The passed vector is actually const so the original is not modified. If width is omitted, the level width is not changed whereas if it is present, the level width is updated. -
setLevel(std::deque<T>& level, std::size_t width)
sets the internal pointer so that it is connected to the level data stored in the passed deque of T. The passed deque is actually const so the original is not modified. If width is omitted, the level width is not changed whereas if it is present, the level width is updated. -
setLevel(T* level, std::size_t size, std::size_t width)
sets the internal pointer so that it is connected to the level data stored in the raw data pointed to by level. The passed data is const so the original is not modified. The size is required as it specifies the size of the raw data. If width is omitted, the level width is not changed whereas if it is present, the level width is updated. -
setLevelWidth(std::size_t width)
sets the width of the level. This is the amount of data per row of the level. For example, a level with 100 values and a width of 25 would have 4 rows.
-
setSize(sf::Vector2f)
takes an sf::Vector2f that represents the size of the final rendered tile map image. -
setGridSize(sf::Vector2<std::size_t>)
takes an sf::Vector2 with components of type std::size_t that represents the size of the grid used. This represents the number of entire cells that can fit inside the final tile map. -
setOutOfBoundsTile(std::size_t)
takes an std::size_t that represents the number of the tile in the texture to display when there is no level data available for that tile, such as past the edge bounds of the map.
-
setTexture(sf::Texture)
takes an sf::Texture and stores a pointer to it. This means that the texture should exist (at its current memory position) as long as Tile Map requires it. This texture can be changed whenever you like and should be reset if the current texture is moved in memory. You can also use this method to nullify the texture by omitting the parameter. -
setTextureTileSize(sf::Vector2<std::size_t>)
takes an sf::Vector2 with components of type std::size_t that specifies the size of each tile (the section of texture to be shown in each cell). -
setNumberOfTextureTilesPerRow(std::size_t)
takes an std::size_t that informs Tile Map how many texture tiles there are per row in the texture. -
setTextureOffset(sf::Vector2<std::size_t>)
takes an sf::Vector2 with components of type std::size_t that specifies an offset in the texture, which is the top-left of the tile set.
-
setSmooth(bool)
sets whether the final rendered tile map should be smoothed or not. -
setColor(bool)
sets the sf::Color of all the vertices used for the tiles, which allows you to multiple a colour with the textures or use the colour in a shader.
-
setCameraTargetTile(sf::Vector2f)
sets the tile that the camera is targetting. For example, if the target tile is (3.5, 2.5), then the middle of the tile (3, 2) is where the camera's position will be. Continuing with the example, if the camera is at (0, 0), the middle of the tile (3, 2) would be (0, 0) - the top-left of the tile map is the inverse of this value so, in the example just described, the top-left of the tile map would be (-3.5, -2.5). Another example is if the grid is (20, 10), setting the target tile to (10, 5) would mean that the camera position specifies where in the map should be in the centre of the tile map. -
setSmoothScroll(bool)
sets whether to round the camera position to the view's pixel co-ordinates or the internal render texture's. Smooth scrolling allows pixel scrolling at any sized tile map (similar in concept to video stabilization) but may cause slight unwanted effects on the edges of the map. Without smooth scrolling, the camera positions are locked to texture pixels.
-
update()
updates the tiles from the actual level data. This uses the data previously connected to Tile Map using "setLevel". -
setCamera(sf::Vector2f)
sets the "camera" position. The camera is the offset specified as a visual vector e.g. a camera of (25, 10) when the tile size is (10, 10) will mean that the tile map is offset by 2.5 tiles to the right and 1 tile downwards.
-
redraw()
re-renders the tilemap using its current state.
-
getSize()
returns an sf::Vector2f of the current size of the final rendered tile map image. -
getGridSize()
returns an sf::Vector2 with components of type std::size_t of the current grid size (number of entire tiles that fit into the rendered image) -
getTotalGridSize()
returns an std::size_t of the current total grid size (number of entire tiles that fit into the rendered image). This is equivalent to getGridSize().x * getGridSize().y -
getTextureTileSize()
returns an sf::Vector2 with components of type std::size_t representing the size of each tile image within the texture -
getTextureOffset()
returns an sf::Vector2 with components of type std::size_t representing the offset - the position in the texture of the top-left - of the tile set -
getLevelWidth()
returns an std::size_t representing the width of the level in number of data items per row. -
getCamera()
returns the sf::Vector2f representing the current camera position (map offset). SeesetCamera()above for more information -
getCameraTargetTile()
returns the sf::Vector2f representing the current camera target tile. SeesetCameraTargetTile()above for more information -
getSmoothScroll()
gets whether or not smooth scroll is enabled. (see setSmoothScroll above) -
getSmooth()
returns a bool representing whether the final rendered tile map image is smoothed or not -
getColor()
returns the sf::Color that is used to draw the tiles. This multiplies the colour with the texture -
getLevelPositionAtCoord(sf::Vector2f)
returns an sf::Vector2i representing the level position at the specified co-ordinate. This takes into account all transformations -
getTileAtCoord(sf::Vector2f)
returns an std::size_t representing the tile value at the specified co-ordinate. This takes into account all transformations -
getCoordAtLevelGridPosition(sf::Vector2f levelGridPosition)
returns an sf::Vector2f representing the final (transformed) co-ordinate of the specified part of the specified level tile. e.g. (10.5, 3.0) = top-centre of level grid tile at position (10, 3) -
getTileSize()
returns an sf::Vector2f representing the display size of a tile (before transformations)
#include <SFML/Graphics.hpp>
#include <SelbaWard/TileMap.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode({ 288u, 288u }), "Tile Map 2 simple example");
sf::Texture tileMapTexture{};
if (!tileMapTexture.loadFromFile("resources/Simple Tileset.png"))
return EXIT_FAILURE;
std::vector<unsigned char> levelData(10000u); // tile number can be any integer type
for (auto& tile : levelData)
tile = rand() % 4u; // pick one of the four available tiles at "random"
sw::TileMap<unsigned char> tileMap{}; // data type must match type used in level definition data
tileMap.setLevel(levelData); // connect level data
tileMap.setLevelWidth(125u); // width of 125 means that the level data gets processed as if it is 125 x 80
tileMap.setSize({ 288.f, 288.f }); // size of tile map's rendered image
tileMap.setGridSize({ 9u, 9u }); // size of tile map grid (number of tiles)
tileMap.setTexture(tileMapTexture);
tileMap.setNumberOfTextureTilesPerRow(2u);
tileMap.setTextureTileSize({ 32u, 32u }); // actual size of tiles within the texture
tileMap.update();
const float movementAmount{ 0.1f }; // frame-time dependent. use time-based movement for consistent results
while (window.isOpen())
{
while (const auto event{ window.pollEvent() }) if (event->is<sf::Event::Closed>()) window.close();
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Up))
tileMap.setCamera(tileMap.getCamera() + sf::Vector2f(0.f, -movementAmount));
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Down))
tileMap.setCamera(tileMap.getCamera() + sf::Vector2f(0.f, movementAmount));
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Left))
tileMap.setCamera(tileMap.getCamera() + sf::Vector2f(-movementAmount, 0.f));
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Right))
tileMap.setCamera(tileMap.getCamera() + sf::Vector2f(movementAmount, 0.f));
tileMap.update(); // update is only necessary if something changes. we're just updating every frame here to shorten the example
window.clear();
window.draw(tileMap);
window.display();
}
return EXIT_SUCCESS;
}The code above displays:
You can use the arrow keys to move around the map.
Note: the texture for this example is available, along with more examples, in the examples folder, although you can use your own images.
(Tile Map v2.0)
