/****************************************************************************** * File - tile_map.h * Author - Joey Pollack * Date - 2022/02/15 (y/m/d) * Mod Date - 2022/02/15 (y/m/d) * Description - Contains a single tile map ******************************************************************************/ #include "tile_map.h" #include "tile_set.h" #include #include #include #include namespace lunarium { namespace editor { TileMap::TileMap(Sizei tile_size) : mpMap(nullptr), mTileSize(tile_size), mIsDirty(false) { } OpRes TileMap::AddTileSet(int id, TileSet* set) { if (mTileSets.find(id) != mTileSets.end()) { return OpRes::Fail("Cannot add tile set to Tile Map - Tile Set with id: %d already exists", id); } if (set->GetTileSize() != mTileSize) { return OpRes::Fail("Cannot add tile set to Tile Map - Tile size does not match"); } mTileSets[id] = set; return OpRes::OK(); } // NOTE: This could probably be replaced with code that marks it clean on save // since this class will have to implement saving to a file (because it's an asset). void TileMap::MarkClean() { mIsDirty = false; } bool TileMap::IsDirty() const { return mIsDirty; } void TileMap::ClearMap() { for(int i = 0; i < mSizeInTiles.Width; i++) { for (int j = 0; j < mSizeInTiles.Height; j++) { mpMap[i][j] = { -1, {-1, -1} }; } } mIsDirty = true; } void TileMap::SetTile(TileRef tile, Vec2i location) { if (location.X < 0 || location.X >= mSizeInTiles.Width || location.Y < 0 || location.Y >= mSizeInTiles.Height) { return; } mpMap[location.X][location.Y] = tile; mIsDirty = true; } TileRef TileMap::GetTile(Vec2i location) { if (location.X < 0 || location.X >= mSizeInTiles.Width || location.Y < 0 || location.Y >= mSizeInTiles.Height) { return {-1, {-1, -1 }}; } TileRef tile = mpMap[location.X][location.Y]; // Make sure the tileset exists if (mTileSets.find(tile.TileSetID) == mTileSets.end()) { return {-1, {-1, -1 }}; } return tile; } Sizei TileMap::GetSizeInTiles() { return mSizeInTiles; } Sizei TileMap::GetSizeInPixels() { if (!mpMap) return { 0, 0 }; return { mTileSize.Width * mSizeInTiles.Width, mTileSize.Height * mSizeInTiles.Height }; } Sizei TileMap::GetTileSize() { return mTileSize; } void TileMap::ResizeMap(Sizei size) { TileRef** new_map = new TileRef*[size.Width]; for(int i = 0; i < size.Width; i++) { new_map[i] = new TileRef[size.Height]; } int smaller_width = mSizeInTiles.Width < size.Width ? mSizeInTiles.Width : size.Width; int smaller_height = mSizeInTiles.Height < size.Height ? mSizeInTiles.Height : size.Height; for(int i = 0; i < smaller_width; i++) { for (int j = 0; j < smaller_height; j++) { new_map[i][j] = mpMap[i][j]; } } for(int i = 0; i < mSizeInTiles.Width; i++) { delete[] mpMap[i]; } delete[] mpMap; mSizeInTiles = size; mpMap = new_map; mIsDirty = true; } void TileMap::Render(lunarium::Renderer2D* g) { if (!mpMap) return; Sizei map_size_pixels = { mTileSize.Width * mSizeInTiles.Width, mTileSize.Height * mSizeInTiles.Height }; // Draw Map for (int i = 0; i < mSizeInTiles.Width; i++) { for (int j = 0; j < mSizeInTiles.Height; j++) { // If there is no tile here skip this spot if (mpMap[i][j].TileIndex.X == -1 || mpMap[i][j].TileIndex.Y == -1) continue; int id = mpMap[i][j].TileSetID; // -1 means an intentionally empty tile if (-1 == id) { continue; } // Make sure the tileset exists if (mTileSets.find(id) == mTileSets.end()) { Logger::Warn(Editor::LogCat, "Tile Map is missing tile set. No Tile Set with id: %d", id); continue; } TileSet* set = mTileSets[id]; Rectangle dest = Rectangle::MakeFromTopLeft(i * mTileSize.Width, j * mTileSize.Height, mTileSize.Width, mTileSize.Height); Rectangle src = set->GetTileRect(mpMap[i][j].TileIndex); //g->DrawImage(*set->GetImage(), src, dest, Color::White()); // DEBUG //g->DrawImage(*set->GetImage(), glm::vec2(dest.left(), dest.top()), Color::White()); //g->DrawImage(*set->GetImage(), Rectangle::MakeFromTopLeft(0, 0, 1024, 1024), dest, Color::White()); //g->DrawImage(*set->GetImage(), Rectangle::MakeFromTopLeft(16, 0, 16, 16), Rectangle::MakeFromTopLeft(0, 0, 500, 500), Color::White()); } } // Draw grid // for (int i = 0; i < mSizeInTiles.Width; i++) // { // g->DrawLine(glm::vec2(i * mTileSize.Width, 0), glm::vec2(i * mTileSize.Width, map_size_pixels.Height), Color::Black(), 1.0f); // } // g->DrawLine(glm::vec2(map_size_pixels.Width, 0), glm::vec2(map_size_pixels.Width, map_size_pixels.Height), Color::Black(), 1.0f); // for (int j = 0; j < mSizeInTiles.Height; j++) // { // g->DrawLine(glm::vec2(0, j * mTileSize.Height), glm::vec2(map_size_pixels.Width, j * mTileSize.Height), Color::Black(), 1.0f); // } // g->DrawLine(glm::vec2(0, map_size_pixels.Height), glm::vec2(map_size_pixels.Width, map_size_pixels.Height), Color::Black(), 1.0f); } }}