From 688ae3b0103913a7296d77697cffe7b825e4b250 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 6 Sep 2020 16:12:13 +0100 Subject: [PATCH] entity collision and player health --- The Great Machine/Collisions.cpp | 42 +++++++++++++++++++++++++++++--- The Great Machine/Collisions.hpp | 7 +++++- The Great Machine/Dungeon.cpp | 33 ++++++++++++++++++------- The Great Machine/Things.hpp | 1 + The Great Machine/main.cpp | 10 +++++++- 5 files changed, 78 insertions(+), 15 deletions(-) diff --git a/The Great Machine/Collisions.cpp b/The Great Machine/Collisions.cpp index 9c7cdb9..cfd747a 100644 --- a/The Great Machine/Collisions.cpp +++ b/The Great Machine/Collisions.cpp @@ -5,18 +5,21 @@ #include "Camera.hpp" #include "Collisions.hpp" -bool EntityCollide(Entity* entity, std::vector& nearby, int tileSize, CollisionInfo* info, olc::PixelGameEngine* engine) +static bool ShowCollisionDebug = false; + +void CollisionTick(olc::PixelGameEngine* engine) { - static bool ShowCollisionDebug = false; if (engine->GetKey(olc::P).bPressed) ShowCollisionDebug = !ShowCollisionDebug; - +} + +bool EntityCollideDungeon(Entity* entity, std::vector& nearby, int tileSize, CollisionInfo* info, olc::PixelGameEngine* engine) +{ if (!entity->HitBox) return false; static Logger& _Logger = Logger::getInstance(); engine->SetDrawTarget(1); - engine->Clear(olc::BLANK); float entityX = static_cast(entity->Coords.x - entity->TrackingCamera->Coords.x); float entityY = static_cast(entity->Coords.y - entity->TrackingCamera->Coords.y); @@ -68,3 +71,34 @@ bool EntityCollide(Entity* entity, std::vector& nearby, int tileSize, Col return false; } +bool EntityCollide(Entity* e1, Entity* e2, olc::PixelGameEngine* engine) +{ + if (!e1->HitBox || !e2->HitBox) return false; + + static Logger& _Logger = Logger::getInstance(); + + engine->SetDrawTarget(1); + + float e1X = static_cast((e1->Coords.x - e1->TrackingCamera->Coords.x) + static_cast(e1->HitBox->x)); + float e1Y = static_cast((e1->Coords.y - e1->TrackingCamera->Coords.y) + static_cast(e1->HitBox->y)); + float e1W = static_cast(e1->HitBox->w); + float e1H = static_cast(e1->HitBox->h); + + float e2X = static_cast((e2->Coords.x - e1->TrackingCamera->Coords.x) + static_cast(e2->HitBox->x)); + float e2Y = static_cast((e2->Coords.y - e1->TrackingCamera->Coords.y) + static_cast(e2->HitBox->y)); + float e2W = static_cast(e2->HitBox->w); + float e2H = static_cast(e2->HitBox->h); + + bool xOverlaps = (e1X <= e2X + e2W) && (e1X + e1W >= e2X); + bool yOverlaps = (e1Y <= e2Y + e2H) && (e1Y + e1H >= e2Y); + + bool collision = xOverlaps && yOverlaps; + if (ShowCollisionDebug) + { + engine->DrawRect(e1X, e1Y, e1W, e1H, collision ? olc::BLUE : olc::RED); + engine->DrawRect(e2X, e2Y, e2W, e2H, collision ? olc::BLUE : olc::RED); + } + + return collision; +} + diff --git a/The Great Machine/Collisions.hpp b/The Great Machine/Collisions.hpp index 4889718..46631e7 100644 --- a/The Great Machine/Collisions.hpp +++ b/The Great Machine/Collisions.hpp @@ -19,12 +19,17 @@ class CollisionInfo { public: Tile* TileCollided; + Entity* EntityCollided; bool CollidingX; bool CollidingY; }; -bool EntityCollide(Entity* entity, std::vector& nearby, int tileSize, CollisionInfo* info, olc::PixelGameEngine* engine); +void CollisionTick(olc::PixelGameEngine* engine); +bool EntityCollideDungeon(Entity* entity, std::vector& nearby, int tileSize, CollisionInfo* info, olc::PixelGameEngine* engine); + +// e1 needs to have a camera +bool EntityCollide(Entity* e1, Entity* e2, olc::PixelGameEngine* engine); #endif diff --git a/The Great Machine/Dungeon.cpp b/The Great Machine/Dungeon.cpp index 5447d2f..a97b5a8 100644 --- a/The Great Machine/Dungeon.cpp +++ b/The Great Machine/Dungeon.cpp @@ -406,8 +406,6 @@ void Dungeon::Input(olc::PixelGameEngine* engine, float fTime) Player->Animator->SetState(state); lastState = state; - - // Map collisions olc::vi2d currentTile = { static_cast(Player->Coords.x / TileSize), static_cast(Player->Coords.y / TileSize) }; @@ -451,7 +449,7 @@ void Dungeon::Input(olc::PixelGameEngine* engine, float fTime) // Passes ownership back CollisionInfo collisionInfo; - bool colliding = EntityCollide(Player, nearbyCollidables, TileSize, &collisionInfo, engine); + bool colliding = EntityCollideDungeon(Player, nearbyCollidables, TileSize, &collisionInfo, engine); // collision response if (colliding) @@ -482,9 +480,17 @@ float vecDistance(T v1, T v2) void Dungeon::Update(olc::PixelGameEngine* engine, float fTime) { ActiveCamera->Update(fTime); + CollisionTick(engine); if (!HasBegun) return; + engine->SetDrawTarget(1); + + int enemyBoundsLeft = static_cast(Player->Coords.x - (1280.0f / 2.0f)); + int enemyBoundsTop = static_cast(Player->Coords.y - (720.0f / 2.0f)); + int enemyBoundsRight = enemyBoundsLeft + 1280.0f; + int enemyBoundsBottom = enemyBoundsTop + 720.0f; + // spawn enemies if (rand() % 100 < 1) { @@ -492,11 +498,22 @@ void Dungeon::Update(olc::PixelGameEngine* engine, float fTime) enemy->Type = EEntity::Type::Enemy; enemy->Renderable = EnemyRenderable; enemy->Animator = EnemyAnimator; - enemy->Coords = { static_cast(((float)rand() / (float)RAND_MAX) * 1280.0f), static_cast(((float)rand() / (float)RAND_MAX) * 720.0f) }; + + // This is naive I KNOW. fuck off + // stops integer divisions by 0 + if (enemyBoundsLeft == 0) enemyBoundsLeft = 1; + if (enemyBoundsTop == 0) enemyBoundsTop = 1; + + auto rangedRand = [](float min, float max) -> int { + return static_cast(min) + rand() % ((static_cast(max) + 1) - static_cast(min)); + }; + + enemy->Coords = { static_cast(rangedRand(enemyBoundsLeft, enemyBoundsRight)), static_cast(rangedRand(enemyBoundsTop, enemyBoundsBottom) ) }; + enemy->dxdy = { static_cast(rand() % 10 - 5), static_cast(rand() % 10 - 5) }; float distanceFromPlayer = vecDistance(Player->Coords, enemy->Coords); - _Logger.Debug(enemy->Coords.x, " ", enemy->Coords.y); + _Logger.Debug(enemy->Coords.x, " ", enemy->Coords.y, " ", distanceFromPlayer); if (distanceFromPlayer > 100) { enemy->HitBox = new Collider{ 0, 0, 28, 36 }; @@ -515,6 +532,8 @@ void Dungeon::Update(olc::PixelGameEngine* engine, float fTime) { enemy->dxdy = static_cast(TileSize) * (fTime * (Player->Speed / 1.5f) * olc::vf2d(desiredLocation - enemy->Coords).norm()); + EntityCollide(Player, enemy, engine); + enemy->Coords += enemy->dxdy; } @@ -539,7 +558,6 @@ void Dungeon::Draw(olc::PixelGameEngine* engine, float fTime) // Dungeon Layer engine->SetDrawTarget(4); - engine->Clear({38, 36, 40}); engine->SetPixelMode(olc::Pixel::ALPHA); for (std::pair tile : DungeonTiles) @@ -549,7 +567,6 @@ void Dungeon::Draw(olc::PixelGameEngine* engine, float fTime) // Entity Layer engine->SetDrawTarget(3); - engine->Clear(olc::BLANK); // Draw character Player->Animator->Draw(fTime, {Player->Coords.x - ActiveCamera->Coords.x, Player->Coords.y - ActiveCamera->Coords.y}); @@ -562,7 +579,6 @@ void Dungeon::Draw(olc::PixelGameEngine* engine, float fTime) // Lighting layers engine->SetDrawTarget(2); - engine->Clear(olc::BLANK); static bool WasFireLit = false; static bool HasFireLit = false; @@ -631,7 +647,6 @@ void Dungeon::Draw(olc::PixelGameEngine* engine, float fTime) // UI Layer engine->SetDrawTarget(1); - engine->Clear(olc::BLANK); engine->DrawString({15, 15}, std::to_string(Enemies.size()), olc::WHITE, 5); diff --git a/The Great Machine/Things.hpp b/The Great Machine/Things.hpp index 6abca61..80dcfe5 100644 --- a/The Great Machine/Things.hpp +++ b/The Great Machine/Things.hpp @@ -124,6 +124,7 @@ class FixedItem : public Entity class Playable : public Entity { public: + int Health = 100; float Speed = 4.0f; int SelectedInventoryItem = 0; std::array Inventory; diff --git a/The Great Machine/main.cpp b/The Great Machine/main.cpp index 4c9c0ee..d2cd577 100644 --- a/The Great Machine/main.cpp +++ b/The Great Machine/main.cpp @@ -51,8 +51,16 @@ class Game : public olc::PixelGameEngine SetDrawTarget(uint8_t(0)); Clear(olc::BLANK); + SetDrawTarget(uint8_t(1)); + Clear(olc::BLANK); + SetDrawTarget(uint8_t(2)); + Clear(olc::BLANK); + SetDrawTarget(uint8_t(3)); + Clear(olc::BLANK); + SetDrawTarget(uint8_t(4)); + Clear({38, 36, 40}); - // goto bruh; + goto bruh; if (_TimeAccumilator < 6.0f) {