diff --git a/client/entities/local_character.cpp b/client/entities/local_character.cpp index dc563d9..79ba6be 100644 --- a/client/entities/local_character.cpp +++ b/client/entities/local_character.cpp @@ -47,12 +47,18 @@ bool LocalCharacter::ProcessCollisionGrid(std::list boxList, Uint8* bool ret = false; for(auto& box : boxList) { - if (box.CheckOverlap(origin + bounds)) { + if (box.CheckCollision(origin + bounds)) { //push the character to the closest non-contact position - //TODO + Vector2 shift = box.CalcShift(origin + bounds); + origin += shift; //set any motion in that direction to zero - //TODO + if (shift.x != 0) { + newMotion.x = 0; + } + if (shift.y != 0) { + newMotion.y = 0; + } ret = true; } } diff --git a/client/menu_scenes/lobby_menu.cpp b/client/menu_scenes/lobby_menu.cpp index befc6f5..0665d37 100644 --- a/client/menu_scenes/lobby_menu.cpp +++ b/client/menu_scenes/lobby_menu.cpp @@ -166,7 +166,7 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { //has the user selected a server on the list? BoundingBox tmpBox = listBox; tmpBox.h *= serverInfo.size(); - if (tmpBox.CheckOverlap({button.x, button.y})) { + if (tmpBox.CheckCollision({button.x, button.y, 0, 0})) { selection = &serverInfo[(button.y - listBox.y)/listBox.h]; } else { diff --git a/common/utilities/bounding_box.hpp b/common/utilities/bounding_box.hpp index baf9917..9dee995 100644 --- a/common/utilities/bounding_box.hpp +++ b/common/utilities/bounding_box.hpp @@ -22,6 +22,8 @@ #ifndef BOUNDINGBOX_HPP_ #define BOUNDINGBOX_HPP_ +#include "vector2.hpp" + #include #include @@ -32,16 +34,15 @@ public: int w, h; BoundingBox() = default; - BoundingBox(int i, int j): x(i), y(j), w(0), h(0) {}; BoundingBox(int i, int j, int k, int l): x(i), y(j), w(k), h(l) {}; ~BoundingBox() = default; BoundingBox& operator=(BoundingBox const&) = default; int Size() { - return std::max(w*h,0); + return (w-x) * (h-y); } - bool CheckOverlap(BoundingBox rhs) { + bool CheckCollision(BoundingBox rhs) { return !( x >= rhs.x + rhs.w || y >= rhs.y + rhs.h || @@ -49,24 +50,25 @@ public: rhs.y >= y + h); } - BoundingBox CalcOverlap(BoundingBox rhs) { - if (!CheckOverlap(rhs)) { - return {0, 0, 0, 0}; + Vector2 CalcShift(BoundingBox rhs) { + if (!CheckCollision(rhs)) { + return {0, 0}; } - BoundingBox ret; - ret.x = std::max(x, rhs.x); - ret.y = std::max(y, rhs.y); - ret.w = std::min(x+w, rhs.x+rhs.w) - ret.x; - ret.h = std::min(y+h, rhs.y+rhs.h) - ret.y; - return ret; + + //DOCS: Given two BoundingBox objects, how does the other have to move so that they are no longer colliding? + Vector2 horizontal = {0, 0}; + Vector2 vertical = {0, 0}; + + horizontal.x = std::abs(x + w - rhs.x) < std::abs(rhs.x + rhs.w - x) ? x + w - rhs.x -1 : -(rhs.x + rhs.w - x -1); + vertical.y = std::abs(y + h - rhs.x) < std::abs(rhs.y + rhs.h - y) ? y + h - rhs.y -1 : -(rhs.y + rhs.h - y -1); + + return std::abs(vertical.y) < std::abs(horizontal.x) ? vertical : horizontal; } }; //This is explicitly a POD static_assert(std::is_pod::value, "BoundingBox is not a POD"); -#include "vector2.hpp" - //operators inline BoundingBox operator+(BoundingBox b, Vector2 v) { return {b.x + (int)v.x, b.y + (int)v.y, b.w, b.h};