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;
+ }
+ };
}
}