Zad2 final v2 - fix collision

This commit is contained in:
Michał Leśniak 2021-12-13 22:56:37 +01:00
parent 4960cdb39b
commit d2556a6579
6 changed files with 42 additions and 19 deletions

View File

@ -143,6 +143,7 @@
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>vcpkg_installed\x64-windows\x64-windows\include\SDL2</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>vcpkg_installed\x64-windows\x64-windows\include\SDL2</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

View File

@ -135,7 +135,7 @@ namespace KapitanGame {
switch (line[i]) switch (line[i])
{ {
case '#': case '#':
Objects.emplace_back(std::make_shared<KWall>(position, Textures["wall.bmp"])); Objects.emplace(std::make_pair(static_cast<int>(i), y), std::make_shared<KWall>(position, Textures["wall.bmp"]));
break; break;
case ' ': case ' ':
FreePositions.emplace_back(position); FreePositions.emplace_back(position);
@ -157,8 +157,7 @@ namespace KapitanGame {
{ {
Pawns.clear(); Pawns.clear();
std::shuffle(FreePositions.begin(), FreePositions.end(), Utils::GetRandomEngine()); std::shuffle(FreePositions.begin(), FreePositions.end(), Utils::GetRandomEngine());
Objects.emplace_back(std::make_shared<KExit>(FreePositions.back(), Textures["exit.bmp"])); Exit = Objects.emplace(std::make_pair(static_cast<int>(FreePositions.back().X / Constants::TILE_WIDTH), static_cast<int>(FreePositions.back().Y / Constants::TILE_HEIGHT)), std::make_shared<KExit>(FreePositions.back(), Textures["exit.bmp"])).first->second;
Exit = Objects.back();
FreePositions.pop_back(); FreePositions.pop_back();
Pawns.emplace_back(std::make_shared<KCirclePawn>(FreePositions.back(), Textures["P1.bmp"], PlayerControllers[static_cast<int>(KPlayer::Player1)])); Pawns.emplace_back(std::make_shared<KCirclePawn>(FreePositions.back(), Textures["P1.bmp"], PlayerControllers[static_cast<int>(KPlayer::Player1)]));
@ -383,12 +382,12 @@ namespace KapitanGame {
if (Playing) { if (Playing) {
for (const auto& object : Objects) for (const auto& object : Objects)
object->Render(Renderer, cameraInUse); object.second->Render(Renderer, cameraInUse);
for (const auto& pawn : Pawns) { for (const auto& pawn : Pawns) {
pawn->Render(Renderer, cameraInUse); pawn->Render(Renderer, cameraInUse);
} }
if (const auto exit = Exit.lock()) { 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 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); 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); Textures["arrow.bmp"].RenderEx(Renderer, Constants::SCREEN_WIDTH / 2.f - Textures["arrow.bmp"].GetWidth() / 2.f, 25.f, degrees);

View File

@ -7,6 +7,7 @@
#include "KFont.h" #include "KFont.h"
#include "KInput.h" #include "KInput.h"
#include "Utils.h"
namespace KapitanGame { namespace KapitanGame {
@ -29,7 +30,7 @@ namespace KapitanGame {
SDL_Renderer* Renderer = nullptr; SDL_Renderer* Renderer = nullptr;
std::vector<std::shared_ptr<KObject>> Objects; std::unordered_map<std::pair<int, int>, std::shared_ptr<KObject>, Utils::PairHash> Objects;
std::vector<std::shared_ptr<KPawn>> Pawns; std::vector<std::shared_ptr<KPawn>> Pawns;
std::vector<std::shared_ptr<KPlayerController>> PlayerControllers; std::vector<std::shared_ptr<KPlayerController>> PlayerControllers;
std::unordered_map<std::string, KTexture> Textures; std::unordered_map<std::string, KTexture> Textures;

View File

@ -2,6 +2,7 @@
#include <memory> #include <memory>
#include <typeinfo> #include <typeinfo>
#include <unordered_map>
#include "Constants.h" #include "Constants.h"
#include "KPlayerController.h" #include "KPlayerController.h"
@ -9,21 +10,32 @@
namespace KapitanGame namespace KapitanGame
{ {
void KPawn::CollisionDetectionStep(const std::vector<std::shared_ptr<KObject>>& objects) void KPawn::CollisionDetectionStep(const std::unordered_map<std::pair<int, int>, std::shared_ptr<KObject>, Utils::PairHash>& objects)
{ {
if (GetCollider() == nullptr) return; if (GetCollider() == nullptr) return;
for (auto& other : objects) {
if (other->GetCollider() == nullptr) continue; const auto xPos = static_cast<int>(GetPosition().X / Constants::TILE_WIDTH);
if (other->Id == Id) continue; const auto yPos = static_cast<int>(GetPosition().Y / Constants::TILE_HEIGHT);
if (GetCollider()->IsCollision(other->GetCollider())) {
if (typeid(*other) == typeid(KExit)) { for (const auto& [oX, oY] : std::initializer_list<std::pair<int, int>>{ {0, 0}, {-1,0}, {1,0}, {0,-1}, {0,1}, {-1,-1}, {1,1}, {1,-1}, {-1,1} })
if (const auto pc = PlayerController.lock()) { {
pc->NotifyWin(); 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&)
{
} }
} }
} }

View File

@ -1,8 +1,9 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <vector> #include <unordered_map>
#include "KObject.h" #include "KObject.h"
#include "Utils.h"
namespace KapitanGame namespace KapitanGame
{ {
@ -17,7 +18,7 @@ namespace KapitanGame
PlayerController(playerController) PlayerController(playerController)
{ {
} }
void CollisionDetectionStep(const std::vector<std::shared_ptr<KObject>>& objects); void CollisionDetectionStep(const std::unordered_map<std::pair<int, int>, std::shared_ptr<KObject>, Utils::PairHash>& objects);
void MovementStep(const float& timeStep); void MovementStep(const float& timeStep);
void CollisionDetectionWithMapStep(const SDL_FRect& map); void CollisionDetectionWithMapStep(const SDL_FRect& map);
void AddMovementInput(const KVector2D& input); void AddMovementInput(const KVector2D& input);

View File

@ -96,5 +96,14 @@ namespace KapitanGame {
} }
typedef Iterator<KPlayer, KPlayer::Player1, KPlayer::Player2> KPlayerIterator; typedef Iterator<KPlayer, KPlayer::Player1, KPlayer::Player2> KPlayerIterator;
struct PairHash {
template <class T1, class T2>
std::size_t operator () (const std::pair<T1, T2>& p) const {
auto h1 = std::hash<T1>{}(p.first);
auto h2 = std::hash<T2>{}(p.second);
return h1 ^ h2;
}
};
} }
} }