You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
6.1 KiB
C++
203 lines
6.1 KiB
C++
/******************************************************************************
|
|
* 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 <core/core.h>
|
|
#include <renderer/renderer2D.h>
|
|
#include <editor/editor.h>
|
|
#include <utils/logger.h>
|
|
|
|
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);
|
|
}
|
|
}}
|