From 3e9c83428df7a55fd671a808d7d0028b743a6596 Mon Sep 17 00:00:00 2001 From: Tamir Atias Date: Sun, 5 Feb 2012 17:54:11 +0200 Subject: [PATCH] [Fix] Collision testing is now more accurate. --- src/libUnuk/Engine/Character.cpp | 6 +++- src/libUnuk/Engine/Character.h | 12 ++++--- src/libUnuk/Engine/WorldManager.cpp | 17 ++++++++++ src/libUnuk/Engine/WorldManager.h | 3 ++ src/libUnuk/LevelGen/LevelGen.cpp | 51 +++++++++++++++++++++++++++++ src/libUnuk/LevelGen/LevelGen.h | 4 +++ 6 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/libUnuk/Engine/Character.cpp b/src/libUnuk/Engine/Character.cpp index b8b9f4e..5ff3d93 100644 --- a/src/libUnuk/Engine/Character.cpp +++ b/src/libUnuk/Engine/Character.cpp @@ -157,6 +157,9 @@ void Character::OnAttack(void) { } void Character::Move(void) { + map->MoveIfPossible(this, xVel, yVel); + + /* x += xVel; tileX = (int)(((x + (w / 2)) / TILE_WIDTH)); tileY = (int)(((y + (h / 2)) / TILE_HEIGHT)); @@ -175,7 +178,8 @@ void Character::Move(void) { if(CheckTileCollisions()) y -= yVel; if(CheckEntityCollisions()) y -= yVel; if(CheckCharacterCollisions()) y -= yVel; - + */ + _healthBar.SetXY((int)x, (int)(y - _healthBar.GetHeight() - 5)); } diff --git a/src/libUnuk/Engine/Character.h b/src/libUnuk/Engine/Character.h index 5983953..8b6c23c 100644 --- a/src/libUnuk/Engine/Character.h +++ b/src/libUnuk/Engine/Character.h @@ -62,11 +62,13 @@ public: // inline void operator delete [](void* object) { // gMemManager.Free(object); // } - - static const int FACING_UP = 0; - static const int FACING_RIGHT = 1; - static const int FACING_DOWN = 2; - static const int FACING_LEFT = 3; + + enum { + FACING_UP, + FACING_RIGHT, + FACING_DOWN, + FACING_LEFT + }; protected: void Move(void); diff --git a/src/libUnuk/Engine/WorldManager.cpp b/src/libUnuk/Engine/WorldManager.cpp index b0d273b..a54c53e 100644 --- a/src/libUnuk/Engine/WorldManager.cpp +++ b/src/libUnuk/Engine/WorldManager.cpp @@ -75,6 +75,23 @@ void WorldManager::CreateNPC(int x, int y) { _npcs.push_back(npc); } +bool WorldManager::CheckCollision(const SDL_Rect& charRect) { + for(std::list::iterator i = _npcs.begin(); i != _npcs.end(); ++i) { + NPC* npc = (*i); + + SDL_Rect npcRect; + npcRect.x = npc->GetX(); + npcRect.y = npc->GetY(); + npcRect.w = npc->GetWidth(); + npcRect.h = npc->GetHeight(); + + if(CheckCollisionRect(npcRect, charRect)) { + return true; + } + } + return false; +} + void WorldManager::OnPlayerAttack(Player* player) { int playerX = (int)(player->GetX() / 32.0f); int playerY = (int)(player->GetY() / 32.0f); diff --git a/src/libUnuk/Engine/WorldManager.h b/src/libUnuk/Engine/WorldManager.h index e161d0f..12a7309 100644 --- a/src/libUnuk/Engine/WorldManager.h +++ b/src/libUnuk/Engine/WorldManager.h @@ -5,6 +5,8 @@ class NPC; class Player; class LevelGen; +#include + class WorldManager { public: WorldManager(LevelGen* level); @@ -19,6 +21,7 @@ public: NPC* GetNPCAt(int xArg, int yArg); void CreateNPC(int x, int y); + bool CheckCollision(const SDL_Rect& charRect); int GetNPCCount() { return _npcs.size(); } diff --git a/src/libUnuk/LevelGen/LevelGen.cpp b/src/libUnuk/LevelGen/LevelGen.cpp index bf5e658..719d27f 100644 --- a/src/libUnuk/LevelGen/LevelGen.cpp +++ b/src/libUnuk/LevelGen/LevelGen.cpp @@ -297,6 +297,57 @@ void LevelGen::GenerateEnemies(void) { } } +void LevelGen::MoveIfPossible(Character* character, float xVel, float yVel) { + if(xVel == 0.0f && yVel == 0.0f) { + return; + } + + int targetX = character->GetX() + xVel; + int targetY = character->GetY() + yVel; + + if(targetX < 0 || targetX > (SCREEN_WIDTH - character->GetWidth()) || + targetY < 0 || targetY > (SCREEN_HEIGHT - character->GetHeight())) { + return; + } + + int targetTileX = targetX / TILE_WIDTH; + int targetTileY = targetY / TILE_HEIGHT; + + if(_tile[targetTileX][targetTileY].GetTileSolidity()) { + return; + } + + SDL_Rect charRect; + charRect.x = targetX; + charRect.y = targetY + (character->GetHeight() / 2); + charRect.w = character->GetWidth(); + charRect.h = character->GetHeight() / 2; + + for(int x = 0; x < BOUNDARIES_X; x++) { + for(int y = 0; y < BOUNDARIES_Y; y++) { + if(!_tile[x][y].GetEntitySolitity()) { + continue; + } + + SDL_Rect entityRect; + entityRect.x = _tile[x][y].GetEntityX(); + entityRect.y = _tile[x][y].GetEntityY(); + entityRect.w = _tile[x][y].GetEntityWidth(); + entityRect.h = _tile[x][y].GetEntityHeight(); + + if(CheckCollisionRect(entityRect, charRect)) { + return; + } + } + } + + if(_world.CheckCollision(charRect)) { + return; + } + + character->SetXY(targetX, targetY); +} + string LevelGen::GetCurrentMap(void) { return _currentMap; } diff --git a/src/libUnuk/LevelGen/LevelGen.h b/src/libUnuk/LevelGen/LevelGen.h index b1d1e88..f299eb0 100644 --- a/src/libUnuk/LevelGen/LevelGen.h +++ b/src/libUnuk/LevelGen/LevelGen.h @@ -16,6 +16,8 @@ #include "../Engine/WorldManager.h" using namespace std; +class Character; + class LevelGen { public: LevelGen(void); @@ -46,6 +48,8 @@ public: string GetCurrentMap(void); WorldManager& GetWorld(void) { return _world; } + + void MoveIfPossible(Character* character, float xVel, float yVel); private: void Unload(void);