rutile-game/src/rutile/core/resources/tile_set.cppm

89 lines
2.9 KiB
C++

module;
#include <cassert>
export module rutile.core.resources.tile_set;
import std;
import rutile.core.common;
import rutile.core.resources.texture;
import wrappers.sdl;
export namespace rutile
{
using TileSetID = unsigned int;
using TileID = unsigned int;
struct TileDefinition
{
sdl::FRect atlas_src_rect;
};
class TileSet
{
// Shared pointer to the tileset atlas texture (managed by ResourceServer)
ResourcePtr<Texture> texture_ptr_;
// Size of each tile in pixels
// TODO: Do we need this?
// int tile_size_;
// Tile definitions: Maps tile ID to a struct describing the tile, e.g. the texture source boundaries,
// collision data, etc.
std::vector<TileDefinition> tile_definitions_;
public:
TileSet() = delete;
explicit TileSet(
const ResourcePtr<Texture>& texture_ptr,
std::vector<TileDefinition> tile_definitions
)
: texture_ptr_{texture_ptr},
tile_definitions_{std::move(tile_definitions)}
{}
static TileSet create_from_texture(
const ResourcePtr<Texture>& texture_ptr,
const int tile_size,
const std::vector<sdl::Point>& tile_atlas_coords
)
{
assert(tile_size > 0);
// TODO: These probably shouldn't be asserts...
assert(texture_ptr->get_width() % tile_size == 0);
assert(texture_ptr->get_height() % tile_size == 0);
std::vector<TileDefinition> tile_definitions;
// TODO: Should we automatically create tile 0 (no tile) instead of listing it in tile_atlas_coords?
for (const auto& [x, y] : tile_atlas_coords) {
const TileDefinition tile{
{
static_cast<float>(x * tile_size),
static_cast<float>(y * tile_size),
static_cast<float>(tile_size),
static_cast<float>(tile_size),
}
};
// TODO: These probably shouldn't be asserts...
assert(tile.atlas_src_rect.x + tile.atlas_src_rect.w <= texture_ptr->get_width());
assert(tile.atlas_src_rect.y + tile.atlas_src_rect.h <= texture_ptr->get_height());
tile_definitions.push_back(tile);
}
return TileSet(texture_ptr, tile_definitions);
}
constexpr const Texture& get_texture() const
{
return *texture_ptr_;
}
constexpr const TileDefinition& get_tile_definition(const TileID tile_id) const
{
return tile_definitions_.at(tile_id);
}
};
}