updating tile map
This commit is contained in:
parent
b5bc16afcf
commit
ce07b55c34
12
imgui.ini
12
imgui.ini
@ -27,7 +27,7 @@ DockId=0x00000001,0
|
||||
|
||||
[Window][Viewport]
|
||||
Pos=265,19
|
||||
Size=501,412
|
||||
Size=501,590
|
||||
Collapsed=0
|
||||
DockId=0x00000007,0
|
||||
|
||||
@ -42,14 +42,14 @@ Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Console]
|
||||
Pos=265,433
|
||||
Size=501,287
|
||||
Pos=265,611
|
||||
Size=501,109
|
||||
Collapsed=0
|
||||
DockId=0x00000008,0
|
||||
|
||||
[Window][Tilemap Editor]
|
||||
Pos=265,19
|
||||
Size=1141,869
|
||||
Size=1141,1047
|
||||
Collapsed=0
|
||||
DockId=0x00000007,1
|
||||
|
||||
@ -58,8 +58,8 @@ DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X
|
||||
DockNode ID=0x00000003 Parent=0x11111111 SizeRef=1406,1158 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=263,701 HiddenTabBar=1 Selected=0x12EF0F59
|
||||
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1141,701 Split=Y Selected=0xC450F867
|
||||
DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,869 CentralNode=1 Selected=0xC450F867
|
||||
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,287 HiddenTabBar=1 Selected=0xEA83D666
|
||||
DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,1047 CentralNode=1 Selected=0xC450F867
|
||||
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,109 Selected=0xEA83D666
|
||||
DockNode ID=0x00000004 Parent=0x11111111 SizeRef=512,1158 Split=Y Selected=0x36DC96AB
|
||||
DockNode ID=0x00000005 Parent=0x00000004 SizeRef=407,835 HiddenTabBar=1 Selected=0x36DC96AB
|
||||
DockNode ID=0x00000006 Parent=0x00000004 SizeRef=407,321 HiddenTabBar=1 Selected=0x3FC1A724
|
||||
|
@ -1,2 +1,3 @@
|
||||
[COMPILE] g++ -std=c++20 -Wall -Isrc/include -Isrc/vendor -Isrc/vendor/imgui -IC:/msys64/mingw64/include -Isrc/include -Isrc/vendor -Isrc/vendor/imgui -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\Components\TilemapComponent.cpp -o src\build\src\Components\TilemapComponent.o
|
||||
[LINK] g++ src\build\src\Engine.o src\build\src\main.o src\build\src\Renderer.o src\build\src\Components\CameraComponent.o src\build\src\Components\LightComponent.o src\build\src\Components\SpriteComponent.o src\build\src\Components\TilemapComponent.o src\build\src\Entitys\Object.o src\build\src\utils\EngineConfig.o src\build\src\utils\FileDialog.o src\build\src\utils\Logging.o src\build\src\utils\Shader.o src\build\src\utils\utils.o src\build\vendor\imgui\imgui.o src\build\vendor\imgui\imgui_demo.o src\build\vendor\imgui\imgui_draw.o src\build\vendor\imgui\imgui_impl_glfw.o src\build\vendor\imgui\imgui_impl_opengl3.o src\build\vendor\imgui\imgui_tables.o src\build\vendor\imgui\imgui_widgets.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto
|
||||
[ERROR] Interrupted by user.
|
||||
[RUN] Executed app.exe successfully.
|
||||
|
@ -74,6 +74,28 @@ void TilemapComponent::UpdateAtlasDimensions()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool TilemapComponent::IsTileFullyTransparent(int col, int row, int texW, int texH, unsigned char* imageData)
|
||||
{
|
||||
int x0 = col * m_AtlasTileWidth;
|
||||
int y0 = row * m_AtlasTileHeight;
|
||||
|
||||
for (int y = 0; y < m_AtlasTileHeight; ++y)
|
||||
{
|
||||
for (int x = 0; x < m_AtlasTileWidth; ++x)
|
||||
{
|
||||
int px = x0 + x;
|
||||
int py = y0 + y;
|
||||
int idx = (py * texW + px) * 4;
|
||||
if (imageData[idx + 3] > 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Serialization: store grid size, tile size, tile data, and atlas settings.
|
||||
void TilemapComponent::Save(YAML::Emitter &out) const
|
||||
{
|
||||
@ -119,140 +141,122 @@ void TilemapComponent::Load(const YAML::Node &node)
|
||||
UpdateAtlasDimensions();
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// Editor UI
|
||||
// -----------------------------
|
||||
void TilemapComponent::DrawEditorUI()
|
||||
{
|
||||
ImGui::Begin("Tilemap Editor");
|
||||
|
||||
// --- Atlas Settings ---
|
||||
if (ImGui::CollapsingHeader("Tileset Atlas Settings"))
|
||||
if (ImGui::BeginTabBar("TilemapEditorTabs"))
|
||||
{
|
||||
// Display current atlas path
|
||||
ImGui::Text("Current Atlas: %s", m_AtlasPath.empty() ? "None" : m_AtlasPath.c_str());
|
||||
if (ImGui::Button("Import Atlas"))
|
||||
// --- Atlas Settings ---
|
||||
if (ImGui::BeginTabItem("Atlas Settings"))
|
||||
{
|
||||
std::string path = OpenFileDialog(FileDialogType::Images);
|
||||
if (!path.empty())
|
||||
ImGui::Text("Current Atlas: %s", m_AtlasPath.empty() ? "None" : m_AtlasPath.c_str());
|
||||
if (ImGui::Button("Import Atlas"))
|
||||
{
|
||||
// For simplicity, default atlas tile dimensions are set via input later.
|
||||
m_AtlasPath = path;
|
||||
std::string path = OpenFileDialog(FileDialogType::Images);
|
||||
if (!path.empty())
|
||||
{
|
||||
m_AtlasPath = path;
|
||||
UpdateAtlasDimensions();
|
||||
}
|
||||
}
|
||||
|
||||
int atlasW = m_AtlasTileWidth, atlasH = m_AtlasTileHeight;
|
||||
if (ImGui::InputInt("Atlas Tile Width", &atlasW))
|
||||
{
|
||||
m_AtlasTileWidth = atlasW;
|
||||
UpdateAtlasDimensions();
|
||||
}
|
||||
}
|
||||
// Configure atlas tile size
|
||||
int atlasW = m_AtlasTileWidth, atlasH = m_AtlasTileHeight;
|
||||
if (ImGui::InputInt("Atlas Tile Width", &atlasW))
|
||||
{
|
||||
m_AtlasTileWidth = atlasW;
|
||||
UpdateAtlasDimensions();
|
||||
}
|
||||
if (ImGui::InputInt("Atlas Tile Height", &atlasH))
|
||||
{
|
||||
m_AtlasTileHeight = atlasH;
|
||||
UpdateAtlasDimensions();
|
||||
}
|
||||
ImGui::Text("Atlas Grid: %d columns x %d rows", m_AtlasCols, m_AtlasRows);
|
||||
}
|
||||
|
||||
// --- Map Grid Settings ---
|
||||
if (ImGui::CollapsingHeader("Map Settings"))
|
||||
{
|
||||
glm::ivec2 grid = m_GridSize;
|
||||
int gridW = grid.x, gridH = grid.y;
|
||||
if (ImGui::InputInt("Map Grid Width", &gridW) || ImGui::InputInt("Map Grid Height", &gridH))
|
||||
{
|
||||
SetGridSize(glm::ivec2(gridW, gridH));
|
||||
}
|
||||
glm::ivec2 ts = m_TileSize;
|
||||
int tileW = ts.x, tileH = ts.y;
|
||||
if (ImGui::InputInt("Tile Width", &tileW) || ImGui::InputInt("Tile Height", &tileH))
|
||||
{
|
||||
SetTileSize(glm::ivec2(tileW, tileH));
|
||||
}
|
||||
}
|
||||
|
||||
// --- Tileset Palette Editor ---
|
||||
if (ImGui::CollapsingHeader("Tileset Palette"))
|
||||
{
|
||||
if (m_AtlasPath.empty())
|
||||
{
|
||||
ImGui::Text("No atlas loaded.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Retrieve texture dimensions via stbi_info (for preview UV calculation)
|
||||
int texW, texH, comp;
|
||||
if (stbi_info(m_AtlasPath.c_str(), &texW, &texH, &comp))
|
||||
if (ImGui::InputInt("Atlas Tile Height", &atlasH))
|
||||
{
|
||||
float uvTileW = float(m_AtlasTileWidth) / float(texW);
|
||||
float uvTileH = float(m_AtlasTileHeight) / float(texH);
|
||||
// Display each tile as an image button
|
||||
ImGui::Text("Select a tile:");
|
||||
for (int row = 0; row < m_AtlasRows; row++)
|
||||
{
|
||||
for (int col = 0; col < m_AtlasCols; col++)
|
||||
{
|
||||
int tileIndex = row * m_AtlasCols + col;
|
||||
// UV coordinates for this tile
|
||||
float uvX = float(col) * uvTileW;
|
||||
float uvY = float(row) * uvTileH;
|
||||
ImVec2 uv0(uvX, uvY);
|
||||
ImVec2 uv1(uvX + uvTileW, uvY + uvTileH);
|
||||
m_AtlasTileHeight = atlasH;
|
||||
UpdateAtlasDimensions();
|
||||
}
|
||||
|
||||
char buf[32];
|
||||
sprintf(buf, "##tile_%d", tileIndex);
|
||||
// Display a button. Here, 32x32 pixels is used for preview size.
|
||||
GLuint textureID = LoadTextureIfNeeded(m_AtlasPath);
|
||||
if (ImGui::ImageButton(buf, (ImTextureID)(uintptr_t)textureID, ImVec2(32, 32), uv0, uv1))
|
||||
{
|
||||
g_selectedTileIndex = tileIndex;
|
||||
}
|
||||
ImGui::Text("Atlas Grid: %d x %d", m_AtlasCols, m_AtlasRows);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
}
|
||||
ImGui::NewLine();
|
||||
}
|
||||
ImGui::Text("Selected Tile: %d", g_selectedTileIndex);
|
||||
// --- Map Settings ---
|
||||
if (ImGui::BeginTabItem("Map Settings"))
|
||||
{
|
||||
ImGui::Text("Map Size: %d x %d", m_GridSize.x, m_GridSize.y);
|
||||
ImGui::Text("Tile Size: %d x %d", m_TileSize.x, m_TileSize.y);
|
||||
ImGui::Text("Tile Count: %zu", m_Tiles.size());
|
||||
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
// --- Tile Tools ---
|
||||
if (ImGui::BeginTabItem("Tiles"))
|
||||
{
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (m_AtlasPath.empty())
|
||||
{
|
||||
ImGui::Text("No atlas loaded.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Text("Failed to load atlas info.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Map Editor ---
|
||||
if (ImGui::CollapsingHeader("Map Editor"))
|
||||
{
|
||||
if (m_GridSize.x == 0 || m_GridSize.y == 0)
|
||||
{
|
||||
ImGui::Text("No map created.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Text("Click a cell to paint with the selected tile.");
|
||||
ImGui::BeginChild("TilemapGrid", ImVec2(0, 300), true);
|
||||
for (int y = 0; y < m_GridSize.y; y++)
|
||||
{
|
||||
for (int x = 0; x < m_GridSize.x; x++)
|
||||
int texW, texH, comp;
|
||||
unsigned char* imageData = stbi_load(m_AtlasPath.c_str(), &texW, &texH, &comp, 4);
|
||||
if (imageData)
|
||||
{
|
||||
int tile = GetTile(x, y);
|
||||
char label[32];
|
||||
sprintf(label, "%d##%d_%d", tile, x, y);
|
||||
if (ImGui::Button(label, ImVec2(30, 30)))
|
||||
float uvTileW = float(m_AtlasTileWidth) / float(texW);
|
||||
float uvTileH = float(m_AtlasTileHeight) / float(texH);
|
||||
GLuint textureID = LoadTextureIfNeeded(m_AtlasPath);
|
||||
|
||||
const float tileDisplaySize = 48;
|
||||
ImGui::BeginChild("TilesetView");
|
||||
for (int row = 0; row < m_AtlasRows; ++row)
|
||||
{
|
||||
SetTile(x, y, g_selectedTileIndex);
|
||||
for (int col = 0; col < m_AtlasCols; ++col)
|
||||
{
|
||||
int tileIndex = row * m_AtlasCols + col;
|
||||
float uvX = float(col) * uvTileW;
|
||||
float uvY = float(row) * uvTileH;
|
||||
ImVec2 uv0(uvX, uvY);
|
||||
ImVec2 uv1(uvX + uvTileW, uvY + uvTileH);
|
||||
|
||||
char id[32];
|
||||
sprintf(id, "##tile_%d", tileIndex);
|
||||
|
||||
bool isEmpty = IsTileFullyTransparent(col, row, texW, texH, imageData);
|
||||
ImVec4 tint = isEmpty ? ImVec4(0.3f, 0.3f, 0.3f, 0.5f) : ImVec4(1, 1, 1, 1);
|
||||
if (ImGui::ImageButton(id, (ImTextureID)(uintptr_t)textureID, ImVec2(tileDisplaySize, tileDisplaySize), uv0, uv1))
|
||||
{
|
||||
g_selectedTileIndex = tileIndex;
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("Tile %d", tileIndex);
|
||||
|
||||
ImGui::SameLine();
|
||||
}
|
||||
ImGui::NewLine();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
stbi_image_free(imageData);
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::NewLine();
|
||||
else
|
||||
{
|
||||
ImGui::Text("Failed to load image.");
|
||||
}
|
||||
|
||||
ImGui::Text("Selected Tile: %d", g_selectedTileIndex);
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -53,4 +53,6 @@ private:
|
||||
int m_AtlasRows = 0;
|
||||
|
||||
void UpdateAtlasDimensions();
|
||||
bool IsTileFullyTransparent(int col, int row, int texW, int texH, unsigned char* imageData);
|
||||
|
||||
};
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "../Components/SpriteComponent.h"
|
||||
#include "../Components/CameraComponent.h"
|
||||
#include "../Components/LightComponent.h"
|
||||
#include "../Components/TilemapComponent.h"
|
||||
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
@ -90,6 +92,9 @@ void Object::Load(const YAML::Node& node) {
|
||||
} else if (type == "LightComponent") {
|
||||
auto comp = AddComponent<LightComponent>();
|
||||
comp->Load(compNode);
|
||||
} else if (type == "TilemapComponent") {
|
||||
auto comp = AddComponent<TilemapComponent>();
|
||||
comp->Load(compNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,3 +37,5 @@ std::string GetFilenameFromPath(const std::string& path)
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user