diff --git a/2dgk_7/2dgk_7/2dgk_7.vcxproj b/2dgk_7/2dgk_7/2dgk_7.vcxproj index e3b2e0a..5b786e2 100644 --- a/2dgk_7/2dgk_7/2dgk_7.vcxproj +++ b/2dgk_7/2dgk_7/2dgk_7.vcxproj @@ -143,6 +143,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true vcpkg_installed\x64-windows\x64-windows\include\SDL2 + stdcpp17 Console diff --git a/2dgk_7/2dgk_7/KGame.cpp b/2dgk_7/2dgk_7/KGame.cpp index 471e590..2ed17d7 100644 --- a/2dgk_7/2dgk_7/KGame.cpp +++ b/2dgk_7/2dgk_7/KGame.cpp @@ -135,7 +135,7 @@ namespace KapitanGame { switch (line[i]) { case '#': - Objects.emplace_back(std::make_shared(position, Textures["wall.bmp"])); + Objects.emplace(std::make_pair(static_cast(i), y), std::make_shared(position, Textures["wall.bmp"])); break; case ' ': FreePositions.emplace_back(position); @@ -157,8 +157,7 @@ namespace KapitanGame { { Pawns.clear(); std::shuffle(FreePositions.begin(), FreePositions.end(), Utils::GetRandomEngine()); - Objects.emplace_back(std::make_shared(FreePositions.back(), Textures["exit.bmp"])); - Exit = Objects.back(); + Exit = Objects.emplace(std::make_pair(static_cast(FreePositions.back().X / Constants::TILE_WIDTH), static_cast(FreePositions.back().Y / Constants::TILE_HEIGHT)), std::make_shared(FreePositions.back(), Textures["exit.bmp"])).first->second; FreePositions.pop_back(); Pawns.emplace_back(std::make_shared(FreePositions.back(), Textures["P1.bmp"], PlayerControllers[static_cast(KPlayer::Player1)])); @@ -383,12 +382,12 @@ namespace KapitanGame { if (Playing) { for (const auto& object : Objects) - object->Render(Renderer, cameraInUse); + object.second->Render(Renderer, cameraInUse); for (const auto& pawn : Pawns) { pawn->Render(Renderer, cameraInUse); } if (const auto exit = Exit.lock()) { - const float exitX = camera.GetViewport().x + Constants::SCREEN_WIDTH / 2.f - Textures["arrow.bmp"].GetWidth() / 2.f - exit->GetPosition().X+exit->GetCollider()->GetWidth()/2.f; + const float exitX = camera.GetViewport().x + Constants::SCREEN_WIDTH / 2.f - Textures["arrow.bmp"].GetWidth() / 2.f - exit->GetPosition().X + exit->GetCollider()->GetWidth() / 2.f; const float exitY = camera.GetViewport().y + 25.f - exit->GetPosition().Y + exit->GetCollider()->GetHeight() / 2.f; const double degrees = atan2(-exitX, exitY) * (180.f / M_PI); Textures["arrow.bmp"].RenderEx(Renderer, Constants::SCREEN_WIDTH / 2.f - Textures["arrow.bmp"].GetWidth() / 2.f, 25.f, degrees); diff --git a/2dgk_7/2dgk_7/KGame.h b/2dgk_7/2dgk_7/KGame.h index 9a352a2..79ad0c6 100644 --- a/2dgk_7/2dgk_7/KGame.h +++ b/2dgk_7/2dgk_7/KGame.h @@ -7,6 +7,7 @@ #include "KFont.h" #include "KInput.h" +#include "Utils.h" namespace KapitanGame { @@ -29,7 +30,7 @@ namespace KapitanGame { SDL_Renderer* Renderer = nullptr; - std::vector> Objects; + std::unordered_map, std::shared_ptr, Utils::PairHash> Objects; std::vector> Pawns; std::vector> PlayerControllers; std::unordered_map Textures; diff --git a/2dgk_7/2dgk_7/KPawn.cpp b/2dgk_7/2dgk_7/KPawn.cpp index 445e6b9..e1dd296 100644 --- a/2dgk_7/2dgk_7/KPawn.cpp +++ b/2dgk_7/2dgk_7/KPawn.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "Constants.h" #include "KPlayerController.h" @@ -9,21 +10,32 @@ namespace KapitanGame { - void KPawn::CollisionDetectionStep(const std::vector>& objects) + void KPawn::CollisionDetectionStep(const std::unordered_map, std::shared_ptr, Utils::PairHash>& objects) { if (GetCollider() == nullptr) return; - for (auto& other : objects) { - if (other->GetCollider() == nullptr) continue; - if (other->Id == Id) continue; - if (GetCollider()->IsCollision(other->GetCollider())) { - if (typeid(*other) == typeid(KExit)) { - if (const auto pc = PlayerController.lock()) { - pc->NotifyWin(); + + const auto xPos = static_cast(GetPosition().X / Constants::TILE_WIDTH); + const auto yPos = static_cast(GetPosition().Y / Constants::TILE_HEIGHT); + + for (const auto& [oX, oY] : std::initializer_list>{ {0, 0}, {-1,0}, {1,0}, {0,-1}, {0,1}, {-1,-1}, {1,1}, {1,-1}, {-1,1} }) + { + try { + const auto& other = objects.at({ xPos + oX, yPos + oY }); + if (other->GetCollider() == nullptr) continue; + if (other->Id == Id) continue; + if (GetCollider()->IsCollision(other->GetCollider())) { + if (typeid(*other) == typeid(KExit)) { + if (const auto pc = PlayerController.lock()) { + pc->NotifyWin(); + } + return; } - return; + const auto separationVector = GetCollider()->GetSeparationVector(other->GetCollider()); + Position += separationVector; } - const auto separationVector = GetCollider()->GetSeparationVector(other->GetCollider()); - Position += separationVector; + } + catch (std::out_of_range&) + { } } } diff --git a/2dgk_7/2dgk_7/KPawn.h b/2dgk_7/2dgk_7/KPawn.h index f49159d..cb72136 100644 --- a/2dgk_7/2dgk_7/KPawn.h +++ b/2dgk_7/2dgk_7/KPawn.h @@ -1,8 +1,9 @@ #pragma once #include -#include +#include #include "KObject.h" +#include "Utils.h" namespace KapitanGame { @@ -17,7 +18,7 @@ namespace KapitanGame PlayerController(playerController) { } - void CollisionDetectionStep(const std::vector>& objects); + void CollisionDetectionStep(const std::unordered_map, std::shared_ptr, Utils::PairHash>& objects); void MovementStep(const float& timeStep); void CollisionDetectionWithMapStep(const SDL_FRect& map); void AddMovementInput(const KVector2D& input); diff --git a/2dgk_7/2dgk_7/Utils.h b/2dgk_7/2dgk_7/Utils.h index 4b4ce7f..27834de 100644 --- a/2dgk_7/2dgk_7/Utils.h +++ b/2dgk_7/2dgk_7/Utils.h @@ -96,5 +96,14 @@ namespace KapitanGame { } typedef Iterator KPlayerIterator; + + struct PairHash { + template + std::size_t operator () (const std::pair& p) const { + auto h1 = std::hash{}(p.first); + auto h2 = std::hash{}(p.second); + return h1 ^ h2; + } + }; } }