feat(editor): brush amb preview snap-to-grid i pintura per clic

This commit is contained in:
JailDesigner committed 2026-04-23 12:11:54 +02:00
1 parent a612a8255f
commit 05cdcfa660
3 files changed
+86 -11

No files matched your search

+55 -11
View File
@@ -7,6 +7,7 @@
#include "core/locale/locale.hpp"
#include "core/rendering/notification_presets.hpp"
#include "core/rendering/screen.hpp"
#include "core/system/event_buffer.hpp"
#include "game/map/tilemap.hpp"
#include "utils/defaults.hpp"
#include "utils/defines.hpp"
@@ -35,25 +36,68 @@ void Editor::toggle(Tilemap& tilemap) {
}
}
// cppcheck-suppress constParameterReference
// Tilemap& mutable: al pas següent `setTileAt()` (no const) el muta.
void Editor::update(int /*delta_ms*/, Tilemap& tilemap) {
if (!active_) { return; }
cursor_col_ = -1;
cursor_row_ = -1;
(void)tilemap; // TODO: brush + click + picker al pas següent.
// 1. Cursor → cel·la. Convertim la posició del ratolí (espai finestra)
// a coordenades del canvas amb Screen::windowToCanvas, i d'allí al
// sistema de cel·les del tilemap restant l'origin i dividint pel
// tile_size. Fora del mapa → cursor_col/row = -1.
float mouse_x = 0.0F;
float mouse_y = 0.0F;
SDL_GetMouseState(&mouse_x, &mouse_y);
const auto CANVAS_PT = Screen::get().windowToCanvas(mouse_x, mouse_y);
const int CX = static_cast<int>(CANVAS_PT.x) - tilemap.getOriginX();
const int CY = static_cast<int>(CANVAS_PT.y) - tilemap.getOriginY();
const int TS = tilemap.getTileSize();
int col = -1;
int row = -1;
if (TS > 0 && CX >= 0 && CY >= 0) {
const int C = CX / TS;
const int R = CY / TS;
if (C < tilemap.getCols() && R < tilemap.getRows()) {
col = C;
row = R;
}
}
cursor_col_ = col;
cursor_row_ = row;
// 2. Clicks: només per-esdeveniment (no per estat). Un clic = un
// tile col·locat o brush netejat. El picker encara no existeix, així
// que el right-click no obre res: només neteja el brush.
for (const auto& ev : EventBuffer::events) {
if (ev.type != SDL_EVENT_MOUSE_BUTTON_DOWN) { continue; }
if (ev.button.button == SDL_BUTTON_LEFT) {
if (brush_ >= 0 && cursor_col_ >= 0 && cursor_row_ >= 0) {
tilemap.setTileAt(cursor_col_, cursor_row_, brush_);
}
} else if (ev.button.button == SDL_BUTTON_RIGHT) {
brush_ = -1;
}
}
}
void Editor::render(const Tilemap& /*tilemap*/) const {
void Editor::render(const Tilemap& tilemap) const {
if (!active_) { return; }
auto& screen = Screen::get();
constexpr int W = GameCanvas::WIDTH;
constexpr int H = GameCanvas::HEIGHT;
constexpr auto ARGB = Defaults::Editor::BORDER_ARGB;
screen.fillRect(0, 0, W, 1, ARGB); // top
screen.fillRect(0, H - 1, W, 1, ARGB); // bottom
screen.fillRect(0, 0, 1, H, ARGB); // left
screen.fillRect(W - 1, 0, 1, H, ARGB); // right
constexpr auto BORDER = Defaults::Editor::BORDER_ARGB;
// Preview del brush: blitejem el tile seleccionat a la cel·la sota
// el cursor, abans del border, així el border no el talla si caiguera
// al perímetre. Cap efecte si no hi ha brush o el cursor està fora.
if (brush_ >= 0 && cursor_col_ >= 0 && cursor_row_ >= 0) {
const int PX = tilemap.getOriginX() + (cursor_col_ * tilemap.getTileSize());
const int PY = tilemap.getOriginY() + (cursor_row_ * tilemap.getTileSize());
tilemap.renderTilePreview(PX, PY, brush_);
}
screen.fillRect(0, 0, W, 1, BORDER); // top
screen.fillRect(0, H - 1, W, 1, BORDER); // bottom
screen.fillRect(0, 0, 1, H, BORDER); // left
screen.fillRect(W - 1, 0, 1, H, BORDER); // right
}
#endif // _DEBUG