178 lines
5.9 KiB
C++
178 lines
5.9 KiB
C++
/// Redacted Software 2D Level Library
|
|
/// Level File Format Specification
|
|
///
|
|
#pragma once
|
|
|
|
#include <vector>
|
|
#include <json.hpp>
|
|
#include <filesystem>
|
|
#include <format>
|
|
#include <Re2DLevelAPI.hpp>
|
|
#include <J3ML/Geometry/AABB2D.hpp>
|
|
|
|
|
|
/// Represents a rectangular sub-region of a larger space, such as a texture.
|
|
/// @see J2D::DrawPartialSprite();
|
|
struct Quad {
|
|
int x; int y;
|
|
int w; int h;
|
|
#ifdef QUAD_EXTENDED_API
|
|
Vector2i Position() const { return {x, y};}
|
|
Vector2i Size() const { return {w, h};}
|
|
void Position(const Vector2i& value) { x = value.x; y = value.y; }
|
|
void Size(const Vector2i& value) { w = value.x; h = value.y; }
|
|
void Set(AABB2D& rect) { }
|
|
|
|
|
|
Quad Translated(const Vector2i& translation) {
|
|
Quad copy;
|
|
}
|
|
|
|
void Translate(const Vector2i& translation) {
|
|
x += translation.x;
|
|
y += translation.y;
|
|
}
|
|
#endif
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct Tile
|
|
{
|
|
int id;
|
|
std::string name;
|
|
/// The portion of the Tilesheet that corresponds to this tile-object.
|
|
/// @note Non-uniform tile width and height are technically possible, but not generally designed for.\n
|
|
/// The quad.w, quad.h should match the Tileset.tile_width, and Tileseh.tile_height.
|
|
Quad quad;
|
|
json::value metadata;
|
|
bool collides;
|
|
|
|
bool persistent = false;
|
|
};
|
|
|
|
|
|
/// @class Tileset
|
|
/// @brief Represents a collection of tiles, typically from a single texture atlas, used in a level.
|
|
///
|
|
/// The Tileset class defines the properties of a set of tiles, including their dimensions,
|
|
/// spacing, and how they are arranged within a source texture. It also provides metadata
|
|
/// about the tileset itself, such as its name and author.
|
|
///
|
|
/// @note As a space-saving measure, tiles are only saved to file if they contain non-generic metadata, or a custom name or ID. Otherwise, tiles are simply generated in incrementing order at runtime.
|
|
///
|
|
class Tileset {
|
|
public:
|
|
#pragma region json fields
|
|
/// The unique name of the tileset.
|
|
std::string name;
|
|
/// The author or creator of the tileset.
|
|
std::string author;
|
|
/// The file path of this tileset.
|
|
std::string file_path;
|
|
/// The file path to the source texture atlas image for this tileset.
|
|
/// @note This path is typically relative to the lvel's JSON file.
|
|
std::string texture_path;
|
|
|
|
/// The width of a single tile in pixels within this tileset.
|
|
int tile_width;
|
|
// The height of a single tile in pixels within this tileset.
|
|
int tile_height;
|
|
/// The spacing in pixels between individual tiles within the texture atlas.
|
|
/// @note This is useful if tiles are not tightly packed.
|
|
int tile_spacing;
|
|
/// The total width of the source texture atlas image in pixels.
|
|
int tex_width;
|
|
/// The total height of the source texture atlas image in pixels.
|
|
int tex_height;
|
|
/// The number of full rows of tiles in the texture atlast.
|
|
int rows;
|
|
/// The number of full columns of tiles in the texture atlast.
|
|
/// @note This might be redundant if `tiles_per_row` and `tile_count` are used.
|
|
int cols;
|
|
|
|
std::vector<Tile> tiles;
|
|
#pragma endregion
|
|
#pragma region computed fields
|
|
/// The total number of tiles defined in this tileset.
|
|
/// @note This is calculated from `rows * cols` or by iterating
|
|
int tile_count;
|
|
/// The number of tiles that fit horizontally in a single row of the texture atlast, taking into account `tile_width` and `tile_spacing`.
|
|
int tiles_per_row;
|
|
|
|
std::vector<Quad> quads;
|
|
|
|
#pragma endregion
|
|
public:
|
|
|
|
static Tileset Template()
|
|
{
|
|
Tileset tileset;
|
|
|
|
tileset.author = "J. O'Leary";
|
|
tileset.name = "Sample Tileset";
|
|
tileset.file_path = "tileset.json";
|
|
tileset.cols = 50;
|
|
tileset.rows = 64;
|
|
tileset.texture_path = "assets/megacommando.png";
|
|
tileset.tex_width = 1024;
|
|
tileset.tex_height = 800;
|
|
return tileset;
|
|
}
|
|
|
|
/// Default constructor for Tileset .
|
|
/// Initializes member variables to default or zero values.
|
|
/// @see CreateDefault().
|
|
Tileset();
|
|
|
|
/// This constructor is used for the initial definition of a Tileset. i.e. From Editor->Tileset->New
|
|
Tileset(const std::string& name, const std::filesystem::path& texture_path, int tex_width, int tex_height, int tile_width, int tile_height, int tile_spacing);
|
|
|
|
/// Constructs a tileset object by deserializing data from a JSON object.
|
|
explicit Tileset(const json::value& json);
|
|
|
|
/// Loads the Tileset from a file-path containing a json-string.
|
|
explicit Tileset(const std::filesystem::path& filePath);
|
|
|
|
/// Destructor for Tileset - cleans up any held resources.
|
|
~Tileset() = default;
|
|
|
|
/// Deserializes a JSON object into the current Tileset object's data.
|
|
void Deserialize(const json::value& json);
|
|
|
|
/// Serializes the current Tileset object's data into a JSON object.
|
|
/// @return a JJX::json::value object representing the tileset's data.
|
|
json::value Serialize() const;
|
|
|
|
protected:
|
|
|
|
/// Converts a 1D tile index to 2D cell coordinates (row, column) within the tileset grid.
|
|
/// The row and column are 0-based.
|
|
/// @param index The 0-based 1D index of the tile.
|
|
/// @warning If the index is out of bounds, the returned coordinates might be invalid (e.g. negative)
|
|
Vector2i IndexToCell(int index) const;
|
|
|
|
inline int CellToIndex(int cx, int cy) const;
|
|
|
|
/// Fill the tile-id lookup table with their respective partial-sprite bounding boxes.
|
|
void ComputeQuads();
|
|
|
|
void FillTiles() {
|
|
// Generate some tiles
|
|
tiles.reserve(rows*cols);
|
|
tile_count = rows*cols;
|
|
for (int i = 0 ; i < this->rows*this->cols; i++)
|
|
{
|
|
Tile tile;
|
|
tile.id = i;
|
|
tile.quad = quads[i];
|
|
tile.name = std::format("tile_{}", i);
|
|
tile.metadata = json::value();
|
|
tile.collides = true;
|
|
tiles.emplace(tiles.begin() + i, tile);
|
|
}
|
|
}
|
|
}; |