From d3af79309259e54381be738fb3feadda1b874adf Mon Sep 17 00:00:00 2001 From: Jan Mrna Date: Sun, 12 Oct 2025 16:04:40 +0200 Subject: [PATCH] Show rectangle when selecting entities --- cpp/src/gameloop.cpp | 11 ++++++++++- cpp/src/pathfindingdemo.cpp | 14 +++++++++++--- cpp/src/pathfindingdemo.hpp | 3 ++- cpp/src/user_input.cpp | 7 +++++++ cpp/src/user_input.hpp | 2 ++ cpp/src/window.cpp | 10 +++++++++- cpp/src/window.hpp | 4 +++- 7 files changed, 44 insertions(+), 7 deletions(-) diff --git a/cpp/src/gameloop.cpp b/cpp/src/gameloop.cpp index 329d4a6..d2db912 100644 --- a/cpp/src/gameloop.cpp +++ b/cpp/src/gameloop.cpp @@ -21,7 +21,7 @@ void GameLoop::Draw() { TilePos{static_cast(row), static_cast(col)})); const auto &size = camera.WorldToWindowSize(map.GetTileSize()); // LOG_DEBUG("Drawing rect (", row, ", ", col, ")"); - m_Window->DrawRect(position, size, tiles[row][col]->R, tiles[row][col]->G, + m_Window->DrawFilledRect(position, size, tiles[row][col]->R, tiles[row][col]->G, tiles[row][col]->B, tiles[row][col]->A); } } @@ -52,6 +52,15 @@ void GameLoop::Draw() { m_Window->DrawCircle(entity_pos_window, entity->GetCollisionRadius()); } } + + // draw the selection box, if present + if (m_Game->IsSelectionBoxActive()) + { + const auto& [corner_pos, size] = m_Game->GetSelectionBoxPosSize(); + m_Window->DrawRect(corner_pos, size, 200, 20, 20, 100); + } + + } // TODO rethink coupling and dependencies in the game loop class diff --git a/cpp/src/pathfindingdemo.cpp b/cpp/src/pathfindingdemo.cpp index c2abec6..f82c41c 100644 --- a/cpp/src/pathfindingdemo.cpp +++ b/cpp/src/pathfindingdemo.cpp @@ -219,6 +219,12 @@ void PathFindingDemo::HandleActions(const std::vector &actions) WorldPos end = m_Camera.WindowToWorld(m_SelectionBox.end); SelectEntitiesInRectangle(start, end); } + else if (action.type == UserAction::Type::SELECTION_CHANGE) + { + m_SelectionBox.end = action.Argument.position; + auto diff = m_SelectionBox.end - m_SelectionBox.start; + m_SelectionBox.size = diff.ChangeTag(); + } }; } @@ -241,10 +247,12 @@ void PathFindingDemo::SelectEntitiesInRectangle(WorldPos A, WorldPos B) LOG_INFO("Selected ", m_SelectedEntities.size(), " entities"); } -std::pair PathFindingDemo::GetSelectionBoxPosSize() +std::pair PathFindingDemo::GetSelectionBoxPosSize() { const auto& pos = m_SelectionBox.start; - WindowPos diff = m_SelectionBox.end - m_SelectionBox.start; - + WindowPos size_pos = m_SelectionBox.end - m_SelectionBox.start; + WindowSize size = size_pos.ChangeTag(); + return std::pair(pos, size); + } diff --git a/cpp/src/pathfindingdemo.hpp b/cpp/src/pathfindingdemo.hpp index 51ffd0f..b327c8f 100644 --- a/cpp/src/pathfindingdemo.hpp +++ b/cpp/src/pathfindingdemo.hpp @@ -17,6 +17,7 @@ using Collision = std::pair, std::weak_ptr>; struct SelectionBox { WindowPos start, end; + WindowSize size; bool active; }; @@ -43,7 +44,7 @@ public: void SelectEntitiesInRectangle(WorldPos A, WorldPos B); bool IsSelectionBoxActive() const { return m_SelectionBox.active; } - std::pair GetSelectionBoxPosSize(); + std::pair GetSelectionBoxPosSize(); private: const std::vector& GetEntityCollisions(); diff --git a/cpp/src/user_input.cpp b/cpp/src/user_input.cpp index 590924e..ae9895f 100644 --- a/cpp/src/user_input.cpp +++ b/cpp/src/user_input.cpp @@ -32,6 +32,7 @@ void UserInput::GetActions_mouse(const SDL_Event& event) if (button == MouseButton::LEFT) { LOG_DEBUG("Selection start at ", mouse_event.x, ", ", mouse_event.y); + m_SelectionActive = true; m_Actions.emplace_back(UserAction::Type::SELECTION_START, WindowPos{mouse_event.x, mouse_event.y}); } @@ -51,6 +52,7 @@ void UserInput::GetActions_mouse(const SDL_Event& event) if (button == MouseButton::LEFT) { LOG_DEBUG("Selection end at ", mouse_event.x, ", ", mouse_event.y); + m_SelectionActive = false; m_Actions.emplace_back(UserAction::Type::SELECTION_END, WindowPos{mouse_event.x, mouse_event.y}); } @@ -67,6 +69,11 @@ void UserInput::GetActions_mouse(const SDL_Event& event) m_Actions.emplace_back(UserAction::Type::CAMERA_PAN, WindowPos{motion_event.xrel, motion_event.yrel}); } + if (m_SelectionActive) + { + m_Actions.emplace_back(UserAction::Type::SELECTION_CHANGE, + WindowPos{mouse_event.x, mouse_event.y}); + } } else if(event.type == SDL_EVENT_MOUSE_WHEEL) { diff --git a/cpp/src/user_input.hpp b/cpp/src/user_input.hpp index de2c9f1..dee9231 100644 --- a/cpp/src/user_input.hpp +++ b/cpp/src/user_input.hpp @@ -22,6 +22,7 @@ public: CAMERA_PAN, CAMERA_ZOOM, SELECTION_START, + SELECTION_CHANGE, SELECTION_END }; @@ -62,6 +63,7 @@ public: private: std::vector m_Actions; + bool m_SelectionActive = false; void GetActions_keyboard(const SDL_Event&); void GetActions_mouse(const SDL_Event&); diff --git a/cpp/src/window.cpp b/cpp/src/window.cpp index 91b9ab6..d1675f9 100644 --- a/cpp/src/window.cpp +++ b/cpp/src/window.cpp @@ -84,13 +84,21 @@ void Window::DrawSprite(const WindowPos &position, Sprite &s, float scale) { SDL_RenderTexture(m_Renderer.get(), s.GetTexture(), nullptr, &rect); } -void Window::DrawRect(const WindowPos &position, const WindowSize size, uint8_t R, +void Window::DrawFilledRect(const WindowPos &position, const WindowSize size, uint8_t R, uint8_t G, uint8_t B, uint8_t A) { SDL_FRect rect = {position.x(), position.y(), size.x(), size.y()}; SDL_SetRenderDrawColor(m_Renderer.get(), R, G, B, A); SDL_RenderFillRect(m_Renderer.get(), &rect); } +void Window::DrawRect(const WindowPos &position, const WindowSize size, uint8_t R, + uint8_t G, uint8_t B, uint8_t fill_alpha) { + SDL_FRect rect = {position.x(), position.y(), size.x(), size.y()}; + SDL_SetRenderDrawColor(m_Renderer.get(), R, G, B, 255); + SDL_RenderRect(m_Renderer.get(), &rect); + //SDL_RenderFillRect(m_Renderer.get(), &rect); +} + void Window::ClearWindow() { SDL_SetRenderDrawColor(m_Renderer.get(), 50, 50, 50, 255); SDL_RenderClear(m_Renderer.get()); diff --git a/cpp/src/window.hpp b/cpp/src/window.hpp index 8453d67..a34566c 100644 --- a/cpp/src/window.hpp +++ b/cpp/src/window.hpp @@ -23,8 +23,10 @@ public: std::expected Init(); void DrawSprite(const WindowPos &position, Sprite &s, float scale = 1.0f); - void DrawRect(const WindowPos &position, const WindowSize size, uint8_t R, + void DrawFilledRect(const WindowPos &position, const WindowSize size, uint8_t R, uint8_t G, uint8_t B, uint8_t A); + void DrawRect(const WindowPos &position, const WindowSize size, uint8_t R, + uint8_t G, uint8_t B, uint8_t fill_alpha); void ClearWindow(); void Flush(); void DrawCircle(const WindowPos &position, float radius);