diff --git a/Engine/Collision.cpp b/Engine/Collision.cpp index 8f9e52d..a767386 100644 --- a/Engine/Collision.cpp +++ b/Engine/Collision.cpp @@ -1,6 +1,7 @@ #include "Collision.h" #include "utils.h" +#include "../Game/Player.h" namespace Collision { @@ -120,4 +121,14 @@ namespace Collision } return false; } + + bool ResolvePlayerVsRect(Player& player, float ElapsedTime, Collision::CollisionRect* staticRectangle) { + CollisionRect rect = player.GetCollisionRect(); + Collision::ResolveDynamicRectVsRect(rect, ElapsedTime, staticRectangle); + // std::map test = rect.ContactMap; + // player.SetContactMap(test); + player.SetPosition(rect.pos); + player.SetVelocity(rect.vel); + return true; + } } diff --git a/Engine/Collision.h b/Engine/Collision.h index 22ed9f8..16181a7 100644 --- a/Engine/Collision.h +++ b/Engine/Collision.h @@ -6,6 +6,7 @@ #include "structs.h" #include "utils.h" +class Player; class WorldTile; namespace Collision @@ -20,12 +21,14 @@ namespace Collision struct CollisionRect { - + CollisionRect() = default; + CollisionRect(const Point2f& pos, const Point2f& size) : pos(pos), size(size) {} + CollisionRect(const Point2f& pos, const Point2f& size, const Point2f& vel) : pos(pos), size(size), vel(vel) {} Point2f pos; Point2f size; Point2f vel; - std::map ContactMap; + std::map ContactMap{}; }; struct TileCollisionRect @@ -55,4 +58,6 @@ namespace Collision bool DynamicRectVsRect(const CollisionRect& dynamicRectangle, float ElapsedTime, const CollisionRect& staticRectangle, Point2f& contactPoint, Point2f& contactNormal, float& contactTime); bool ResolveDynamicRectVsRect(CollisionRect& dynamicRectangle, float ElapsedTime, CollisionRect* staticRectangle); + + bool ResolvePlayerVsRect(Player& player, float ElapsedTime, Collision::CollisionRect* staticRectangle); } diff --git a/Game/Game.cpp b/Game/Game.cpp index 93562a8..d12a9e7 100644 --- a/Game/Game.cpp +++ b/Game/Game.cpp @@ -111,4 +111,6 @@ void Game::ProcessImGui() { ImGui::SameLine(); ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), std::to_string(Texture::m_TextureCounter).c_str()); ImGui::End(); + + m_WorldLevel.ProcessImGui(); } diff --git a/Game/Level.h b/Game/Level.h index fb43ffd..b5aff35 100644 --- a/Game/Level.h +++ b/Game/Level.h @@ -11,6 +11,7 @@ public: virtual void Update(float elapsedSec) = 0; virtual void Draw() const = 0; virtual void MouseMove(const Point2f& mousePos) = 0; + virtual void ProcessImGui() = 0; private: diff --git a/Game/Player.cpp b/Game/Player.cpp index 8416ac9..735ef96 100644 --- a/Game/Player.cpp +++ b/Game/Player.cpp @@ -1,19 +1,25 @@ #include "pch.h" #include "Player.h" +#include + #include "colors.h" #include "utils.h" #include "WorldLevel.h" Player::Player(const Point2f& Position) : m_Position(Position), m_Size(Point2f{50, 20}) {} +Collision::CollisionRect Player::GetCollisionRect() { + Collision::CollisionRect rect = {m_Position, m_Size, m_Vel}; + return rect; +} void Player::Draw() const { utils::SetColor(Colors::RED); utils::DrawRect(Rectf{m_Position.x, m_Position.y, m_Size.x, m_Size.y}); } -void Player::Update(float elapsedTime, const WorldLevel& level) { +void Player::Update(float elapsedTime, WorldLevel& level) { // m_Acc.y += m_Gravity.y; // m_Vel.y = std::min(m_Vel.y, m_MaxSpeed); // @@ -35,23 +41,25 @@ void Player::Update(float elapsedTime, const WorldLevel& level) { m_Vel.x = 100; } - Point2f nextPos = m_Position + m_Vel * elapsedTime; - bool isColliding = false; + float t = 0, min_t = INFINITY; + Point2f intersectionPoint, normal; - auto tiles = level.GetAllTiles(); - for (int x{0}; x < WorldLevel::WORLD_WIDTH; ++x) { - for (int y{0}; y < WorldLevel::WORLD_HEIGHT; ++y) { - WorldTile* tile = tiles[x][y]; - if (tile->GetTileType() == GroundTileTypes::Dirt) { - Rectf tileRect = Rectf{tile->GetPosition().x, tile->GetPosition().y, WorldLevel::TILE_WIDTH, WorldLevel::TILE_HEIGHT}; - if (utils::IsOverlapping(nextPos, m_Size, tileRect)) { - isColliding = true; - } - } + std::vector> contactTimes{}; + + for (size_t i { 0 }; i < level.m_Rects.size(); ++i) { + if(Collision::DynamicRectVsRect(this->GetCollisionRect(), elapsedTime, level.m_Rects[i], intersectionPoint, normal, t)) { + contactTimes.push_back(std::pair{i, t}); } } - - if(!isColliding) { - m_Position = nextPos; + + std::sort(contactTimes.begin(), contactTimes.end(), [](const std::pair& a, const std::pair& b) { + return a.second < b.second; + }); + + for (std::pair contact_time : contactTimes) { + Collision::ResolvePlayerVsRect(*this, elapsedTime, &level.m_Rects[contact_time.first]); } + + m_Position = m_Position + m_Vel * elapsedTime; + } \ No newline at end of file diff --git a/Game/Player.h b/Game/Player.h index ff152f3..b794081 100644 --- a/Game/Player.h +++ b/Game/Player.h @@ -1,4 +1,5 @@ #pragma once +#include "Collision.h" class WorldLevel; class Player @@ -6,8 +7,18 @@ class Player public: Player(const Point2f& Position); - void Update(float elapsedTime, const WorldLevel& level); + Collision::CollisionRect GetCollisionRect(); + void Update(float elapsedTime, WorldLevel& level); void Draw() const; + + void SetPosition(Point2f pos) { m_Position = pos; } + Point2f GetPosition() const { return m_Position; } + + void SetVelocity(Point2f vel) { m_Vel = vel; } + Point2f GetVelocity() const { return m_Vel; } + + auto GetContactMap(){ return m_ContactMap; } + void SetContactMap(Collision::CollisionDirection dir, WorldTile* tile) { m_ContactMap[dir] = tile; } private: Point2f m_Position{}; @@ -15,6 +26,8 @@ private: Point2f m_Vel{}; + std::map m_ContactMap{}; + Point2f m_Acc{}; Point2f m_Gravity{ 0, -9.81f }; float m_MaxSpeed{ 200 }; diff --git a/Game/WorldLevel.cpp b/Game/WorldLevel.cpp index 95fcd08..8a6d9e0 100644 --- a/Game/WorldLevel.cpp +++ b/Game/WorldLevel.cpp @@ -1,4 +1,5 @@ -#include "pch.h" +#include +#include "pch.h" #include "WorldLevel.h" #include @@ -88,48 +89,50 @@ void WorldLevel::Update(float elapsedSec) { Point2f intersectionPoint, normal; std::vector> contactTimes{}; - - for (size_t i { 1 }; i < m_Rects.size(); ++i) { - if(Collision::DynamicRectVsRect(m_Rects[0], elapsedSec, m_Rects[i], intersectionPoint, normal, t)) { - contactTimes.push_back(std::pair{i, t}); - } - } - - std::sort(contactTimes.begin(), contactTimes.end(), [](const std::pair& a, const std::pair& b) { - return a.second < b.second; - }); - - for (std::pair contact_time : contactTimes) { - Collision::ResolveDynamicRectVsRect(m_Rects[0], elapsedSec, &m_Rects[contact_time.first]); - } - contactTimes.clear(); - - //loop over the worldTiles - for (int x {0} ; x < WORLD_WIDTH; ++x) { - for (int y {0}; y < WORLD_HEIGHT; ++y) { - if(m_worldTiles[x][y]->GetTileType() == GroundTileTypes::Dirt) { - if(Collision::DynamicRectVsRect(m_Rects[0], elapsedSec, m_worldTiles[x][y]->GetCollisionRect().getCollisionRect(), intersectionPoint, normal, t)) { - contactTimes.push_back(std::pair{x + y * WORLD_WIDTH, t}); - } - } - } - } - - std::sort(contactTimes.begin(), contactTimes.end(), [](const std::pair& a, const std::pair& b) { - return a.second < b.second; - }); + m_player.Update(elapsedSec, *this); - for (std::pair contact_time : contactTimes) { - WorldTile* tile = m_worldTiles[contact_time.first % WORLD_WIDTH][contact_time.first / WORLD_WIDTH]; - Collision::CollisionRect rect = tile->GetCollisionRect().getCollisionRect(); - Collision::ResolveDynamicRectVsRect(m_Rects[0], elapsedSec, &rect); - //delete tile; - //WorldTile* tileRect = tile->GetCollisionRect().tile; - //tileRect->SetTileType(GroundTileTypes::Air); - } + // for (size_t i { 1 }; i < m_Rects.size(); ++i) { + // if(Collision::DynamicRectVsRect(m_Rects[0], elapsedSec, m_Rects[i], intersectionPoint, normal, t)) { + // contactTimes.push_back(std::pair{i, t}); + // } + // } + // + // std::sort(contactTimes.begin(), contactTimes.end(), [](const std::pair& a, const std::pair& b) { + // return a.second < b.second; + // }); + // + // for (std::pair contact_time : contactTimes) { + // Collision::ResolveDynamicRectVsRect(m_Rects[0], elapsedSec, &m_Rects[contact_time.first]); + // } - m_Rects[0].pos = m_Rects[0].pos + m_Rects[0].vel * elapsedSec; + //contactTimes.clear(); + + // //loop over the worldTiles + // for (int x {0} ; x < WORLD_WIDTH; ++x) { + // for (int y {0}; y < WORLD_HEIGHT; ++y) { + // if(m_worldTiles[x][y]->GetTileType() == GroundTileTypes::Dirt) { + // if(Collision::DynamicRectVsRect(m_Rects[0], elapsedSec, m_worldTiles[x][y]->GetCollisionRect().getCollisionRect(), intersectionPoint, normal, t)) { + // contactTimes.push_back(std::pair{x + y * WORLD_WIDTH, t}); + // } + // } + // } + // } + // + // std::sort(contactTimes.begin(), contactTimes.end(), [](const std::pair& a, const std::pair& b) { + // return a.second < b.second; + // }); + // + // for (std::pair contact_time : contactTimes) { + // WorldTile* tile = m_worldTiles[contact_time.first % WORLD_WIDTH][contact_time.first / WORLD_WIDTH]; + // Collision::CollisionRect rect = tile->GetCollisionRect().getCollisionRect(); + // Collision::ResolveDynamicRectVsRect(m_Rects[0], elapsedSec, &rect); + // //delete tile; + // //WorldTile* tileRect = tile->GetCollisionRect().tile; + // //tileRect->SetTileType(GroundTileTypes::Air); + // } + // + // m_Rects[0].pos = m_Rects[0].pos + m_Rects[0].vel * elapsedSec; } void WorldLevel::Draw() const { @@ -139,11 +142,6 @@ void WorldLevel::Draw() const { utils::DrawRect(rect.pos, rect.size.x, rect.size.y); } - //Rectf expanded = Rectf{ m_Rects[1].bottomLeft.x - m_Rects[0].width / 2, m_Rects[1].bottomLeft.y - m_Rects[0].height / 2, m_Rects[1].width + m_Rects[0].width, m_Rects[1].height + m_Rects[0].height }; - //utils::SetColor(Colors::RED); - //utils::DrawRect(expanded); - - Point2f RayPoint = Point2f{m_pCamera->Viewport.width, m_pCamera->Viewport.height}; Point2f RayDir = Point2f{m_mousePos.x - RayPoint.x, m_mousePos.y - RayPoint.y}; @@ -152,18 +150,6 @@ void WorldLevel::Draw() const { utils::FillEllipse(m_mousePos, 20, 20); - // Point2f intersectionPoint, normal; - // float contactTime; - // Rectf testRect = Rectf{m_Rects[1].bottomLeft.x, m_Rects[1].bottomLeft.y, m_Rects[1].width, m_Rects[1].height}; - // if(utils::RayVsRect(RayPoint, RayDir, testRect, intersectionPoint, normal, contactTime) && contactTime > 0.0f && contactTime < 1.0f) { - // utils::SetColor(Colors::GREEN); - // utils::FillEllipse(intersectionPoint, 5, 5); - // utils::DrawLine(intersectionPoint, Point2f{intersectionPoint.x + normal.x * 50, intersectionPoint.y + normal.y * 50}); - // } - // - - // utils::SetColor(Colors::YELLOW); - // utils::FillEllipse(m_mousePos,2,2); for (size_t x { 0 }; x < WORLD_WIDTH; ++x) { for (size_t y { 0 }; y < WORLD_HEIGHT; ++y) { m_worldTiles[x][y]->Draw(); @@ -199,16 +185,25 @@ void WorldLevel::Draw() const { utils::SetColor(Colors::MAGENTA); utils::FillEllipse(0, 0, 5, 5); - //m_player.Draw(); + m_player.Draw(); m_pCamera->EndRendering(); - - //utils::SetColor(Colors::WHITE); - //m_pTextTexture->Draw(Point2f{ 0, 0 }); - } void WorldLevel::MouseMove(const Point2f& mousePos) { m_mousePos = mousePos; } +void WorldLevel::ProcessImGui() { + ImGui::Begin("Player Info", nullptr, ImGuiWindowFlags_AlwaysAutoResize); + ImGui::Text("Player Position: (%f, %f)", m_player.GetPosition().x, m_player.GetPosition().y); + ImGui::Text("Player Velocity: (%f, %f)", m_player.GetVelocity().x, m_player.GetVelocity().y); + //PLAYER COLLISIONS + ImGui::Text("Player Collisions:"); + // for (std::pair contact : m_player.GetContactMap()) { + // ImGui::Text("Direction: %d", contact.first); + // ImGui::Text("Position: (%f, %f)", contact.second->pos.x, contact.second->pos.y); + // ImGui::Text("Size: (%f, %f)", contact.second->size.x, contact.second->size.y); + // } + ImGui::End(); +} WorldTile* WorldLevel::GetTileAt(const Point2f& pos) const { return nullptr; } @@ -218,3 +213,5 @@ std::array, WorldLevel::WORLD_HE return m_worldTiles; } + + diff --git a/Game/WorldLevel.h b/Game/WorldLevel.h index ab59e90..6ca96cc 100644 --- a/Game/WorldLevel.h +++ b/Game/WorldLevel.h @@ -25,6 +25,7 @@ public: void Draw() const override; void MouseMove(const Point2f& mousePos) override; + void ProcessImGui() override; WorldTile* GetTileAt(const Point2f& pos) const; void SetTileAt(const Point2f& pos, WorldTile* tile);