diff --git a/Engine/Collision.cpp b/Engine/Collision.cpp index 463e99b..8f9e52d 100644 --- a/Engine/Collision.cpp +++ b/Engine/Collision.cpp @@ -4,6 +4,9 @@ namespace Collision { + + TileCollisionRect::TileCollisionRect(const Point2f& pos, const Point2f& size, WorldTile* tile): pos(pos), size(size), tile(tile) + {} bool PointVsRect(const Point2f p, const Collision::CollisionRect& r) { return ( p.x >= r.pos.x && p.y >= r.pos.y && p.x < r.pos.x + r.size.x && p.y < r.pos.y + r.size.y ); } @@ -99,16 +102,16 @@ namespace Collision float contact_time = 0.0f; if (DynamicRectVsRect(dynamicRectangle, ElapsedTime, *staticRectangle, contactPoint, contactNormal, contact_time)) { if (contactNormal.y > 0) { - dynamicRectangle.contact[0] = staticRectangle; + dynamicRectangle.ContactMap[CollisionDirection::Bottom] = staticRectangle; } if (contactNormal.x < 0) { - dynamicRectangle.contact[1] = staticRectangle; + dynamicRectangle.ContactMap[CollisionDirection::Left] = staticRectangle; } if (contactNormal.y < 0) { - dynamicRectangle.contact[2] = staticRectangle; + dynamicRectangle.ContactMap[CollisionDirection::Top] = staticRectangle; } if (contactNormal.x > 0) { - dynamicRectangle.contact[3] = staticRectangle; + dynamicRectangle.ContactMap[CollisionDirection::Right] = staticRectangle; } //dynamicRectangle.vel = dynamicRectangle.vel + contactNormal * Point2f(std::abs(dynamicRectangle.vel.x), std::abs(dynamicRectangle.vel.y)) * ( 1 - contact_time ); diff --git a/Engine/Collision.h b/Engine/Collision.h index e0d393c..22ed9f8 100644 --- a/Engine/Collision.h +++ b/Engine/Collision.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include "structs.h" #include "utils.h" @@ -10,6 +11,13 @@ class WorldTile; namespace Collision { + enum CollisionDirection { + Top, + Bottom, + Left, + Right + }; + struct CollisionRect { @@ -17,19 +25,25 @@ namespace Collision Point2f size; Point2f vel; - std::array contact; + std::map ContactMap; }; - struct TileCollisionRect : public CollisionRect + struct TileCollisionRect { - TileCollisionRect(const Point2f& pos, const Point2f& size, WorldTile* tile) - : CollisionRect{ pos, size, Point2f{ 0, 0 }, { nullptr, nullptr, nullptr, nullptr } } - , tile{ tile } - {} + Point2f pos; + Point2f size; + Point2f vel; + TileCollisionRect(const Point2f& pos, const Point2f& size, WorldTile* tile); WorldTile* tile; + std::map ContactMap; + bool Contains(Point2f point2_f) { return utils::IsPointInRect(point2_f, Rectf{ pos.x, pos.y, size.x, size.y }); } + + Collision::CollisionRect getCollisionRect() { + return Collision::CollisionRect{ pos, size, vel }; + } }; bool PointVsRect(const Point2f p, const CollisionRect& r); diff --git a/Game/WorldLevel.cpp b/Game/WorldLevel.cpp index f15bf2f..2c66781 100644 --- a/Game/WorldLevel.cpp +++ b/Game/WorldLevel.cpp @@ -76,12 +76,13 @@ void WorldLevel::Update(float elapsedSec) { if(utils::isKeyDown(SDL_SCANCODE_D)) { m_Rects[0].vel.x += 10; } + if(utils::isKeyDown(SDL_SCANCODE_SPACE)) { + //check if the player is on the ground + m_Rects[0].ContactMap[Collision::CollisionDirection::Bottom]->pos.y += 100; + } m_Rects[0].vel.y -= 9.81f; - m_Rects[0].contact[0] = nullptr; - m_Rects[0].contact[1] = nullptr; - m_Rects[0].contact[2] = nullptr; - m_Rects[0].contact[3] = nullptr; + m_Rects[0].ContactMap.clear(); float t = 0, min_t = INFINITY; Point2f intersectionPoint, normal; @@ -108,7 +109,7 @@ void WorldLevel::Update(float elapsedSec) { 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(), intersectionPoint, normal, t)) { + 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}); } } @@ -121,14 +122,13 @@ void WorldLevel::Update(float elapsedSec) { 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(); + 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; } @@ -174,7 +174,7 @@ void WorldLevel::Draw() const { for (int x { 0 }; x < WORLD_WIDTH; ++x) { for (int y { 0 }; y < WORLD_HEIGHT; ++y) { if(m_worldTiles[x][y]->GetTileType() == GroundTileTypes::Dirt) { - Collision::CollisionRect rect = m_worldTiles[x][y]->GetCollisionRect(); + Collision::CollisionRect rect = m_worldTiles[x][y]->GetCollisionRect().getCollisionRect(); utils::SetColor(Colors::GREEN); utils::DrawRect(rect.pos, rect.size.x, rect.size.y); } @@ -182,9 +182,10 @@ void WorldLevel::Draw() const { } for (size_t i { 0 }; i < 4; ++i) { - if(m_Rects[0].contact[i] != nullptr) { + if(m_Rects[0].ContactMap.find(static_cast(i)) != m_Rects[0].ContactMap.end()) { utils::SetColor(Colors::RED); - utils::FillRect(m_Rects[0].contact[i]->pos, m_Rects[0].contact[i]->size.x, m_Rects[0].contact[i]->size.y); + Collision::CollisionRect* rect = m_Rects[0].ContactMap.at(static_cast(i)); + utils::FillRect(rect->pos, rect->size.x, rect->size.y); } } diff --git a/Game/WorldTile.cpp b/Game/WorldTile.cpp index d2ed95a..6b88c50 100644 --- a/Game/WorldTile.cpp +++ b/Game/WorldTile.cpp @@ -19,3 +19,6 @@ void WorldTile::Draw() const { //utils::FillRect(m_Position.x, m_Position.y, 50, 50); } } +Collision::TileCollisionRect WorldTile::GetCollisionRect() { + return Collision::TileCollisionRect{ m_Position, GetSize(), (this)}; +} diff --git a/Game/WorldTile.h b/Game/WorldTile.h index 9426499..f0ac89a 100644 --- a/Game/WorldTile.h +++ b/Game/WorldTile.h @@ -24,7 +24,7 @@ public: GroundTileTypes GetTileType() const { return m_GroundTileType; } void SetTileType(GroundTileTypes type) { m_GroundTileType = type; } - Collision::TileCollisionRect GetCollisionRect() const { return Collision::TileCollisionRect{ m_Position, GetSize(), const_cast(this)}; } + Collision::TileCollisionRect GetCollisionRect(); private: