From e01d71afaf0cfb85e1160d3706c3668ae6619210 Mon Sep 17 00:00:00 2001 From: ecrinyildiz Date: Sun, 19 Jan 2025 23:32:15 +0300 Subject: [PATCH 1/7] [~] Game: Enhance CollisionManager - Seperate detection and resolve session - Rearrange inline `pair_hash` struct, so it can be reusable - Create alias for `SpatialGrid` and `CollisionsObject` to reduce complexity - Remove dynamic casting while calculating the `center` of the game objects, now call the `getCenter()` function handle the casting operation. --- include/CollisionManager.hpp | 29 ++++++---- src/CollisionManager.cpp | 108 ++++++++++++++--------------------- 2 files changed, 62 insertions(+), 75 deletions(-) diff --git a/include/CollisionManager.hpp b/include/CollisionManager.hpp index 032b111..750a616 100644 --- a/include/CollisionManager.hpp +++ b/include/CollisionManager.hpp @@ -8,12 +8,31 @@ #include namespace game::engine { +struct pair_hash +{ + template + std::size_t operator()(const std::pair& pair) const + { + auto h1 = std::hash{}(pair.first); + auto h2 = std::hash{}(pair.second); + return h1 ^ (h2 << 1); // Combine hashes + } +}; + class CollisionManager { + + using SpatialGrid = + std::unordered_map, std::vector, pair_hash>; + using CollisionsObject = + std::vector>; + private: std::vector> m_active_collisions; int m_cumulative_collision_count = 0; + const std::vector> neighborOffsets = { + {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 0}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; public: CollisionManager() = default; @@ -24,16 +43,6 @@ class CollisionManager const std::vector>& get_active_collisions() const; int get_collision_count() const; - struct pair_hash - { - template - std::size_t operator()(const std::pair& pair) const - { - auto h1 = std::hash{}(pair.first); - auto h2 = std::hash{}(pair.second); - return h1 ^ (h2 << 1); // Combine hashes - } - }; }; } // namespace game::engine diff --git a/src/CollisionManager.cpp b/src/CollisionManager.cpp index d626ad6..39c1b6a 100644 --- a/src/CollisionManager.cpp +++ b/src/CollisionManager.cpp @@ -6,39 +6,16 @@ namespace game::engine void CollisionManager::resolve_collisions( const std::vector>& objects) { - // Define the grid size const float cellSize = 50.0f; // Adjust based on object size and game world - // A map to store objects by their grid cell - std::unordered_map, std::vector, pair_hash> - spatialGrid; + SpatialGrid spatialGrid; // A map to store objects by their grid cell // Helper lambda to compute grid cell for a position auto getCell = [cellSize](const game::object::GameObject& obj) { - int pos_x, pos_y; - switch (obj.get_type()) - { - case game::object::helper::ObjectType::CIRCLE: - if (const auto* circle = dynamic_cast(&obj)) - { - pos_x = static_cast(std::floor(circle->getPosition().getX() / cellSize)); - pos_y = static_cast(std::floor(circle->getPosition().getY() / cellSize)); - } - break; - case game::object::helper::ObjectType::RECTANGLE: - if (const auto* rect = dynamic_cast(&obj)) - { - pos_x = static_cast(std::floor( - (rect->getPosition().getX() + rect->get_width() / 2) / cellSize)); - pos_y = static_cast(std::floor( - (rect->getPosition().getY() + rect->get_height() / 2) / cellSize)); - } - break; - } - - int cellX = static_cast(std::floor(pos_x / cellSize)); - int cellY = static_cast(std::floor(pos_y / cellSize)); + game::object::Position center = obj.getCenter(); + int cellX = static_cast(std::floor(center.getX() / cellSize)); + int cellY = static_cast(std::floor(center.getY() / cellSize)); return std::make_pair(cellX, cellY); }; @@ -50,59 +27,60 @@ void CollisionManager::resolve_collisions( } // Temporary set to track current collisions - std::vector> currentCollisions; + CollisionsObject currentCollisions; // Check collisions within each cell and neighboring cells for (const auto& [cell, cellObjects] : spatialGrid) { - const int cellX = cell.first; - const int cellY = cell.second; - - // Iterate over the cell and its 8 neighbors - for (int dx = -1; dx <= 1; ++dx) + for (const auto& offset : this->neighborOffsets) { - for (int dy = -1; dy <= 1; ++dy) + auto neighborCell = + std::make_pair(cell.first + offset.first, cell.second + offset.second); + if (spatialGrid.find(neighborCell) == spatialGrid.end()) { - auto neighborCell = std::make_pair(cellX + dx, cellY + dy); - if (spatialGrid.find(neighborCell) == spatialGrid.end()) - continue; - - const auto& neighborObjects = spatialGrid[neighborCell]; + continue; + } + const auto& neighborObjects = spatialGrid[neighborCell]; - // Check for collisions between objects in the current cell and neighbor cell - for (auto* obj1 : cellObjects) + // Check for collisions between objects in the current cell and neighbor cell + for (auto* obj1 : cellObjects) + { + for (auto* obj2 : neighborObjects) { - for (auto* obj2 : neighborObjects) + if (obj1 >= obj2) { - if (obj1 == obj2) - continue; // Skip self-collision - if (obj1->is_colliding_with(*obj2)) - { - obj1->on_collision(*obj2); - obj2->on_collision(*obj1); - // Track the colliding pair - currentCollisions.emplace_back(obj1, obj2); - m_cumulative_collision_count++; - } - else - { - m_active_collisions.erase( - std::remove_if( - m_active_collisions.begin(), m_active_collisions.end(), - [&](const std::pair& pair) - { - return (pair.first == obj1 && pair.second == obj2) || - (pair.first == obj2 && pair.second == obj1); - }), - m_active_collisions.end()); - } + continue; // Skip self-collision and duplicate checks + } + + if (obj1->is_colliding_with(*obj2)) + { + currentCollisions.emplace_back(obj1, obj2); + m_cumulative_collision_count++; + } + else + { + m_active_collisions.erase( + std::remove_if(m_active_collisions.begin(), m_active_collisions.end(), + [&](const std::pair& pair) + { + return (pair.first == obj1 && pair.second == obj2) || + (pair.first == obj2 && pair.second == obj1); + }), + m_active_collisions.end()); } } } } } + // Resolve Collisions + for (const auto& [obj1, obj2] : currentCollisions) + { + obj1->on_collision(*obj2); + obj2->on_collision(*obj1); + } + // Update active collisions m_active_collisions = std::move(currentCollisions); } From cb41710c29435b3ee1646c704d08e231c2c9f788 Mon Sep 17 00:00:00 2001 From: Erinc Yildiz Date: Thu, 23 Jan 2025 09:33:59 +0300 Subject: [PATCH 2/7] [+~] Stability: Add stable objects for testing physics and fix some naming conventions. --- include/GameObject.hpp | 12 ++++++--- src/CollisionManager.cpp | 2 +- src/GameObject.cpp | 58 ++++++++++++++++++++++++++++++---------- src/RectObject.cpp | 26 +++++++++++++++++- src/SDLHelper.cpp | 18 ++++++------- src/main.cpp | 52 ++++++++++++++++++----------------- 6 files changed, 115 insertions(+), 53 deletions(-) diff --git a/include/GameObject.hpp b/include/GameObject.hpp index 9433214..7aea930 100644 --- a/include/GameObject.hpp +++ b/include/GameObject.hpp @@ -3,7 +3,7 @@ #include "ClassLogger.hpp" #include "ObjectHelper.hpp" - +#include "GameHelper.hpp" #include #include #include @@ -40,6 +40,7 @@ class GameObject m_pos = {0.0f, 0.0f}; m_acceleration = {0.0f, 0.0f}; m_restitution = 1; + m_is_stable = false; }; virtual ~GameObject() {} @@ -66,12 +67,14 @@ class GameObject void setRestitution(double restitution); void setColor(Color color); void setColorState(ColorState colorState); + void setStability(bool stable); + bool getStability() const; std::vector getLastPositions() const; Force getForce() const; - double get_mass(); + double getMass() const; - ObjectType get_type() const; - Color get_color() const; + ObjectType getType() const; + Color getColor() const; Position getPosition() const; Velocity getVelocity() const; Acceleration getAcceleration() const; @@ -86,6 +89,7 @@ class GameObject double m_mass; double m_restitution; // Coefficient of restitution (bounciness) for elastic/inelastic // collisions. 1.0 for perfectly elastic, 0.0 for perfectly inelastic. + bool m_is_stable; Force m_force; ColorState m_color_state; Color m_color; diff --git a/src/CollisionManager.cpp b/src/CollisionManager.cpp index 39c1b6a..3e762e8 100644 --- a/src/CollisionManager.cpp +++ b/src/CollisionManager.cpp @@ -126,7 +126,7 @@ void CollisionManager::calculate_gravitational_force( sqrt(d_square(obj2->getPosition().getX() - obj1->getPosition().getX()) + d_square(obj2->getPosition().getY() - obj1->getPosition().getY())); double g_force = - (GRAVITATIONAL_CONSTANT * obj1->get_mass() * obj2->get_mass()) / d_square(distance); + (GRAVITATIONAL_CONSTANT * obj1->getMass() * obj2->getMass()) / d_square(distance); game::object::helper::Vector2D force{0, 0}; if (!distance) diff --git a/src/GameObject.cpp b/src/GameObject.cpp index 14eec3a..8ffb3f5 100644 --- a/src/GameObject.cpp +++ b/src/GameObject.cpp @@ -98,7 +98,14 @@ void GameObject::update_color(float delta_time) } void GameObject::setVelocity(Velocity velocity) { - m_velocity = velocity; + if(!m_is_stable) + { + m_velocity = velocity; + } + else + { + m_velocity *= 0; + } } void GameObject::setPosition(Position pos) { @@ -130,15 +137,27 @@ void GameObject::setColorState(ColorState colorState) { m_color_state = colorState; } -double GameObject::get_mass() +void GameObject::setStability(bool stable) +{ + if(stable) + { + m_velocity *= 0; + } + m_is_stable = stable; +} +bool GameObject::getStability() const +{ + return m_is_stable; +} +double GameObject::getMass() const { return m_mass; } -ObjectType GameObject::get_type() const +ObjectType GameObject::getType() const { return m_type; } -Color GameObject::get_color() const +Color GameObject::getColor() const { return m_color; } @@ -251,15 +270,19 @@ void GameObject::on_collision(GameObject& other) auto speed_this = impulse_vector / this->m_mass; auto speed_other = impulse_vector / other.m_mass; const double velocityQuantizationStep = 0.01; - - this->m_velocity -= game::object::helper::Vector2D( - std::round(speed_this.getX() / velocityQuantizationStep) * velocityQuantizationStep, - std::round(speed_this.getY() / velocityQuantizationStep) * velocityQuantizationStep); - + if(!getStability()) + { + this->m_velocity -= game::object::helper::Vector2D( + std::round(speed_this.getX() / velocityQuantizationStep) * velocityQuantizationStep, + std::round(speed_this.getY() / velocityQuantizationStep) * velocityQuantizationStep); + } // Quantize the velocity of the other object - other.m_velocity += game::object::helper::Vector2D( - std::round(speed_other.getX() / velocityQuantizationStep) * velocityQuantizationStep, - std::round(speed_other.getY() / velocityQuantizationStep) * velocityQuantizationStep); + if(!other.getStability()) + { + other.m_velocity += game::object::helper::Vector2D( + std::round(speed_other.getX() / velocityQuantizationStep) * velocityQuantizationStep, + std::round(speed_other.getY() / velocityQuantizationStep) * velocityQuantizationStep); + } } Acceleration GameObject::getAcceleration() const @@ -308,8 +331,15 @@ void GameObject::update_position(float delta_time) { auto x_speed = std::clamp(m_velocity.getX(), MIN_VELOCITY, MAX_VELOCITY); auto y_speed = std::clamp(m_velocity.getY(), MIN_VELOCITY, MAX_VELOCITY); - m_velocity.setX(x_speed); - m_velocity.setY(y_speed); + if(!getStability()) + { + m_velocity.setX(x_speed); + m_velocity.setY(y_speed); + } + else + { + m_velocity *= 0; + } m_pos += m_velocity * delta_time; } diff --git a/src/RectObject.cpp b/src/RectObject.cpp index 01edcf1..266565b 100644 --- a/src/RectObject.cpp +++ b/src/RectObject.cpp @@ -67,7 +67,7 @@ void RectObject::update(float delta_time, int screen_width, int screen_height) bool RectObject::border_collision(int screen_width, int screen_height) { - + #ifdef BORDER_COLLISION if (this->m_pos.getX() < 0) { this->m_pos.setX(0); @@ -92,6 +92,30 @@ bool RectObject::border_collision(int screen_width, int screen_height) this->m_velocity.reverseY(); return true; } + #else + if (m_pos.getX() + m_width < 0) + { + m_pos.setX(screen_width); + return true; + } + if (m_pos.getX() - m_width > screen_width) + { + m_pos.setX(0); + return true; + } + + if (m_pos.getY() + m_height < 0) + { + m_pos.setY(screen_height); + return true; + } + if (m_pos.getY() - m_height > screen_height) + { + m_pos.setY(0); + return true; + } + #endif + return false; } diff --git a/src/SDLHelper.cpp b/src/SDLHelper.cpp index 4d14184..a69a7e9 100644 --- a/src/SDLHelper.cpp +++ b/src/SDLHelper.cpp @@ -348,7 +348,7 @@ void SDLHelper::drawGameObjects( { game::object::Position pos = obj->getPosition(); - switch (obj->get_type()) + switch (obj->getType()) { case game::object::helper::ObjectType::CIRCLE: // Safely cast to CircleObject @@ -357,9 +357,9 @@ void SDLHelper::drawGameObjects( int radius = static_cast(circle->getRadius()); drawCircleFill(pos.getX(), pos.getY(), radius, { - static_cast(obj->get_color().r), - static_cast(obj->get_color().g), - static_cast(obj->get_color().b), + static_cast(obj->getColor().r), + static_cast(obj->getColor().g), + static_cast(obj->getColor().b), 255 // Fully opaque }); } @@ -371,9 +371,9 @@ void SDLHelper::drawGameObjects( { drawRectangleFill(pos.getX(), pos.getY(), rect->get_width(), rect->get_height(), { - static_cast(obj->get_color().r), - static_cast(obj->get_color().g), - static_cast(obj->get_color().b), + static_cast(obj->getColor().r), + static_cast(obj->getColor().g), + static_cast(obj->getColor().b), 255 // Fully opaque }); } @@ -412,11 +412,11 @@ void SDLHelper::renderCollisionHighlights( for (auto* obj : {collision.first, collision.second}) { - if (obj->get_type() == game::object::ObjectType::CIRCLE) + if (obj->getType() == game::object::ObjectType::CIRCLE) { drawOutline(*(dynamic_cast(obj))); } - else if (obj->get_type() == game::object::ObjectType::RECTANGLE) + else if (obj->getType() == game::object::ObjectType::RECTANGLE) { drawOutline(*(dynamic_cast(obj))); } diff --git a/src/main.cpp b/src/main.cpp index 899775b..95fdbdf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,45 +22,49 @@ int main(int argc, char* argv[]) std::string logger2 = "Circle2"; std::string logger3 = "Circle3"; std::string logger4 = "Rect1"; - auto circle1 = std::make_unique(5, logger1); - auto circle2 = std::make_unique(15, logger2); - auto circle3 = std::make_unique(15, logger3); - auto rectan1 = std::make_unique(logger1); + auto circle1 = std::make_unique(30, logger1); + auto circle2 = std::make_unique(10, logger2); + // auto circle3 = std::make_unique(15, logger3); + // auto rectan1 = std::make_unique(logger1); float width = game.getWindowWidth(); float height = game.getWindowHeight(); - game::object::Position pos1 = {width / 2 - 250, height / 2}; - game::object::Position pos2 = {width / 2 + 250, height / 2}; - game::object::Position pos3 = {width / 2, height / 2 - 200}; - game::object::Position pos4 = {width / 2 - 300, height / 2 + 70}; + game::object::Position pos1 = {width / 2 , height / 2}; + game::object::Position pos2 = {width / 2 - 250, height / 2 - 250}; + // game::object::Position pos3 = {width / 2, height / 2 - 200}; + // game::object::Position pos4 = {width / 2 - 300, height / 2 + 70}; circle1->setPosition(pos1); circle2->setPosition(pos2); - circle3->setPosition(pos3); - rectan1->setPosition(pos4); + // circle3->setPosition(pos3); + // rectan1->setPosition(pos4); - circle1->setMass(1.0); - circle2->setMass(5000.0); - circle3->setMass(100.0); - rectan1->setMass(50.0); + circle1->setMass(450.0); + circle2->setMass(15.0); + // circle3->setMass(10.0); + // rectan1->setMass(50.0); - circle1->setRestitution(1.0f); + circle1->setRestitution(0.5f); circle2->setRestitution(1.0f); - circle3->setRestitution(1.0f); - rectan1->setRestitution(1.0f); + // circle3->setRestitution(1.0f); + // rectan1->setRestitution(1.0f); game::object::Velocity vel1 = {0.0f, 0.0f}; - game::object::Velocity vel2 = {0.0f, 0.0f}; - game::object::Velocity vel3 = {0.0f, 0.0f}; - game::object::Velocity vel4 = {0.0f, 0.0f}; + game::object::Velocity vel2 = {30.0f, 5.0f}; + // game::object::Velocity vel3 = {25.0f, -20.0f}; + // game::object::Velocity vel4 = {30.0f, 20.0f}; + circle1->setVelocity(vel1); circle2->setVelocity(vel2); - circle3->setVelocity(vel3); - rectan1->setVelocity(vel4); + + circle1->setStability(true); + circle2->setStability(false); + // circle3->setVelocity(vel3); + // rectan1->setVelocity(vel4); game.addGameObject(std::move(circle1)); game.addGameObject(std::move(circle2)); - game.addGameObject(std::move(circle3)); - game.addGameObject(std::move(rectan1)); + // game.addGameObject(std::move(circle3)); + // game.addGameObject(std::move(rectan1)); game.run(); } \ No newline at end of file From 3edec31687c2b1f0f40ccfbf6180fabef52c7286 Mon Sep 17 00:00:00 2001 From: Erinc Yildiz Date: Thu, 13 Feb 2025 11:20:57 +0300 Subject: [PATCH 3/7] [~] Collision Manager: Fix infinite bounce problem when an object collides with other. --- src/CollisionManager.cpp | 9 +++++++++ src/GameObject.cpp | 1 + 2 files changed, 10 insertions(+) diff --git a/src/CollisionManager.cpp b/src/CollisionManager.cpp index 3e762e8..651ecd4 100644 --- a/src/CollisionManager.cpp +++ b/src/CollisionManager.cpp @@ -54,6 +54,15 @@ void CollisionManager::resolve_collisions( if (obj1->is_colliding_with(*obj2)) { + if(!obj2->getStability()) + { + if(obj2->getVelocity().magnitude()< 2.5) + { + object::helper::Vector2D zeroSpeed{0,0}; + obj2->setVelocity(zeroSpeed); + return; + } + } currentCollisions.emplace_back(obj1, obj2); m_cumulative_collision_count++; } diff --git a/src/GameObject.cpp b/src/GameObject.cpp index 8ffb3f5..07f8451 100644 --- a/src/GameObject.cpp +++ b/src/GameObject.cpp @@ -325,6 +325,7 @@ void GameObject::update_acceleration() void GameObject::update_velocity(float delta_time) { m_velocity += m_acceleration * delta_time; + m_logger.debug("\nCurrent speed x: {}\nCurrent speed y: {}\nCurrent magnitude:{}", m_velocity.getX(), m_velocity.getY(),m_velocity.magnitude()); } void GameObject::update_position(float delta_time) From 40217d14dfe8d02d84c8f33e150cbdb38df76cc1 Mon Sep 17 00:00:00 2001 From: erincyldz <53654423+erincyldz@users.noreply.github.com> Date: Mon, 20 Jan 2025 15:10:40 +0300 Subject: [PATCH 4/7] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index befa835..3acd7ac 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # C++ Gravitation Simulation with using SDL2 Library. ## **Installing dependencies and building the project for the first time**. -This project created using WSL Ubuntu LTS on a windows platform. But before you clone and use make to build the project, you have to make some configuration if this is the first time using C/GCC/SDL in your machine. +This project created using WSL Ubuntu 22.04 LTS on a windows platform. But before you clone and use make to build the project, you have to make some configuration if this is the first time using C/GCC/SDL in your machine. ### **Dependencies** @@ -26,4 +26,4 @@ You have to install LLVM for formatting your code. Refer to [this](https://llvm. **THIS PROJECT IS CREATED USING UBUNTU 22.04LTS. SOMEHOW, IN OTHER UBUNTU RELEASES, I COULD NOT GET MY TOOLCHAIN SETTED UP TO BUILD THE PROJECT BECAUSE I AM NOT CAPABLE OF FIXING THOSE KIND OF PROBLEMS(FOR NOW).** - (**PROBABLY ONLY FOR WSL USERS**)When SDL library tries to popup a textbox or etc. via using xServer over windows, it fails and gets a core dump fail. To fix this, you need to install the correct GUI package for your wsl. It is most probably gets fixed with ```sudo apt install zenity ``` but it may depend on the linux version and distribution you are currently using. For further questions, go and search it on Google, Stackoverflow or ask ChatGPT. Don't bother me. -- In systems other than Ubuntu 22.04LTS, some building problems might occur (for example, i could not build Logger class because i had to include each C++ standard library by hand, such as **`#include `** **`#include `**). If you know how to fix it, please feel free to contribute to this file. \ No newline at end of file +- In systems other than Ubuntu 22.04LTS, some building problems might occur (for example, i could not build Logger class because i had to include each C++ standard library by hand, such as **`#include `** **`#include `**). If you know how to fix it, please feel free to contribute to this file. From f7e662f4c73f2ed2b123561e555b5ee8afaaab5b Mon Sep 17 00:00:00 2001 From: Erinc Yildiz Date: Sun, 15 Mar 2026 16:10:18 +0300 Subject: [PATCH 5/7] [+] Includes: Update necessary includes to make the program compile with different compiler flags. --- include/CollisionManager.hpp | 2 ++ include/Logger.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/CollisionManager.hpp b/include/CollisionManager.hpp index 750a616..b6d02a2 100644 --- a/include/CollisionManager.hpp +++ b/include/CollisionManager.hpp @@ -6,6 +6,8 @@ #include #include #include +#include + namespace game::engine { struct pair_hash diff --git a/include/Logger.hpp b/include/Logger.hpp index ac70266..7c015a6 100644 --- a/include/Logger.hpp +++ b/include/Logger.hpp @@ -1,8 +1,10 @@ #pragma once +#include #include #include #include #include +#include namespace utils { class Logger From a413419d78e671ec4a815ba15905bdfd63f2b962 Mon Sep 17 00:00:00 2001 From: Erinc Yildiz Date: Mon, 16 Mar 2026 01:50:35 +0300 Subject: [PATCH 6/7] [~] RawPtr: Fix raw pointer bug which corrupts data and sometimes makes the game not launchable since it gets stuck over a corrupted vector loop --- include/Game.hpp | 2 +- src/Game.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/Game.hpp b/include/Game.hpp index bf7d19f..7ef5cf3 100644 --- a/include/Game.hpp +++ b/include/Game.hpp @@ -37,7 +37,7 @@ class Game { return m_window_height; } - GameState* p_gameState; + GameState m_gameState; private: void init(); diff --git a/src/Game.cpp b/src/Game.cpp index b57bdab..3a7f46d 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -72,13 +72,13 @@ void Game::run() while (m_sdl->isRunning()) { m_sdl->update(); // Update SDL timing - m_sdl->handleEvents(*p_gameState); - m_sdl->render(gameObjects, *p_gameState); // Pass game objects to SDLHelper for rendering + m_sdl->handleEvents(m_gameState); + m_sdl->render(gameObjects, m_gameState); // Pass game objects to SDLHelper for rendering m_sdl->renderCollisionHighlights(m_collisionManager.get_active_collisions()); // Fixed timestep for game logic while (m_sdl->getAccumulator() >= m_LOGIC_TIMESTEP) { - if (*p_gameState == game::GameState::PLAYING) + if (m_gameState == game::GameState::PLAYING) { update(); m_sdl->renderCollisionScoreboard( @@ -95,7 +95,7 @@ void Game::run() void Game::init() { gameObjects = std::vector>(); - *p_gameState = GameState::MENU; + m_gameState = GameState::MENU; std::string loggerName = "sdl_logger"; m_sdl = std::make_unique("Game Title", m_window_width, m_window_height, loggerName); From 82403fc2adb483fd1caa4697559d215159ceabdf Mon Sep 17 00:00:00 2001 From: ecrinyildiz Date: Sun, 19 Jan 2025 23:32:15 +0300 Subject: [PATCH 7/7] [~] Game: Enhance CollisionManager - Seperate detection and resolve session - Rearrange inline `pair_hash` struct, so it can be reusable - Create alias for `SpatialGrid` and `CollisionsObject` to reduce complexity - Remove dynamic casting while calculating the `center` of the game objects, now call the `getCenter()` function handle the casting operation. --- src/CollisionManager.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/CollisionManager.cpp b/src/CollisionManager.cpp index 651ecd4..35c48bd 100644 --- a/src/CollisionManager.cpp +++ b/src/CollisionManager.cpp @@ -42,6 +42,43 @@ void CollisionManager::resolve_collisions( } const auto& neighborObjects = spatialGrid[neighborCell]; + // Check for collisions between objects in the current cell and neighbor cell + for (auto* obj1 : cellObjects) + { + for (auto* obj2 : neighborObjects) + { + if (obj1 >= obj2) + { + continue; // Skip self-collision and duplicate checks + } + + if (obj1->is_colliding_with(*obj2)) + { + currentCollisions.emplace_back(obj1, obj2); + m_cumulative_collision_count++; + } + else + { + m_active_collisions.erase( + std::remove_if(m_active_collisions.begin(), m_active_collisions.end(), + [&](const std::pair& pair) + { + return (pair.first == obj1 && pair.second == obj2) || + (pair.first == obj2 && pair.second == obj1); + }), + m_active_collisions.end()); + } + } + } + } + } + + // Resolve Collisions + for (const auto& [obj1, obj2] : currentCollisions) + { + obj1->on_collision(*obj2); + obj2->on_collision(*obj1); // Check for collisions between objects in the current cell and neighbor cell for (auto* obj1 : cellObjects) {