Cheese Map is a drawable layered tile map for SFML, designed to simplify drawing most 2D maps.
It's also fully header-only so no library compilation needed; simply just include it.
You can create multiple grid map (standard grid tile maps) and place them anywhere in space and Cheese Map will draw them all together. You basically give it the view you want it to fill and it draws the map that is needed to fill that view, automatically culling everything out-of-range.
You can also create layers of individual "free" tiles that are tiles that can be placed anywhere in space with no restraint to a grid. These are likely most useful for separate, individual objects that don't conform to a grid and/or need to be layered in front or behind without having to create another entire grid map in front or behind.
Whether it be a grid or layer, each one can have a z-order depth and is automatically sorted when drawn so you easily decide on the order things are drawn. Each one can also have a depth that offsets it in the 3rd dimension; it projects away from the screen towards the back and follows the rule of the perspective (the vanishing point of the map can be customised). Each one can also have its own colour, be activated (drawn) and de-activated (ignored), and given any offset/position that moves the entire grid/layer.
Each tile's texture can also be transformed: flipped/mirrored/rotated using flipx, flipy, and rotate (90 degrees).
Cheese Map makes it easy to move around by using the view: you can move, scale and rotate the view however you like and Cheese Map adapts. You can think of it as if the entire map is static and your view is your camera that you can aim at it however you want to. Cheese Map doesn't draw stuff it doesn't need outside of the camera/view.
To get started quickly, you can have a look at the
Simple Example that - with very little code - produces this animation:
#include <SFML/Graphics.hpp>
#include <CheeseMap.hpp>
int main()
{
// load the texture
sf::Texture mapTexture;
if (!mapTexture.loadFromFile("resources/16colours(16x16_4x4each).png"))
return EXIT_FAILURE;
// some constants that define the format of the tiles inside the texture
const std::size_t numberOfTilesInTexture{ 16u };
const sf::Vector2<std::size_t> sizeOfTilesInTexture{ 4u, 4u };
const std::size_t numberOfTilesPerRowInTexture{ 4u };
// create the Cheese Map and set its texture
cm::Map map;
map.setTexture(mapTexture);
// set-up the texture atlas to contain all the tiles in the texture
map.textureAtlas.resize(numberOfTilesInTexture);
for (std::size_t i{ 0u }; i < map.textureAtlas.size(); ++i)
map.textureAtlas[i] = { sf::Vector2f(i % numberOfTilesPerRowInTexture * sizeOfTilesInTexture.x, i / numberOfTilesPerRowInTexture * sizeOfTilesInTexture.y), sf::Vector2f(sizeOfTilesInTexture) };
// add a grid map with random tile IDs
map.grids.resize(1u);
const sf::Vector2<std::size_t> sizeOfGridMap{ 50u, 10u };
map.grids[0u].rowWidth = sizeOfGridMap.x;
map.grids[0u].tileSize = { 50.f, 50.f };
map.grids[0u].tileIds.resize(sizeOfGridMap.x * sizeOfGridMap.y);
for (auto& tile : map.grids[0u].tileIds)
tile = rand() % numberOfTilesInTexture; // trivially random, just for an example
// basic window loop
sf::RenderWindow window(sf::VideoMode(960u, 540u), "Cheese Map - simple example 1");
sf::View mapView(window.getDefaultView());
sf::Clock clock;
while (window.isOpen())
{
sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); }
const float time{ clock.getElapsedTime().asSeconds() };
mapView.setCenter({ 500.f + std::cos(time * 2.f) * 200.f, 0.f + std::sin(time * 2.f) * 30.f }); // move the view around based on the time
map.update(mapView);
window.clear();
window.setView(mapView);
window.draw(map);
window.display();
}
}
There are also a couple of videos available that were created of tests during development:
Early Test Demo:
Initial Tests:
EDIT: fixed Simple Example link