Tile maps can now be painted to correctly
parent
60bb47f25e
commit
e4df9cb217
@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
High Importance:
|
High Importance:
|
||||||
☐ The Map Editor does not get the tile maps when a project is opened @high
|
✔ The Map Editor does not get the tile maps when a project is opened @high @done (3/3/2022, 2:47:41 PM)
|
||||||
|
✔ Tile Set IDs (as opposed to the Asset ID) is not saved or loaded yet @high @done (3/11/2022, 2:10:30 PM)
|
||||||
|
✔ Had to flip the V component of the UVs for the sprite vertices. This fixes the partial image drawing but will need to be accounted for in other places in the editor. @done (3/14/2022, 1:46:48 PM)
|
||||||
@ -0,0 +1,200 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* 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 <graphics/graphics.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::IGraphics* 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::Log(Editor::LogCat, LogLevel::WARNING, "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());
|
||||||
|
//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);
|
||||||
|
}
|
||||||
|
}}
|
||||||
@ -1,118 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* 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 <graphics/graphics.h>
|
|
||||||
|
|
||||||
namespace lunarium { namespace editor
|
|
||||||
{
|
|
||||||
|
|
||||||
TileMap::TileMap(std::map<int, TileSet*>* tilesets)
|
|
||||||
: mpTileSets(tilesets), mpMap(nullptr)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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} };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Sizei TileMap::GetSizeInTiles()
|
|
||||||
{
|
|
||||||
return mSizeInTiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sizei TileMap::GetSizeInPixels()
|
|
||||||
{
|
|
||||||
if (!mpMap)
|
|
||||||
return { 0, 0 };
|
|
||||||
|
|
||||||
Sizei tile_size = (*mpTileSets)[mpMap[0][0].TileSetID]->GetTileSize();
|
|
||||||
return { tile_size.Width * mSizeInTiles.Width, tile_size.Height * mSizeInTiles.Height };
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TileMap::Render(lunarium::IGraphics* g)
|
|
||||||
{
|
|
||||||
if (!mpMap)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Check the size of the tiles - each tileset should have the same sized tiles for the same map
|
|
||||||
Sizei tile_size = (*mpTileSets)[mpMap[0][0].TileSetID]->GetTileSize();
|
|
||||||
Sizei map_size_pixels = { tile_size.Width * mSizeInTiles.Width, tile_size.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;
|
|
||||||
|
|
||||||
TileSet* set = (*mpTileSets)[mpMap[i][j].TileSetID];
|
|
||||||
Rectangle dest = Rectangle::MakeFromTopLeft(i * tile_size.Width, j * tile_size.Height, tile_size.Width, tile_size.Height);
|
|
||||||
Rectangle src = set->GetTileRect(mpMap[i][j].TileIndex);
|
|
||||||
|
|
||||||
g->DrawImage(*set->GetImage(), src, dest, Color::White());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw grid
|
|
||||||
for (int i = 0; i < mSizeInTiles.Width; i++)
|
|
||||||
{
|
|
||||||
g->DrawLine(glm::vec2(i * tile_size.Width, 0), glm::vec2(i * tile_size.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 * tile_size.Height), glm::vec2(map_size_pixels.Width, j * tile_size.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);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
Loading…
Reference in New Issue