Awesome Tilemap editor!!!

This commit is contained in:
2025-05-15 01:57:01 -05:00
parent cbf105266d
commit becf608534

View File

@@ -6,6 +6,9 @@
#include "JUI/Widgets/Scene.hpp"
#include "JUI/Widgets/UtilityBar.hpp"
#include "JUI/Widgets/Window.hpp"
// TODO: ColorPicker.hpp needs to include Slider.hpp
#include "JUI/Widgets/Slider.hpp"
#include "JUI/Widgets/ColorPicker.hpp"
#define GL_VER_MAJOR 2
#define GL_VER_MINOR 1
@@ -13,13 +16,28 @@
using namespace ReWindow;
using namespace JUI::UDimLiterals;
struct EditorCamera {
Vector2 translation;
float rotation;
float scale;
};
class EditorApp : public OpenGLWindow {
public:
EditorCamera camera;
JUI::Scene* scene;
JUI::Window* tileset_viewer;
JUI::Rect* cell_indicator;
JGL::Texture* test_tilesheet;
JUI::Window* bg_color_tool_window = nullptr;
JUI::ColorPicker* bg_color_tool = nullptr;
bool grid_overlay_enabled = true;
Color4 grid_overlay_color = {255, 255, 255, 128};
Color4 bg_color = Colors::Black;
int grid_pixel_width = 16;
int grid_pixel_height = 16;
@@ -62,8 +80,32 @@ public:
return cell.y*width + cell.x;
}
EditorApp() : OpenGLWindow("Editor App", 1770, 768, GL_VER_MAJOR, GL_VER_MINOR) {
EditorApp() : OpenGLWindow("Editor App", 1776, 1000, GL_VER_MAJOR, GL_VER_MINOR) {
camera.rotation = 0.f;
camera.translation = {0.f, 0.f};
camera.scale = 1.f;
}
void LoadTestFile() {
std::ifstream input;
input.open("test.lvl", std::ios::binary | std::ios::in);
input.seekg(0, std::ios::end);
int data_length = input.tellg();
input.seekg(0, std::ios::beg);
char* buffer = new char[data_length];
input.read(buffer, data_length);
input.close();
auto* data = reinterpret_cast<int*>(buffer);
memcpy(grid, data, grid_rows * grid_cols * sizeof(int));
}
void SaveTestFile() {
std::ofstream output;
output.open("test.lvl", std::ios::out | std::ios::binary);
output.write(reinterpret_cast<const char*>(&grid[0][0]), grid_rows * grid_cols * sizeof(int));
output.close();
}
void LoadMisc() {
@@ -77,9 +119,12 @@ public:
for (int x = 0; x < grid_rows; x++) {
for (int y = 0; y < grid_cols; y++) {
grid[x][y] = -1;
}
}
if (std::filesystem::exists("test.lvl"))
LoadTestFile();
}
@@ -145,7 +190,8 @@ public:
view->AddButton("Zoom In");
view->AddButton("Zoom Out");
view->AddSeparator(2_px);
view->AddButton("Toggle Grid");
view->AddButton("Toggle Grid", [this]{ToggleGrid();});
view->AddButton("Set Background Color", [this]{bg_color_tool_window->Toggle();});
auto* level = topbar->AddSubmenu("Level");
auto* layer = topbar->AddSubmenu("Layer");
@@ -159,6 +205,15 @@ public:
tileset_viewer = CreateTilesetViewerWindow(scene);
bg_color_tool_window = new JUI::Window(scene);
bg_color_tool = new JUI::ColorPicker(bg_color_tool_window->Content());
bg_color_tool->OnColorValueChanged += [this] (Color4 new_color) mutable { bg_color = new_color; };
}
void ToggleGrid() {
grid_overlay_enabled = !grid_overlay_enabled;
}
bool Open() override {
@@ -209,7 +264,28 @@ public:
Math::Floor(mouse_v2.y/grid_pixel_height));
}
void CameraUpdate(float elapsed) {
float move_rate = 10;
float zoom_rate = 0.05f;
if (IsKeyDown(Keys::LeftArrow))
camera.translation.x -= move_rate*elapsed;
if (IsKeyDown(Keys::RightArrow))
camera.translation.x += move_rate*elapsed;
if (IsKeyDown(Keys::UpArrow))
camera.translation.y -= move_rate*elapsed;
if (IsKeyDown(Keys::DownArrow))
camera.translation.y += move_rate*elapsed;
if (IsKeyDown(Keys::Minus))
camera.scale -= zoom_rate*elapsed;
if (IsKeyDown(Keys::Equals))
camera.scale += zoom_rate*elapsed;
}
void Update(float elapsed) {
CameraUpdate(elapsed);
auto size = GetSize();
Vector2i vSize = Vector2i(size.x, size.y);
@@ -218,16 +294,17 @@ public:
scene->SetViewportSize(Vector2(vSize));
scene->Update(elapsed);
if (tileset_viewer->Content()->IsMouseInside()) {
cell_indicator->Visible(true);
if (tileset_viewer->IsMouseInside()) {
if (tileset_viewer->Content()->IsMouseInside()) {
cell_indicator->Visible(true);
Vector2 rel_mouse = Vector2(GetTilesetCellFromMouse());
Vector2 rel_mouse = Vector2(GetTilesetCellFromMouse());
rel_mouse.x *= grid_pixel_width;
rel_mouse.y *= grid_pixel_height;
cell_indicator->Position(JUI::UDim2::FromPixels(rel_mouse.x, rel_mouse.y));
rel_mouse.x *= grid_pixel_width;
rel_mouse.y *= grid_pixel_height;
cell_indicator->Position(JUI::UDim2::FromPixels(rel_mouse.x, rel_mouse.y));
}
} else {
cell_indicator->Visible(false);
@@ -235,11 +312,14 @@ public:
Vector2i grid_cell = GetGridCellFromMouse();
grid[grid_cell.x][grid_cell.y] = selected_quad;
}
if (IsMouseButtonDown(MouseButtons::Right)) {
Vector2i grid_cell = GetGridCellFromMouse();
grid[grid_cell.x][grid_cell.y] = -1;
}
}
}
void DrawGrid(const AABB2D& bounds, const Color4& color) {
Vector2 viewport_topleft = bounds.minPoint;
Vector2 viewport_bottomright = bounds.maxPoint;
@@ -268,12 +348,17 @@ public:
}
void Draw() {
glClearColor(bg_color.RN(), bg_color.GN(), bg_color.BN(), 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
J2D::Begin();
glPushMatrix();
glTranslatef(-camera.translation.x, -camera.translation.y, 0);
glRotatef(camera.rotation, 0, 0, 1);
glScalef(camera.scale, camera.scale, 1);
//J2D::DrawSprite(test_tilesheet, {32, 32}, 0, Vector2::Zero, Vector2::One, Colors::White);
for (int gx = 0; gx < grid_rows; gx++) {
for (int gy = 0; gy < grid_cols; gy++) {
@@ -289,12 +374,21 @@ public:
Vector2(quad.x, quad.y), Vector2(quad.w, quad.h));
}
}
DrawGrid();
if (grid_overlay_enabled)
DrawGrid(grid_overlay_color);
glPopMatrix();
J2D::End();
scene->Draw();
}
void OnClosing() override {
SaveTestFile();
}
void OnRefresh(float elapsed) override {
Update(elapsed);
Draw();