From 4960cdb39bc0b38b9214373952dcf3fceaec2e0c Mon Sep 17 00:00:00 2001 From: Kapitan Date: Sun, 12 Dec 2021 13:40:09 +0100 Subject: [PATCH] Zad2 final --- .gitattributes | 1 + 2dgk_7/2dgk_7/2dgk_7.rc | 101 ++++++ 2dgk_7/2dgk_7/2dgk_7.vcxproj | 24 +- 2dgk_7/2dgk_7/2dgk_7.vcxproj.filters | 60 +++- 2dgk_7/2dgk_7/Constants.h | 3 +- 2dgk_7/2dgk_7/KActionBind.h | 8 +- 2dgk_7/2dgk_7/KCamera.cpp | 42 +++ 2dgk_7/2dgk_7/KCamera.h | 42 +++ 2dgk_7/2dgk_7/KCircle.cpp | 124 ++++--- 2dgk_7/2dgk_7/KCircle.h | 28 +- 2dgk_7/2dgk_7/KCirclePawn.cpp | 15 + 2dgk_7/2dgk_7/KCirclePawn.h | 18 + 2dgk_7/2dgk_7/KCollider.cpp | 34 ++ 2dgk_7/2dgk_7/KCollider.h | 35 ++ 2dgk_7/2dgk_7/KExit.cpp | 9 + 2dgk_7/2dgk_7/KExit.h | 22 ++ 2dgk_7/2dgk_7/KFont.cpp | 63 ++++ 2dgk_7/2dgk_7/KFont.h | 36 ++ 2dgk_7/2dgk_7/KGame.cpp | 382 +++++++++++++++------ 2dgk_7/2dgk_7/KGame.h | 33 +- 2dgk_7/2dgk_7/KInput.cpp | 18 +- 2dgk_7/2dgk_7/KInput.h | 34 +- 2dgk_7/2dgk_7/KObject.cpp | 23 ++ 2dgk_7/2dgk_7/KObject.h | 28 ++ 2dgk_7/2dgk_7/KPawn.cpp | 46 +++ 2dgk_7/2dgk_7/KPawn.h | 29 ++ 2dgk_7/2dgk_7/KPlayer.h | 3 +- 2dgk_7/2dgk_7/KPlayerController.cpp | 30 +- 2dgk_7/2dgk_7/KPlayerController.h | 21 +- 2dgk_7/2dgk_7/KRect.cpp | 137 ++++++-- 2dgk_7/2dgk_7/KRect.h | 36 +- 2dgk_7/2dgk_7/KRectPawn.cpp | 15 + 2dgk_7/2dgk_7/KRectPawn.h | 20 ++ 2dgk_7/2dgk_7/KShape.cpp | 85 ----- 2dgk_7/2dgk_7/KShape.h | 45 --- 2dgk_7/2dgk_7/KTexture.cpp | 61 +++- 2dgk_7/2dgk_7/KTexture.h | 11 +- 2dgk_7/2dgk_7/KVector2d.h | 2 + 2dgk_7/2dgk_7/KWall.cpp | 9 + 2dgk_7/2dgk_7/KWall.h | 22 ++ 2dgk_7/2dgk_7/Utils.cpp | 11 +- 2dgk_7/2dgk_7/Utils.h | 61 +++- 2dgk_7/2dgk_7/assets/fonts/LICENSE.txt | 202 +++++++++++ 2dgk_7/2dgk_7/assets/fonts/Roboto-Thin.ttf | 3 + 2dgk_7/2dgk_7/assets/levels/level2.txt | 2 +- 2dgk_7/2dgk_7/assets/textures/P1.bmp | 2 +- 2dgk_7/2dgk_7/assets/textures/P2.bmp | 2 +- 2dgk_7/2dgk_7/assets/textures/arrow.bmp | 3 + 2dgk_7/2dgk_7/config.default.ini | 15 - 2dgk_7/2dgk_7/config.json | 16 +- 2dgk_7/2dgk_7/level.txt | 31 -- 2dgk_7/2dgk_7/resource.h | 14 + 2dgk_7/2dgk_7/vcpkg.json | 3 +- 53 files changed, 1632 insertions(+), 488 deletions(-) create mode 100644 2dgk_7/2dgk_7/2dgk_7.rc create mode 100644 2dgk_7/2dgk_7/KCamera.cpp create mode 100644 2dgk_7/2dgk_7/KCamera.h create mode 100644 2dgk_7/2dgk_7/KCirclePawn.cpp create mode 100644 2dgk_7/2dgk_7/KCirclePawn.h create mode 100644 2dgk_7/2dgk_7/KCollider.cpp create mode 100644 2dgk_7/2dgk_7/KCollider.h create mode 100644 2dgk_7/2dgk_7/KExit.cpp create mode 100644 2dgk_7/2dgk_7/KExit.h create mode 100644 2dgk_7/2dgk_7/KFont.cpp create mode 100644 2dgk_7/2dgk_7/KFont.h create mode 100644 2dgk_7/2dgk_7/KObject.cpp create mode 100644 2dgk_7/2dgk_7/KObject.h create mode 100644 2dgk_7/2dgk_7/KPawn.cpp create mode 100644 2dgk_7/2dgk_7/KPawn.h create mode 100644 2dgk_7/2dgk_7/KRectPawn.cpp create mode 100644 2dgk_7/2dgk_7/KRectPawn.h delete mode 100644 2dgk_7/2dgk_7/KShape.cpp delete mode 100644 2dgk_7/2dgk_7/KShape.h create mode 100644 2dgk_7/2dgk_7/KWall.cpp create mode 100644 2dgk_7/2dgk_7/KWall.h create mode 100644 2dgk_7/2dgk_7/assets/fonts/LICENSE.txt create mode 100644 2dgk_7/2dgk_7/assets/fonts/Roboto-Thin.ttf create mode 100644 2dgk_7/2dgk_7/assets/textures/arrow.bmp delete mode 100644 2dgk_7/2dgk_7/config.default.ini delete mode 100644 2dgk_7/2dgk_7/level.txt create mode 100644 2dgk_7/2dgk_7/resource.h diff --git a/.gitattributes b/.gitattributes index 95c1536..bba9ac7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ *.bmp filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text diff --git a/2dgk_7/2dgk_7/2dgk_7.rc b/2dgk_7/2dgk_7/2dgk_7.rc new file mode 100644 index 0000000..6e07269 --- /dev/null +++ b/2dgk_7/2dgk_7/2dgk_7.rc @@ -0,0 +1,101 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) + +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Polish (Poland) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PLK) +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041504b0" + BEGIN + VALUE "CompanyName", "Michał Leśniak" + VALUE "FileDescription", "A simple game" + VALUE "FileVersion", "1.0.0.1" + VALUE "InternalName", "2dgk_7.exe" + VALUE "LegalCopyright", "Copyright (C) 2021 Michał Leśniak" + VALUE "OriginalFilename", "2dgk_7.exe" + VALUE "ProductName", "2DKG_7" + VALUE "ProductVersion", "1.0.0.1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x415, 1200 + END +END + +#endif // Polish (Poland) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/2dgk_7/2dgk_7/2dgk_7.vcxproj b/2dgk_7/2dgk_7/2dgk_7.vcxproj index 4008330..e3b2e0a 100644 --- a/2dgk_7/2dgk_7/2dgk_7.vcxproj +++ b/2dgk_7/2dgk_7/2dgk_7.vcxproj @@ -154,13 +154,21 @@ + + + + + + - + + + @@ -172,17 +180,29 @@ + + + + + + - + + + + + + + diff --git a/2dgk_7/2dgk_7/2dgk_7.vcxproj.filters b/2dgk_7/2dgk_7/2dgk_7.vcxproj.filters index 45c7dbb..bf9d63b 100644 --- a/2dgk_7/2dgk_7/2dgk_7.vcxproj.filters +++ b/2dgk_7/2dgk_7/2dgk_7.vcxproj.filters @@ -36,12 +36,36 @@ Source Files - + Source Files Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + @@ -74,7 +98,7 @@ Header Files - + Header Files @@ -89,5 +113,37 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + \ No newline at end of file diff --git a/2dgk_7/2dgk_7/Constants.h b/2dgk_7/2dgk_7/Constants.h index 3793f52..5dab4b1 100644 --- a/2dgk_7/2dgk_7/Constants.h +++ b/2dgk_7/2dgk_7/Constants.h @@ -11,8 +11,7 @@ namespace KapitanGame { constexpr float SCREEN_RATIO = static_cast(SCREEN_WIDTH) / SCREEN_HEIGHT; constexpr int TILE_WIDTH = 32; constexpr int TILE_HEIGHT = 32; - constexpr float SPEED = 0.16f; + constexpr float SPEED = 200.f; constexpr float SMOOTH = 0.4f; - constexpr int CIRCLES_COUNT = 100; } } diff --git a/2dgk_7/2dgk_7/KActionBind.h b/2dgk_7/2dgk_7/KActionBind.h index a659e34..f2cb2de 100644 --- a/2dgk_7/2dgk_7/KActionBind.h +++ b/2dgk_7/2dgk_7/KActionBind.h @@ -10,20 +10,20 @@ namespace KapitanGame { Hold }; struct KActionBind { - KActionBind(std::string name, const InputState expectedInputState, KPlayerController* controllerObject, const KPlayerCommand command, const KPlayer player) : + KActionBind(std::string name, const InputState expectedInputState, const std::shared_ptr& controllerObject, const KPlayerCommand command, const KPlayer player) : Name(std::move(name)), ExpectedInputState(expectedInputState), ControllerObject(controllerObject), Command(command), Player(player) {} std::string Name; InputState ExpectedInputState; - KPlayerController* ControllerObject; + std::weak_ptr ControllerObject; KPlayerCommand Command; KPlayer Player; }; struct KAxisBind { - KAxisBind(std::string name, KPlayerController* controllerObject, const KPlayerAxisCommand command, const KPlayer player) : + KAxisBind(std::string name, const std::shared_ptr& controllerObject, const KPlayerAxisCommand command, const KPlayer player) : Name(std::move(name)), ControllerObject(controllerObject), AxisCommand(command), Player(player) {} std::string Name; - KPlayerController* ControllerObject; + std::weak_ptr ControllerObject; KPlayerAxisCommand AxisCommand; KPlayer Player; }; diff --git a/2dgk_7/2dgk_7/KCamera.cpp b/2dgk_7/2dgk_7/KCamera.cpp new file mode 100644 index 0000000..bb2a071 --- /dev/null +++ b/2dgk_7/2dgk_7/KCamera.cpp @@ -0,0 +1,42 @@ +#include "KCamera.h" + +#include "KPawn.h" +#include "Utils.h" + +namespace KapitanGame +{ + const SDL_FRect& KCamera::GetViewport() const + { + return Viewport; + } + + float KCamera::GetScale() const + { + return Scale; + } + + const KVector2D& KCamera::GetFocusPoint() const + { + return FocusPoint; + } + + void KCamera::Update(const std::shared_ptr& playerOne, const std::shared_ptr& playerTwo, const SDL_FRect& map) + { + FocusPoint = (playerOne->GetPosition() + playerTwo->GetPosition()) * 0.5f; + Viewport.x = Utils::Clamp(FocusPoint.X - Viewport.w / 2.f, 0.f, map.w - Viewport.w); + Viewport.y = Utils::Clamp(FocusPoint.Y - Viewport.h / 2.f, 0.f, map.h - Viewport.h); + PlayArea.x = Utils::Clamp(FocusPoint.X - PlayArea.w / 2.f, static_cast(-Constants::WINDOW_DEAD_ZONE), map.w + static_cast(Constants::WINDOW_DEAD_ZONE)); + PlayArea.y = Utils::Clamp(FocusPoint.Y - PlayArea.h / 2.f, static_cast(-Constants::WINDOW_DEAD_ZONE), map.h + static_cast(Constants::WINDOW_DEAD_ZONE)); + } + + void KCamera::SetDebug(const SDL_FRect& map) + { + Viewport = { 0,0,Constants::SCREEN_WIDTH, Constants::SCREEN_HEIGHT }; + Scale = Constants::SCREEN_RATIO > 1.f ? Constants::SCREEN_HEIGHT * 1.f / map.h : Constants::SCREEN_WIDTH * 1.f / map.w; + } + + const SDL_FRect& KCamera::GetPlayArea() const + { + return PlayArea; + } +} diff --git a/2dgk_7/2dgk_7/KCamera.h b/2dgk_7/2dgk_7/KCamera.h new file mode 100644 index 0000000..49af5a5 --- /dev/null +++ b/2dgk_7/2dgk_7/KCamera.h @@ -0,0 +1,42 @@ +#pragma once +#include +#include + +#include "Constants.h" +#include "KVector2d.h" + +namespace KapitanGame +{ + class KPawn; + + class KCamera + { + public: + explicit KCamera(const SDL_FRect& map) + : Viewport({ + (map.w - Constants::SCREEN_WIDTH) / 2.f, (map.h - Constants::SCREEN_HEIGHT) / 2.f, + Constants::SCREEN_WIDTH * 1.f, + Constants::SCREEN_HEIGHT * 1.f + }), PlayArea({ + 0, 0, + Constants::SCREEN_WIDTH - Constants::WINDOW_DEAD_ZONE, + Constants::SCREEN_HEIGHT - Constants::WINDOW_DEAD_ZONE + }), FocusPoint(Viewport.x + Viewport.w / 2, Viewport.y + Viewport.h / 2), + Scale(1.f) + { + } + + const SDL_FRect& GetViewport() const; + float GetScale() const; + const KVector2D& GetFocusPoint() const; + void Update(const std::shared_ptr& playerOne, const std::shared_ptr& playerTwo, const SDL_FRect& map); + void SetDebug(const SDL_FRect& map); + const SDL_FRect& GetPlayArea() const; + private: + SDL_FRect Viewport; + SDL_FRect PlayArea; + KVector2D FocusPoint; + float Scale; + }; +} + diff --git a/2dgk_7/2dgk_7/KCircle.cpp b/2dgk_7/2dgk_7/KCircle.cpp index df88d83..51d562c 100644 --- a/2dgk_7/2dgk_7/KCircle.cpp +++ b/2dgk_7/2dgk_7/KCircle.cpp @@ -1,70 +1,106 @@ #include "KCircle.h" +#include + #include "KRect.h" #include "Utils.h" namespace KapitanGame { - - KCircle::KCircle(const KVector2D& position, const KVector2D& velocity, const float& radius, const KTexture& texture) : KShape(position, velocity, texture), - Radius(radius) { + bool KCircle::IsCollision(const KCircle* other) const { + return (GetParent()->GetPosition() - other->GetParent()->GetPosition()).Length() < Radius + other->Radius; } - bool KCircle::IsCollision(const KCircle& other) const { - return (Position - other.Position).Length() < Radius + other.Radius; + bool KCircle::IsCollision(const KCollider* other) const + { + const auto circle = dynamic_cast(other); + if (circle != nullptr) + return IsCollision(circle); + + + const auto rect = dynamic_cast(other); + if (rect != nullptr) + return IsCollision(rect); + + throw std::runtime_error("unsupported shape"); } - bool KCircle::IsCollision(const KRect& other) const { - const auto f = KVector2D(Utils::Clamp(Position.X, other.GetPosition().X - other.GetWidth() / 2, other.GetPosition().X + other.GetWidth() / 2), - Utils::Clamp(Position.Y, other.GetPosition().Y - other.GetHeight() / 2, other.GetPosition().Y + other.GetHeight() / 2)); + KVector2D KCircle::GetSeparationVector(const KCollider* other) const + { + const auto circle = dynamic_cast(other); + if (circle != nullptr) + return GetSeparationVector(circle); - return (Position - f).Length() < Radius; + const auto rect = dynamic_cast(other); + if (rect != nullptr) + return GetSeparationVector(rect); + + throw std::runtime_error("unsupported shape"); } - KVector2D KCircle::GetSeparationVector(const KCircle& other) const { - const KVector2D centerDiff = Position - other.Position; + bool KCircle::IsCollision(const KRect* other) const { + const auto f = KVector2D(Utils::Clamp(GetParent()->GetPosition().X, other->GetParent()->GetPosition().X - other->GetWidth() / 2, other->GetParent()->GetPosition().X + other->GetWidth() / 2), + Utils::Clamp(GetParent()->GetPosition().Y, other->GetParent()->GetPosition().Y - other->GetHeight() / 2, other->GetParent()->GetPosition().Y + other->GetHeight() / 2)); + + return (GetParent()->GetPosition() - f).Length() < Radius; + } + + KVector2D KCircle::GetSeparationVector(const KCircle* other) const { + const KVector2D centerDiff = GetParent()->GetPosition() - other->GetParent()->GetPosition(); const float centerDiffLength = centerDiff.Length(); - return centerDiff / centerDiffLength * (Radius + other.Radius - centerDiffLength); + return centerDiff / centerDiffLength * (Radius + other->Radius - centerDiffLength); } - KVector2D KCircle::GetSeparationVector(const KRect& other) const { - const float l = other.GetPosition().X - other.GetWidth() / 2; - const float r = other.GetPosition().X + other.GetWidth() / 2; - const float t = other.GetPosition().Y - other.GetHeight() / 2; - const float b = other.GetPosition().Y + other.GetHeight() / 2; - const auto f = KVector2D(Utils::Clamp(Position.X, l, r), - Utils::Clamp(Position.Y, t, b)); + KVector2D KCircle::GetSeparationVector(const KRect* other) const { + const float l = other->GetParent()->GetPosition().X - other->GetWidth() / 2; + const float r = other->GetParent()->GetPosition().X + other->GetWidth() / 2; + const float t = other->GetParent()->GetPosition().Y - other->GetHeight() / 2; + const float b = other->GetParent()->GetPosition().Y + other->GetHeight() / 2; + const auto f = KVector2D(Utils::Clamp(GetParent()->GetPosition().X, l, r), + Utils::Clamp(GetParent()->GetPosition().Y, t, b)); - if (Position == f) { - const auto left = Position.X - l + Radius; - const auto right = r - Position.X + Radius; - const auto top = Position.Y - t + Radius; - const auto bottom = b - Position.Y + Radius; + if (GetParent()->GetPosition() == f) { + const auto left = GetParent()->GetPosition().X - l + Radius; + const auto right = r - GetParent()->GetPosition().X + Radius; + const auto top = GetParent()->GetPosition().Y - t + Radius; + const auto bottom = b - GetParent()->GetPosition().Y + Radius; return KRect::GetSeparationVector(left, right, top, bottom); } - return (Position - f) / (Position - f).Length() * (Radius - (Position - f).Length()); + return (GetParent()->GetPosition() - f) / (GetParent()->GetPosition() - f).Length() * (Radius - (GetParent()->GetPosition() - f).Length()); } - void KCircle::CollisionDetectionWithMapStep(const SDL_Rect& map) { + KVector2D KCircle::GetSeparationVector(const SDL_FRect& map) const { + KVector2D separationVector{ 0.f,0.f }; + if (GetParent()->GetPosition().X - map.x - Radius < 0) + { + separationVector.X += -(GetParent()->GetPosition().X - map.x - Radius); + } + if (GetParent()->GetPosition().X + Radius - (map.x + map.w) > 0) + { + separationVector.X += -(GetParent()->GetPosition().X - (map.x+map.w) + Radius); + } + if (GetParent()->GetPosition().Y - Radius - map.y < 0) { + separationVector.Y += -(GetParent()->GetPosition().Y - map.y - Radius); + } + if (GetParent()->GetPosition().Y + Radius - (map.y + map.h) > 0) { + separationVector.Y += -(GetParent()->GetPosition().Y - (map.y + map.h) + Radius); + } + return separationVector; + } - if (Position.X - map.x - Radius < 0) - { - Position.X += -(Position.X - map.x - Radius); - Velocity = Velocity.Reflect({ -1.f, 0.f }); - } - if (Position.X + Radius - map.w > 0) - { - Velocity = Velocity.Reflect({ 1.f, 0.f }); - Position.X += -(Position.X - map.w + Radius); - } - if (Position.Y - Radius - map.y < 0) { - Position.Y += -(Position.Y - map.y - Radius); - Velocity = Velocity.Reflect({ 0.f, 1.f }); - } - if (Position.Y + Radius - map.h > 0) { - Position.Y += -(Position.Y - map.h + Radius); - Velocity = Velocity.Reflect({ 0.f, -1.f }); - } + float KCircle::GetWidth() const + { + return Radius * 2; + } + + float KCircle::GetHeight() const + { + return Radius * 2; + } + + KCircle::KCircle(KObject* parent, const float radius): KCollider(parent), + Radius(radius) + { } float KCircle::GetRadius() const { diff --git a/2dgk_7/2dgk_7/KCircle.h b/2dgk_7/2dgk_7/KCircle.h index 8816b59..a4db204 100644 --- a/2dgk_7/2dgk_7/KCircle.h +++ b/2dgk_7/2dgk_7/KCircle.h @@ -1,21 +1,29 @@ #pragma once -#include "KShape.h" -#include "KTexture.h" +#include + +#include "KCollider.h" #include "KVector2d.h" namespace KapitanGame { - class KCircle final : public KShape + class KRect; + + class KCircle final : public KCollider { public: - KCircle(const KVector2D& position, const KVector2D& velocity, const float& radius, const KTexture& texture); - void CollisionDetectionWithMapStep(const SDL_Rect& map) override; + KCircle(KObject* parent, const float radius); float GetRadius() const; - protected: - KVector2D GetSeparationVector(const KCircle& other) const override; - KVector2D GetSeparationVector(const KRect& other) const override; - bool IsCollision(const KCircle& other) const override; - bool IsCollision(const KRect& other) const override; + private: + KVector2D GetSeparationVector(const KCircle* other) const; + KVector2D GetSeparationVector(const KRect* other) const; + bool IsCollision(const KCircle* other) const; + bool IsCollision(const KRect* other) const; + public: + bool IsCollision(const KCollider* other) const override; + KVector2D GetSeparationVector(const KCollider* other) const override; + KVector2D GetSeparationVector(const SDL_FRect& map) const override; + float GetWidth() const override; + float GetHeight() const override; private: float Radius{ 1.f }; }; diff --git a/2dgk_7/2dgk_7/KCirclePawn.cpp b/2dgk_7/2dgk_7/KCirclePawn.cpp new file mode 100644 index 0000000..4e8a2dc --- /dev/null +++ b/2dgk_7/2dgk_7/KCirclePawn.cpp @@ -0,0 +1,15 @@ +#include "KCirclePawn.h" + +namespace KapitanGame +{ + KCirclePawn::KCirclePawn(const KVector2D& position, const KTexture& texture, + const std::shared_ptr& playerController) : KPawn(position, texture, playerController), + Collider(this, static_cast(texture.GetWidth())/2.0f) + { + } + + const KCollider* KCirclePawn::GetCollider() const + { + return &Collider; + } +} diff --git a/2dgk_7/2dgk_7/KCirclePawn.h b/2dgk_7/2dgk_7/KCirclePawn.h new file mode 100644 index 0000000..9ffac03 --- /dev/null +++ b/2dgk_7/2dgk_7/KCirclePawn.h @@ -0,0 +1,18 @@ +#pragma once +#include "KCircle.h" +#include "KPawn.h" + +namespace KapitanGame +{ + class KCirclePawn final :public KPawn + { + public: + KCirclePawn(const KVector2D& position, const KTexture& texture, + const std::shared_ptr& playerController); + + const KCollider* GetCollider() const override; + private: + KCircle Collider; + }; +} + diff --git a/2dgk_7/2dgk_7/KCollider.cpp b/2dgk_7/2dgk_7/KCollider.cpp new file mode 100644 index 0000000..feaa9fe --- /dev/null +++ b/2dgk_7/2dgk_7/KCollider.cpp @@ -0,0 +1,34 @@ +#include "KCollider.h" + +namespace KapitanGame { + KCollider::KCollider(const KCollider& other) = default; + + KCollider::KCollider(KCollider&& other) noexcept: Parent(other.Parent) + { + } + + KCollider& KCollider::operator=(const KCollider& other) + { + if (this == &other) + return *this; + Parent = other.Parent; + return *this; + } + + KCollider& KCollider::operator=(KCollider&& other) noexcept + { + if (this == &other) + return *this; + Parent = other.Parent; + return *this; + } + + KCollider::KCollider(KObject* parent): Parent(parent) + { + } + + KObject* KCollider::GetParent() const + { + return Parent; + } +} diff --git a/2dgk_7/2dgk_7/KCollider.h b/2dgk_7/2dgk_7/KCollider.h new file mode 100644 index 0000000..77e8e07 --- /dev/null +++ b/2dgk_7/2dgk_7/KCollider.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include "KObject.h" +#include "KVector2d.h" + +namespace KapitanGame { + + class KCollider + { + public: + KCollider(const KCollider& other); + + KCollider(KCollider&& other) noexcept; + + KCollider& operator=(const KCollider& other); + + KCollider& operator=(KCollider&& other) noexcept; + + explicit KCollider(KObject* parent); + + virtual ~KCollider() = default; + virtual bool IsCollision(const KCollider* other) const = 0; + virtual KVector2D GetSeparationVector(const KCollider* other) const = 0; + virtual KVector2D GetSeparationVector(const SDL_FRect& map) const = 0; + virtual float GetWidth() const = 0; + virtual float GetHeight() const = 0; + KObject* GetParent() const; + private: + KObject* Parent; + }; +} + + diff --git a/2dgk_7/2dgk_7/KExit.cpp b/2dgk_7/2dgk_7/KExit.cpp new file mode 100644 index 0000000..c015f3b --- /dev/null +++ b/2dgk_7/2dgk_7/KExit.cpp @@ -0,0 +1,9 @@ +#include "KExit.h" + +namespace KapitanGame +{ + const KCollider* KExit::GetCollider() const + { + return &Collider; + } +} diff --git a/2dgk_7/2dgk_7/KExit.h b/2dgk_7/2dgk_7/KExit.h new file mode 100644 index 0000000..60c5d45 --- /dev/null +++ b/2dgk_7/2dgk_7/KExit.h @@ -0,0 +1,22 @@ +#pragma once +#include "KObject.h" +#include "KRect.h" + +namespace KapitanGame +{ + class KExit final : + public KObject + { + public: + KExit(const KVector2D& position, const KTexture& texture) + : KObject(position, texture), + Collider(this, texture.GetWidth() * 1.f, texture.GetHeight() * 1.f) + { + } + + const KCollider* GetCollider() const override; + private: + KRect Collider; + }; +} + diff --git a/2dgk_7/2dgk_7/KFont.cpp b/2dgk_7/2dgk_7/KFont.cpp new file mode 100644 index 0000000..aa92608 --- /dev/null +++ b/2dgk_7/2dgk_7/KFont.cpp @@ -0,0 +1,63 @@ +#include "KFont.h" + +#include "KTexture.h" + +namespace KapitanGame +{ + KFont::KFont() + = default; + + KFont::~KFont() + { + Free(); + } + + KFont::KFont(KFont&& other) noexcept : Font(other.Font) + { + other.Font = nullptr; + } + + KFont& KFont::operator=(KFont&& other) noexcept + { + Font = other.Font; + other.Font = nullptr; + return *this; + } + + bool KFont::LoadFromFile(const std::string& path, const int ptSize) + { + bool success = true; + Font = TTF_OpenFont(path.c_str(), ptSize); + if (Font == nullptr) + { + printf("Failed to load %s font! SDL_ttf Error: %s\n", path.c_str(), TTF_GetError()); + success = false; + } + return success; + } + + void KFont::Free() + { + if (Font != nullptr) + { + TTF_CloseFont(Font); + Font = nullptr; + } + } + + KTexture KFont::GetTextTexture(const std::string& text, const SDL_Color textColor, SDL_Renderer* renderer) const + { + KTexture texture; + SDL_Surface* textSurface = TTF_RenderText_Blended(Font, text.c_str(), textColor); + if (textSurface == nullptr) + { + printf("Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError()); + } + else + { + texture.LoadFromSurface(textSurface, renderer); + SDL_FreeSurface(textSurface); + } + return texture; + } +} diff --git a/2dgk_7/2dgk_7/KFont.h b/2dgk_7/2dgk_7/KFont.h new file mode 100644 index 0000000..05aaa20 --- /dev/null +++ b/2dgk_7/2dgk_7/KFont.h @@ -0,0 +1,36 @@ +#pragma once +#include +#include + +namespace KapitanGame { + //Font wrapper class + class KTexture; + class KFont { + public: + KFont(); + + ~KFont(); + + KFont(const KFont& other) = delete; + + KFont(KFont&& other) noexcept; + + KFont& operator=(const KFont& other) = delete; + + KFont& operator=(KFont&& other) noexcept; + + //Loads image at specified path + bool LoadFromFile(const std::string& path, int ptSize); + + //Deallocates Font + void Free(); + + KTexture GetTextTexture(const std::string& text, SDL_Color textColor, SDL_Renderer* renderer) const; + + private: + //The actual hardware font + TTF_Font* Font{}; + }; + +} + diff --git a/2dgk_7/2dgk_7/KGame.cpp b/2dgk_7/2dgk_7/KGame.cpp index 0a737fa..471e590 100644 --- a/2dgk_7/2dgk_7/KGame.cpp +++ b/2dgk_7/2dgk_7/KGame.cpp @@ -1,20 +1,29 @@ #include "KGame.h" #include "SDL.h" +#include #include #include -#include #include #include #include - #include "Utils.h" #include "Constants.h" +#include "KCamera.h" +#include "KCirclePawn.h" +#include "KExit.h" +#include "KRectPawn.h" #include "KTexture.h" #include "KTile.h" #include "KVector2d.h" +#include "KWall.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif namespace KapitanGame { - KGame::KGame() : HasSeparation(true), HasCollision(true) { + KGame::KGame() : Time(0), PreviousTime(0), Map() + { //Initialize SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { @@ -28,8 +37,14 @@ namespace KapitanGame { Input.Init(); + if (TTF_Init() < 0) + { + throw std::runtime_error(Utils::StringFormat("SDL_TTF could not initialize! TTF_Error: %s", TTF_GetError())); + } + //Create window - Window = SDL_CreateWindow(Constants::WINDOW_TITLE, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Constants::SCREEN_WIDTH, Constants::SCREEN_HEIGHT, SDL_WINDOW_SHOWN); + Window = SDL_CreateWindow(Constants::WINDOW_TITLE, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + Constants::SCREEN_WIDTH, Constants::SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (Window == nullptr) { throw std::runtime_error(Utils::StringFormat("Window could not be created! SDL_Error: %s", SDL_GetError())); @@ -38,7 +53,8 @@ namespace KapitanGame { Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED); if (Renderer == nullptr) { - throw std::runtime_error(Utils::StringFormat("Renderer could not be created! SDL Error: %s", SDL_GetError())); + throw std::runtime_error( + Utils::StringFormat("Renderer could not be created! SDL Error: %s", SDL_GetError())); } //Initialize renderer color SDL_SetRenderDrawColor(Renderer, 0, 0xFF, 0, 0xFF); @@ -46,9 +62,12 @@ namespace KapitanGame { KGame::~KGame() { //Free loaded images - - CircleTexture.Free(); - + Textures.clear(); + Objects.clear(); + Pawns.clear(); + PlayerControllers.clear(); + Fonts.clear(); + TTF_Quit(); Input.Free(); //Destroy window @@ -61,31 +80,165 @@ namespace KapitanGame { SDL_Quit(); } + void KGame::Win(KPlayer player) + { + ++Scores[static_cast(player)]; + Playing = false; + for (const auto& pc : PlayerControllers) + { + pc->UnPossess(); + } + Textures.erase("Text_Score"); + Textures.emplace("Text_Score", Fonts["Roboto-Thin"].GetTextTexture(Utils::StringFormat("%d:%d", Scores[0], Scores[1]), { 0,0,0,0xFF }, Renderer)); + if (++LvlCounter > 3) + { + int max = Scores[0]; + auto winner = KPlayer::Player1; + for (int i = 1; i < static_cast(KPlayer::Player2) + 1; ++i) + { + if (max < Scores[i]) + { + max = Scores[i]; + winner = static_cast(i); + } + } + ShowWinner = true; + Textures.erase("Text_Winner"); + Textures.emplace("Text_Winner", Fonts["Roboto-Thin"].GetTextTexture(Utils::StringFormat("Player %d won!", static_cast(winner) + 1), { 0,0,0,0xFF }, Renderer)); + LvlCounter = 1; + } + RestartTick = Time + 5000; + } + + bool KGame::LoadLevel() + { + bool success = true; + Objects.clear(); + FreePositions.clear(); + std::ifstream levelFile; + levelFile.open("assets/levels/level" + std::to_string(LvlCounter) + ".txt"); + if (levelFile.fail()) + { + printf("Failed to load assets/levels/level%d.txt!\n", LvlCounter); + success = false; + } + else + { + int y = 0; + float mapWidth = 0; + std::string line; + while (std::getline(levelFile, line)) { + if (mapWidth < static_cast(line.length() * Constants::TILE_WIDTH)) + mapWidth = static_cast(line.length()) * Constants::TILE_WIDTH; + for (auto i = 0ull; i < line.length(); ++i) { + KVector2D position{ static_cast(i * Constants::TILE_WIDTH + Constants::TILE_WIDTH / 2) , static_cast(y * Constants::TILE_HEIGHT + Constants::TILE_HEIGHT / 2) }; + switch (line[i]) + { + case '#': + Objects.emplace_back(std::make_shared(position, Textures["wall.bmp"])); + break; + case ' ': + FreePositions.emplace_back(position); + break; + default: + break; + } + } + ++y; + } + const auto mapHeight = static_cast(y * Constants::TILE_HEIGHT); + levelFile.close(); + Map = { 0,0,mapWidth,mapHeight }; + } + return success; + } + + void KGame::LoadPlayerPawnsAndExit() + { + Pawns.clear(); + std::shuffle(FreePositions.begin(), FreePositions.end(), Utils::GetRandomEngine()); + Objects.emplace_back(std::make_shared(FreePositions.back(), Textures["exit.bmp"])); + Exit = Objects.back(); + FreePositions.pop_back(); + + Pawns.emplace_back(std::make_shared(FreePositions.back(), Textures["P1.bmp"], PlayerControllers[static_cast(KPlayer::Player1)])); + FreePositions.pop_back(); + PlayerControllers[static_cast(KPlayer::Player1)]->Possess(Pawns.back().get()); + const auto distMax = KVector2D(Constants::TILE_WIDTH * 5, Constants::TILE_HEIGHT * 5); + do + { + auto diff = FreePositions.back() - Pawns.back()->GetPosition(); + if (diff.X < 0) + diff.X *= -1.f; + if (diff.Y < 0) + diff.Y *= -1.f; + if (distMax.X - diff.X < 0 || distMax.Y - diff.Y < 0) + { + FreePositions.pop_back(); + } + else + { + break; + } + } while (!FreePositions.empty()); + Pawns.emplace_back(std::make_shared(FreePositions.back(), Textures["P2.bmp"], PlayerControllers[static_cast(KPlayer::Player2)])); + FreePositions.pop_back(); + PlayerControllers[static_cast(KPlayer::Player2)]->Possess(Pawns.back().get()); + + } + bool KGame::LoadMedia() { //Loading success flag bool success = true; - if (!PlayerTexture.LoadFromFile("assets/textures/P1.bmp", Renderer)) + for (auto player : Utils::KPlayerIterator()) { - printf("Failed to load player texture image!\n"); - success = false; + std::string filename = "P" + std::to_string(static_cast(player) + 1) + ".bmp"; + Textures.emplace(filename, KTexture()); + if (!Textures[filename].LoadFromFile("assets/textures/" + filename, Renderer)) + { + Textures.erase(filename); + printf("Failed to load player texture image!\n"); + success = false; + break; + } + + PlayerControllers.emplace_back(std::make_shared(player, this)); + PlayerControllers.back()->SetupInputBindings(Input); } - if (!PlayerTexture2.LoadFromFile("assets/textures/P2.bmp", Renderer)) - { - printf("Failed to load player texture image!\n"); - success = false; - } - if (!WallTexture.LoadFromFile("assets/textures/wall.bmp", Renderer)) + Textures.emplace("wall.bmp", KTexture()); + if (!Textures["wall.bmp"].LoadFromFile("assets/textures/wall.bmp", Renderer)) { printf("Failed to load wall texture image!\n"); + Textures.erase("wall.bmp"); success = false; } - if (!ExitTexture.LoadFromFile("assets/textures/exit.bmp", Renderer)) + + Textures.emplace("exit.bmp", KTexture()); + if (!Textures["exit.bmp"].LoadFromFile("assets/textures/exit.bmp", Renderer)) { printf("Failed to load exit texture image!\n"); + Textures.erase("exit.bmp"); success = false; } + Textures.emplace("arrow.bmp", KTexture()); + if (!Textures["arrow.bmp"].LoadFromFile("assets/textures/arrow.bmp", Renderer)) + { + printf("Failed to load arrow texture image!\n"); + Textures.erase("arrow.bmp"); + success = false; + } + + Fonts.emplace("Roboto-Thin", KFont()); + if (!Fonts["Roboto-Thin"].LoadFromFile("assets/fonts/Roboto-Thin.ttf", 72)) + { + printf("Failed to load Roboto-Thin font!\n"); + Fonts.erase("Roboto-Thin"); + success = false; + } + Textures.emplace("Text_Score", Fonts["Roboto-Thin"].GetTextTexture("0:0", { 0,0,0,0xFF }, Renderer)); + Textures.emplace("Text_Winner", KTexture()); std::ifstream configFile("config.json"); if (configFile.fail()) { @@ -106,68 +259,11 @@ namespace KapitanGame { } } } - - Tiles.clear(); - std::ifstream levelFile; - levelFile.open("assets/level1.txt"); - if (levelFile.fail()) - { - printf("Failed to load assets/level1.txt!\n"); + if (!LoadLevel()) success = false; - } - else - { - int y = 0; - std::string line; - while (std::getline(levelFile, line)) { - if (MapWidth < static_cast(line.length() * Constants::TILE_WIDTH)) - MapWidth = static_cast(line.length()) * Constants::TILE_WIDTH; - for (auto i = 0ull; i < line.length(); ++i) { - auto type = TileType::Default; - switch (line[i]) - { - case '#': - type = TileType::Wall; - break; - default: - continue; - } - Tiles.emplace_back(i * Constants::TILE_WIDTH, y * Constants::TILE_HEIGHT, type); - } - ++y; - } - MapHeight = y * Constants::TILE_HEIGHT; - levelFile.close(); - } return success; } - SDL_Texture* KGame::LoadTexture(const std::string& path) const { - //The final optimized image - SDL_Texture* newTexture = nullptr; - - //Load image at specified path - SDL_Surface* loadedSurface = SDL_LoadBMP(path.c_str()); - if (loadedSurface == nullptr) - { - printf("Unable to load image %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); - } - else - { - //Create texture from surface pixels - newTexture = SDL_CreateTextureFromSurface(Renderer, loadedSurface); - if (newTexture == nullptr) - { - printf("Unable to optimize image %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); - } - - //Get rid of old loaded surface - SDL_FreeSurface(loadedSurface); - } - - return newTexture; - } - int KGame::Run(int argc, char* args[]) { //Load media @@ -183,21 +279,24 @@ namespace KapitanGame { //Event handler SDL_Event e; - SDL_Rect map{ 0,0,Constants::SCREEN_WIDTH, Constants::SCREEN_HEIGHT }; + KCamera camera(Map); + KCamera debugCamera(Map); + debugCamera.SetDebug(Map); - for (int i = 0; i < Constants::CIRCLES_COUNT; ++i) { - KVector2D position(Utils::RandomNumber() * (Constants::SCREEN_WIDTH - 2 * CircleTexture.GetWidth()) + CircleTexture.GetWidth(), Utils::RandomNumber() * (Constants::SCREEN_HEIGHT - 2 * CircleTexture.GetHeight()) + CircleTexture.GetHeight()); - Circles.emplace_back(position, KVector2D(100.f, 100.f), CircleTexture.GetWidth() / 2, CircleTexture); - } - uint32_t previousTime; - uint32_t time = previousTime = SDL_GetTicks(); + bool debug = false; + + LoadPlayerPawnsAndExit(); + camera.Update(Pawns[static_cast(KPlayer::Player1)], Pawns[static_cast(KPlayer::Player2)], Map); + + Time = PreviousTime = SDL_GetTicks(); printf("\n"); //While application is running while (!quit) { - previousTime = time; - time = SDL_GetTicks(); + PreviousTime = Time; + Time = SDL_GetTicks(); + float deltaTime = (Time - PreviousTime) * 0.001f; Input.HandleInputPreEvents(); @@ -212,33 +311,116 @@ namespace KapitanGame { } Input.HandleEvent(e); } - Input.HandleInputPostEvents(); - if (Input.IsKeyboardButtonPressed(SDL_SCANCODE_S) || Input.IsControllerButtonPressed(Controllers::Controller1, SDL_CONTROLLER_BUTTON_START)) + Input.HandleInputPostEvents(Playing); + + if (Input.IsKeyboardButtonPressed(SDL_SCANCODE_F1)) { - HasSeparation = !HasSeparation; + debug = !debug; } - if (Input.IsKeyboardButtonPressed(SDL_SCANCODE_C) || Input.IsControllerButtonPressed(Controllers::Controller1, SDL_CONTROLLER_BUTTON_BACK)) + if (Input.IsKeyboardButtonPressed(SDL_SCANCODE_F2)) { - HasCollision = !HasCollision; + CollisionEnabled = !CollisionEnabled; } + if (Playing) { + for (const auto& pc : PlayerControllers) { + pc->Update(deltaTime); + } + for (const auto& pawn : Pawns) { + if (!Playing) break; + pawn->MovementStep(deltaTime); + } + if (CollisionEnabled) { + for (const auto& pawn : Pawns) { + if (!Playing) break; + pawn->CollisionDetectionStep(Objects); + } + } + for (const auto& pawn : Pawns) { + if (!Playing) break; + pawn->CollisionDetectionWithMapStep(Map); + } + for (const auto& pawn : Pawns) { + if (!Playing) break; + pawn->CollisionDetectionWithMapStep(camera.GetPlayArea()); + } - for (auto& circle : Circles) - circle.CollisionDetectionStep(Circles, HasSeparation, HasCollision); + camera.Update(Pawns[static_cast(KPlayer::Player1)], Pawns[static_cast(KPlayer::Player2)], Map); - for (auto& circle : Circles) - circle.CollisionDetectionWithMapStep(map); + } + + if (!Playing) + { + if (Time > RestartTick) + { + LoadLevel(); + LoadPlayerPawnsAndExit(); + debugCamera.SetDebug(Map); + camera.Update(Pawns[static_cast(KPlayer::Player1)], Pawns[static_cast(KPlayer::Player2)], Map); + if (ShowWinner) + { + for (auto i : Utils::KPlayerIterator()) + { + Scores[static_cast(i)] = 0; + } + Textures.erase("Text_Score"); + Textures.emplace("Text_Score", Fonts["Roboto-Thin"].GetTextTexture(Utils::StringFormat("%d:%d", Scores[0], Scores[1]), { 0,0,0,0xFF }, Renderer)); + ShowWinner = false; + } + Playing = true; + continue; + } + } - for (auto& circle : Circles) - circle.MovementStep(static_cast(time - previousTime) / 1000.f); //Clear screen - SDL_SetRenderDrawColor(Renderer, 0, 0xFF, 0, 0xFF); + SDL_SetRenderDrawColor(Renderer, 66, 135, 245, 0xFF); SDL_RenderClear(Renderer); - for (auto& circle : Circles) - circle.Render(Renderer); + const auto& cameraInUse = debug ? debugCamera : camera; + + + if (Playing) { + for (const auto& object : Objects) + object->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 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); + } + } + if (ShowWinner) + { + Textures["Text_Winner"].Render(Renderer, Constants::SCREEN_WIDTH / 2.f - Textures["Text_Winner"].GetWidth() / 2.f, 25.f); + } + + Textures["Text_Score"].Render(Renderer, Constants::SCREEN_WIDTH / 2.f - Textures["Text_Score"].GetWidth() / 2.f, Constants::SCREEN_HEIGHT - 10.f - Textures["Text_Score"].GetHeight()); + if (debug) + { + SDL_SetRenderDrawColor(Renderer, 0x00, 0x00, 0x00, 0xFF); + SDL_RenderDrawLineF(Renderer, 0, Constants::SCREEN_HEIGHT / 2.f, Constants::SCREEN_WIDTH, Constants::SCREEN_HEIGHT / 2.f); + SDL_RenderDrawLineF(Renderer, Constants::SCREEN_WIDTH / 2.f, 0, Constants::SCREEN_WIDTH / 2.f, Constants::SCREEN_HEIGHT); + SDL_SetRenderDrawColor(Renderer, 0x00, 0xFF, 0x00, 0xFF); + + SDL_RenderDrawPointF(Renderer, camera.GetFocusPoint().X * debugCamera.GetScale(), camera.GetFocusPoint().Y * debugCamera.GetScale()); + SDL_SetRenderDrawColor(Renderer, 0xFF, 0x00, 0x00, 0xFF); + SDL_FRect debugViewport = { camera.GetViewport().x * debugCamera.GetScale(), + camera.GetViewport().y * debugCamera.GetScale(), + camera.GetViewport().w * debugCamera.GetScale(), + camera.GetViewport().h * debugCamera.GetScale() }; + SDL_RenderDrawRectF(Renderer, &debugViewport); + SDL_FRect debug2Viewport = { camera.GetPlayArea().x * debugCamera.GetScale(), + camera.GetPlayArea().y * debugCamera.GetScale(), + camera.GetPlayArea().w * debugCamera.GetScale(), + camera.GetPlayArea().h * debugCamera.GetScale() }; + SDL_SetRenderDrawColor(Renderer, 0x00, 0xFF, 0x00, 0xFF); + SDL_RenderDrawRectF(Renderer, &debug2Viewport); + } //Update screen SDL_RenderPresent(Renderer); @@ -247,4 +429,4 @@ namespace KapitanGame { return 0; } -} \ No newline at end of file +} diff --git a/2dgk_7/2dgk_7/KGame.h b/2dgk_7/2dgk_7/KGame.h index 23d0e8f..9a352a2 100644 --- a/2dgk_7/2dgk_7/KGame.h +++ b/2dgk_7/2dgk_7/KGame.h @@ -1,19 +1,24 @@ #pragma once +#include + #include "KTexture.h" #include #include -#include "KCircle.h" +#include "KFont.h" #include "KInput.h" namespace KapitanGame { + class KExit; + class KObject; class KGame { public: KGame(); ~KGame(); + void Win(KPlayer player); KGame(const KGame& other) = delete; KGame(KGame&& other) noexcept = delete; KGame& operator=(const KGame& other) = delete; @@ -24,16 +29,28 @@ namespace KapitanGame { SDL_Renderer* Renderer = nullptr; - KTexture CircleTexture; - - std::vector Circles; + std::vector> Objects; + std::vector> Pawns; + std::vector> PlayerControllers; + std::unordered_map Textures; + std::unordered_map Fonts; + std::vector FreePositions; KInput Input; - bool HasSeparation; - bool HasCollision; - private: + uint32_t Time; + uint32_t PreviousTime; + SDL_FRect Map; + bool CollisionEnabled = true; + bool ShowWinner = false; + std::weak_ptr Exit; + + bool LoadLevel(); + void LoadPlayerPawnsAndExit(); bool LoadMedia(); - SDL_Texture* LoadTexture(const std::string& path) const; + int LvlCounter = 1; + bool Playing = true; + uint32_t RestartTick = -1; + short Scores[static_cast(KPlayer::Player2) + 1] = { 0,0 }; }; } diff --git a/2dgk_7/2dgk_7/KInput.cpp b/2dgk_7/2dgk_7/KInput.cpp index 14e0bde..0b5544b 100644 --- a/2dgk_7/2dgk_7/KInput.cpp +++ b/2dgk_7/2dgk_7/KInput.cpp @@ -74,12 +74,14 @@ namespace KapitanGame { } LastKeyboardInputs = KeyboardInputs; } - void KInput::HandleInputPostEvents() { + void KInput::HandleInputPostEvents(const bool processInput) { int size = 0; const Uint8* currentKeyStates = SDL_GetKeyboardState(&size); KeyboardInputs = std::vector(currentKeyStates, currentKeyStates + size); - ProcessActions(); - ProcessAxes(); + if (processInput) { + ProcessActions(); + ProcessAxes(); + } } void KInput::HandleEvent(const SDL_Event& event) { switch (event.type) { @@ -123,12 +125,12 @@ namespace KapitanGame { } void KInput::BindAction(const std::string& name, InputState expectedInputState, - KPlayerController* controllerObject, + const std::shared_ptr& controllerObject, KPlayerCommand command, KPlayer player) { Actions.emplace_back(name, expectedInputState, controllerObject, command, player); } - void KInput::BindAxis(const std::string& name, KPlayerController* controllerObject, KPlayerAxisCommand command, KPlayer player) + void KInput::BindAxis(const std::string& name, const std::shared_ptr& controllerObject, KPlayerAxisCommand command, KPlayer player) { Axes.emplace_back(name, controllerObject, command, player); } @@ -181,7 +183,8 @@ namespace KapitanGame { void KInput::ProcessActions() { for (auto& action : Actions) { if (CheckAction(action.Name, action.ExpectedInputState, action.Player)) { - std::invoke(action.Command, action.ControllerObject); + if (auto obj = action.ControllerObject.lock()) + std::invoke(action.Command, obj); } } } @@ -189,7 +192,8 @@ namespace KapitanGame { void KInput::ProcessAxes() { for (auto& axis : Axes) { - std::invoke(axis.AxisCommand, axis.ControllerObject, GetAxisValue(axis.Name, axis.Player)); + if (auto obj = axis.ControllerObject.lock()) + std::invoke(axis.AxisCommand, obj, GetAxisValue(axis.Name, axis.Player)); } } diff --git a/2dgk_7/2dgk_7/KInput.h b/2dgk_7/2dgk_7/KInput.h index 5d9db5b..4678c94 100644 --- a/2dgk_7/2dgk_7/KInput.h +++ b/2dgk_7/2dgk_7/KInput.h @@ -3,13 +3,14 @@ #include #include +#include "Controllers.h" #include "GamePad.h" #include "KActionBind.h" #include "KPlayer.h" namespace KapitanGame { struct KControllerAxisMapping { - KControllerAxisMapping(Controllers controller, SDL_GameControllerAxis axis, float scale) : Controller(controller), Axis(axis), Scale(scale) {} + KControllerAxisMapping(const Controllers controller, const SDL_GameControllerAxis axis, const float scale) : Controller(controller), Axis(axis), Scale(scale) {} Controllers Controller; SDL_GameControllerAxis Axis; float Scale; @@ -29,6 +30,22 @@ namespace KapitanGame { std::unordered_multimap> KeyAxisBinds[static_cast(KPlayer::Player2) + 1]; int GamePadsCount; bool Initialized; + + void ProcessActions(); + void ProcessAxes(); + public: + KInput(); + void Init(); + void Free(); + void HandleInputPreEvents(); + void HandleInputPostEvents(bool processInput); + void HandleEvent(const SDL_Event& event); + void BindAction(const std::string& name, InputState expectedInputState, const std::shared_ptr& controllerObject, KPlayerCommand command, KPlayer player); + void BindAxis(const std::string& name, const std::shared_ptr& controllerObject, KPlayerAxisCommand command, KPlayer player); + bool CheckAction(const std::string& name, InputState expectedInputState, KPlayer player); + + void AddAxisMapping(const std::string& name, const float& scale, const std::string& key, const KPlayer& player); + void AddActionMapping(const std::string& name, const std::string& key, const KPlayer& player); bool IsControllerButtonPressed(Controllers controllerId, SDL_GameControllerButton button) const; bool IsControllerButtonReleased(Controllers controllerId, SDL_GameControllerButton button) const; @@ -38,21 +55,6 @@ namespace KapitanGame { bool IsKeyboardButtonPressed(Uint8 scanCode) const; bool IsKeyboardButtonReleased(Uint8 scanCode) const; float GetAxisValue(const std::string& name, const KPlayer& player) const; - void ProcessActions(); - void ProcessAxes(); - public: - KInput(); - void Init(); - void Free(); - void HandleInputPreEvents(); - void HandleInputPostEvents(); - void HandleEvent(const SDL_Event& event); - void BindAction(const std::string& name, InputState expectedInputState, KPlayerController* controllerObject, KPlayerCommand command, KPlayer player); - void BindAxis(const std::string& name, KPlayerController* controllerObject, KPlayerAxisCommand command, KPlayer player); - bool CheckAction(const std::string& name, InputState expectedInputState, KPlayer player); - - void AddAxisMapping(const std::string& name, const float& scale, const std::string& key, const KPlayer& player); - void AddActionMapping(const std::string& name, const std::string& key, const KPlayer& player); }; } diff --git a/2dgk_7/2dgk_7/KObject.cpp b/2dgk_7/2dgk_7/KObject.cpp new file mode 100644 index 0000000..d9cbed9 --- /dev/null +++ b/2dgk_7/2dgk_7/KObject.cpp @@ -0,0 +1,23 @@ +#include "KObject.h" + +#include "KCamera.h" + +namespace KapitanGame +{ + std::atomic KObject::IdCounter{ 0 }; + + KObject::KObject(const KVector2D& position, const KTexture& texture) : + Id(++IdCounter), Position(position), Texture(texture) + { + } + + void KObject::Render(SDL_Renderer* renderer, const KCamera& camera) const + { + Texture.Render(renderer, Position.X - Texture.GetWidth() / 2.f - camera.GetViewport().x, Position.Y - Texture.GetHeight() / 2.f - camera.GetViewport().y, nullptr, camera.GetScale()); + } + + KVector2D KObject::GetPosition() const + { + return Position; + } +} diff --git a/2dgk_7/2dgk_7/KObject.h b/2dgk_7/2dgk_7/KObject.h new file mode 100644 index 0000000..14482fa --- /dev/null +++ b/2dgk_7/2dgk_7/KObject.h @@ -0,0 +1,28 @@ +#pragma once +#include + +#include "KTexture.h" +#include "KVector2d.h" + +namespace KapitanGame +{ + class KCamera; + class KCollider; + + class KObject + { + public: + KObject(const KVector2D& position, const KTexture& texture); + virtual ~KObject() = default; + void Render(SDL_Renderer* renderer, const KCamera& camera) const; + KVector2D GetPosition() const; + virtual const KCollider* GetCollider() const = 0; + const int Id; + static std::atomic IdCounter; + protected: + KVector2D Position{ 0.f, 0.f }; + private: + const KTexture& Texture; + }; +} + diff --git a/2dgk_7/2dgk_7/KPawn.cpp b/2dgk_7/2dgk_7/KPawn.cpp new file mode 100644 index 0000000..445e6b9 --- /dev/null +++ b/2dgk_7/2dgk_7/KPawn.cpp @@ -0,0 +1,46 @@ +#include "KPawn.h" + +#include +#include + +#include "Constants.h" +#include "KPlayerController.h" +#include "KExit.h" + +namespace KapitanGame +{ + void KPawn::CollisionDetectionStep(const std::vector>& 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(); + } + return; + } + const auto separationVector = GetCollider()->GetSeparationVector(other->GetCollider()); + Position += separationVector; + } + } + } + + void KPawn::MovementStep(const float& timeStep) + { + Position += Velocity * timeStep; + } + + void KPawn::CollisionDetectionWithMapStep(const SDL_FRect& map) + { + Position += GetCollider()->GetSeparationVector(map); + } + + void KPawn::AddMovementInput(const KVector2D& input) + { + Velocity = input * Constants::SPEED * (1 - Constants::SMOOTH) + Velocity * Constants::SMOOTH; + } +} + diff --git a/2dgk_7/2dgk_7/KPawn.h b/2dgk_7/2dgk_7/KPawn.h new file mode 100644 index 0000000..f49159d --- /dev/null +++ b/2dgk_7/2dgk_7/KPawn.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include + +#include "KObject.h" + +namespace KapitanGame +{ + class KPlayerController; + + class KPawn : public KObject + { + public: + KPawn(const KVector2D& position, const KTexture& texture, + const std::shared_ptr& playerController) + : KObject(position, texture), + PlayerController(playerController) + { + } + void CollisionDetectionStep(const std::vector>& objects); + void MovementStep(const float& timeStep); + void CollisionDetectionWithMapStep(const SDL_FRect& map); + void AddMovementInput(const KVector2D& input); + private: + const std::weak_ptr PlayerController; + KVector2D Velocity{ 0.f, 0.f }; + }; +} + diff --git a/2dgk_7/2dgk_7/KPlayer.h b/2dgk_7/2dgk_7/KPlayer.h index e9713c0..f5af9a2 100644 --- a/2dgk_7/2dgk_7/KPlayer.h +++ b/2dgk_7/2dgk_7/KPlayer.h @@ -1,7 +1,8 @@ #pragma once + namespace KapitanGame { enum class KPlayer : int { Player1, Player2 }; -} \ No newline at end of file +} diff --git a/2dgk_7/2dgk_7/KPlayerController.cpp b/2dgk_7/2dgk_7/KPlayerController.cpp index 28f1f27..eca99c6 100644 --- a/2dgk_7/2dgk_7/KPlayerController.cpp +++ b/2dgk_7/2dgk_7/KPlayerController.cpp @@ -1,12 +1,13 @@ #include "KPlayerController.h" +#include "KGame.h" #include "KInput.h" namespace KapitanGame { void KPlayerController::SetupInputBindings(KInput& input) { - input.BindAxis("MoveYAxis", this, &KPlayerController::MoveYAxis, Player); - input.BindAxis("MoveXAxis", this, &KPlayerController::MoveXAxis, Player); + input.BindAxis("MoveY", shared_from_this(), &KPlayerController::MoveYAxis, Player); + input.BindAxis("MoveX", shared_from_this(), &KPlayerController::MoveXAxis, Player); } void KPlayerController::MoveYAxis(const float axis) @@ -21,7 +22,28 @@ namespace KapitanGame { void KPlayerController::Update(float deltaTime) { Input.Normalize(); - Pawn->AddMovementInput(Input); - Input = KVector2D(0.f, 0.f); + if (Pawn != nullptr) + Pawn->AddMovementInput(Input); + Input *= 0; + } + + void KPlayerController::NotifyWin() const + { + Game->Win(Player); + } + + void KPlayerController::Possess(KPawn* pawn) + { + Pawn = pawn; + } + + void KPlayerController::UnPossess() + { + Pawn = nullptr; + } + + const KPlayer& KPlayerController::GetPlayer() const + { + return Player; } } diff --git a/2dgk_7/2dgk_7/KPlayerController.h b/2dgk_7/2dgk_7/KPlayerController.h index ac83916..ea4891f 100644 --- a/2dgk_7/2dgk_7/KPlayerController.h +++ b/2dgk_7/2dgk_7/KPlayerController.h @@ -1,16 +1,18 @@ #pragma once -#include "Controllers.h" +#include "KPawn.h" #include "KPlayer.h" -#include "KShape.h" #include "KVector2d.h" namespace KapitanGame { + class KGame; class KInput; - class KPlayerController + class KPlayerController : public std::enable_shared_from_this { public: - KPlayerController(const KPlayer player) : Input(0.f, 0.f), Player(player) + KPlayerController(const KPlayer player, KGame* const game) + : Player(player), + Game(game) { } @@ -18,10 +20,15 @@ namespace KapitanGame { void MoveYAxis(float axis); void MoveXAxis(float axis); void Update(float deltaTime); + void NotifyWin() const; + void Possess(KPawn* pawn); + void UnPossess(); + const KPlayer& GetPlayer() const; private: - KVector2D Input; - KPlayer Player; - KShape* Pawn; + KVector2D Input{ 0.f, 0.f }; + const KPlayer Player; + KPawn* Pawn{}; + KGame* Game; }; typedef void (KPlayerController::* KPlayerCommand)(); typedef void (KPlayerController::* KPlayerAxisCommand)(float input); diff --git a/2dgk_7/2dgk_7/KRect.cpp b/2dgk_7/2dgk_7/KRect.cpp index 9cc6079..8a815f7 100644 --- a/2dgk_7/2dgk_7/KRect.cpp +++ b/2dgk_7/2dgk_7/KRect.cpp @@ -4,12 +4,6 @@ #include "Utils.h" namespace KapitanGame { - KRect::KRect(const KVector2D& position, const KVector2D& velocity, const KTexture& texture, const float width, - const float height) : KShape(position, velocity, texture), Width(width), Height(height) { - } - - void KRect::CollisionDetectionWithMapStep(const SDL_Rect& map) { - } float KRect::GetWidth() const { return Width; @@ -20,54 +14,121 @@ namespace KapitanGame { } KVector2D KRect::GetSeparationVector(const float left, const float right, const float top, const float bottom) { - auto x = left < right ? -left : right; - auto y = top < bottom ? -top : bottom; + const auto x = left < right ? -left : right; + const auto y = top < bottom ? -top : bottom; + auto vX = x; + auto vY = y; if (fabs(x) < fabs(y)) - y = 0; + vY = 0; if (fabs(x) > fabs(y)) - x = 0; - return { x, y }; + vX = 0; + return { vX, vY }; } - KVector2D KRect::GetSeparationVector(const KCircle& other) const { - const float l = Position.X - Width / 2; - const float r = Position.X + Width / 2; - const float t = Position.Y - Height / 2; - const float b = Position.Y + Height / 2; - const auto f = KVector2D(Utils::Clamp(other.GetPosition().X, l, r), - Utils::Clamp(other.GetPosition().Y, t, b)); + KVector2D KRect::GetSeparationVector(const KCircle* other) const { + const float l = GetLeft(); + const float r = GetRight(); + const float t = GetTop(); + const float b = GetBottom(); + const auto f = KVector2D(Utils::Clamp(other->GetParent()->GetPosition().X, l, r), + Utils::Clamp(other->GetParent()->GetPosition().Y, t, b)); - if (other.GetPosition() == f) { - const auto left = other.GetPosition().X - l + other.GetRadius(); - const auto right = r - other.GetPosition().X + other.GetRadius(); - const auto top = other.GetPosition().Y - t + other.GetRadius(); - const auto bottom = b - other.GetPosition().Y + other.GetRadius(); + if (other->GetParent()->GetPosition() == f) { + const auto left = other->GetParent()->GetPosition().X - l + other->GetRadius(); + const auto right = r - other->GetParent()->GetPosition().X + other->GetRadius(); + const auto top = other->GetParent()->GetPosition().Y - t + other->GetRadius(); + const auto bottom = b - other->GetParent()->GetPosition().Y + other->GetRadius(); return GetSeparationVector(left, right, top, bottom) * -1.f; } - return (other.GetPosition() - f) / (other.GetPosition() - f).Length() * (other.GetRadius() - (other.GetPosition() - f).Length()) * 1.f; + return (other->GetParent()->GetPosition() - f) / (other->GetParent()->GetPosition() - f).Length() * (other->GetRadius() - (other->GetParent()->GetPosition() - f).Length()) * 1.f; } - KVector2D KRect::GetSeparationVector(const KRect& other) const { - const auto left = Position.X + Width / 2 - (other.Position.X - other.Width / 2); - const auto right = other.Position.X + other.Width / 2 - (Position.X - Width / 2); - const auto top = Position.Y + Height / 2 - (other.Position.Y - other.Height / 2); - const auto bottom = other.Position.Y + other.Height / 2 - (Position.Y - Height / 2); + KVector2D KRect::GetSeparationVector(const KRect* other) const { + const auto left = GetRight() - other->GetLeft(); + const auto right = other->GetRight() - GetLeft(); + const auto top = GetBottom() - other->GetTop(); + const auto bottom = other->GetBottom() - GetTop(); return GetSeparationVector(left, right, top, bottom); } - bool KRect::IsCollision(const KCircle& other) const { - const auto f = KVector2D(Utils::Clamp(other.GetPosition().X, Position.X - Width / 2, Position.X + Width / 2), - Utils::Clamp(other.GetPosition().Y, Position.Y - Height / 2, Position.Y + Height / 2)); + bool KRect::IsCollision(const KCircle* other) const { + const auto f = KVector2D(Utils::Clamp(other->GetParent()->GetPosition().X, GetLeft(), GetRight()), + Utils::Clamp(other->GetParent()->GetPosition().Y, GetTop(), GetBottom())); - return (Position - f).Length() < other.GetRadius(); + return (other->GetParent()->GetPosition() - f).Length() < other->GetRadius(); } - bool KRect::IsCollision(const KRect& other) const { - return Position.X + Width / 2 > other.Position.X - other.Width / 2 - && other.Position.X + other.Width / 2 > Position.X - Width / 2 - && Position.Y + Height / 2 > other.Position.Y - other.Height / 2 - && other.Position.Y + other.Height / 2 > Position.Y - Height / 2; + float KRect::GetLeft() const + { + return GetParent()->GetPosition().X - Width / 2; } + float KRect::GetRight() const + { + return GetParent()->GetPosition().X + Width / 2; + } + + float KRect::GetBottom() const + { + return GetParent()->GetPosition().Y + Height / 2; + } + + float KRect::GetTop() const + { + return GetParent()->GetPosition().Y - Height / 2; + } + + bool KRect::IsCollision(const KRect* other) const { + return GetRight() >= other->GetLeft() + && other->GetRight() >= GetLeft() + && GetBottom() >= other->GetTop() + && other->GetBottom() >= GetTop(); + } + + bool KRect::IsCollision(const KCollider* other) const + { + const auto circle = dynamic_cast(other); + if (circle != nullptr) + return IsCollision(circle); + + const auto rect = dynamic_cast(other); + if (rect != nullptr) + return IsCollision(rect); + + throw std::runtime_error("unsupported shape"); + } + + KVector2D KRect::GetSeparationVector(const KCollider* other) const + { + const auto circle = dynamic_cast(other); + if (circle != nullptr) + return GetSeparationVector(circle); + + const auto rect = dynamic_cast(other); + if (rect != nullptr) + return GetSeparationVector(rect); + + throw std::runtime_error("unsupported shape"); + } + + KVector2D KRect::GetSeparationVector(const SDL_FRect& map) const + { + KVector2D separationVector{ 0.f,0.f }; + if (GetParent()->GetPosition().X - map.x - GetWidth() / 2 < 0) + { + separationVector.X += -(GetParent()->GetPosition().X - map.x - GetWidth() / 2); + } + if (GetParent()->GetPosition().X + GetWidth() / 2 - (map.x + map.w) > 0) + { + separationVector.X += -(GetParent()->GetPosition().X - (map.x + map.w) + GetWidth() / 2); + } + if (GetParent()->GetPosition().Y - GetHeight() / 2 - map.y < 0) { + separationVector.Y += -(GetParent()->GetPosition().Y - map.y - GetHeight() / 2); + } + if (GetParent()->GetPosition().Y + GetHeight() / 2 - (map.y + map.h) > 0) { + separationVector.Y += -(GetParent()->GetPosition().Y - (map.y + map.h) + GetHeight() / 2); + } + return separationVector; + } } diff --git a/2dgk_7/2dgk_7/KRect.h b/2dgk_7/2dgk_7/KRect.h index ae1b42b..66cd3ca 100644 --- a/2dgk_7/2dgk_7/KRect.h +++ b/2dgk_7/2dgk_7/KRect.h @@ -1,21 +1,35 @@ #pragma once -#include "KShape.h" +#include + +#include "KCollider.h" namespace KapitanGame { - class KRect final : public KShape + class KCircle; + + class KRect final : public KCollider { public: - KRect(const KVector2D& position, const KVector2D& velocity, const KTexture& texture, float width, float height); - void CollisionDetectionWithMapStep(const SDL_Rect& map) override; - float GetWidth() const; - float GetHeight() const; + KRect(KObject* parent, const float width, const float height) + : KCollider(parent), + Width(width), + Height(height) + { + } + float GetWidth() const override; + float GetHeight() const override; static KVector2D GetSeparationVector(float left, float right, float top, float bottom); - protected: - KVector2D GetSeparationVector(const KCircle& other) const override; - KVector2D GetSeparationVector(const KRect& other) const override; - bool IsCollision(const KCircle& other) const override; - bool IsCollision(const KRect& other) const override; + bool IsCollision(const KCollider* other) const override; + KVector2D GetSeparationVector(const KCollider* other) const override; + KVector2D GetSeparationVector(const SDL_FRect& map) const override; private: + KVector2D GetSeparationVector(const KCircle* other) const; + KVector2D GetSeparationVector(const KRect* other) const; + bool IsCollision(const KCircle* other) const; + float GetLeft() const; + float GetRight() const; + float GetBottom() const; + float GetTop() const; + bool IsCollision(const KRect* other) const; float Width; float Height; }; diff --git a/2dgk_7/2dgk_7/KRectPawn.cpp b/2dgk_7/2dgk_7/KRectPawn.cpp new file mode 100644 index 0000000..2ef8134 --- /dev/null +++ b/2dgk_7/2dgk_7/KRectPawn.cpp @@ -0,0 +1,15 @@ +#include "KRectPawn.h" + +namespace KapitanGame +{ + KRectPawn::KRectPawn(const KVector2D& position, const KTexture& texture, + const std::shared_ptr& playerController) : KPawn(position, texture, playerController), + Collider(this, texture.GetWidth(), texture.GetHeight()) + { + } + + const KCollider* KRectPawn::GetCollider() const + { + return &Collider; + } +} diff --git a/2dgk_7/2dgk_7/KRectPawn.h b/2dgk_7/2dgk_7/KRectPawn.h new file mode 100644 index 0000000..f2cf0c9 --- /dev/null +++ b/2dgk_7/2dgk_7/KRectPawn.h @@ -0,0 +1,20 @@ +#pragma once +#include "KPawn.h" +#include "KRect.h" + +namespace KapitanGame +{ + class KRectPawn final : + public KPawn + { + public: + KRectPawn(const KVector2D& position, const KTexture& texture, + const std::shared_ptr& playerController); + + const KCollider* GetCollider() const override; + private: + KRect Collider; + }; + + +} diff --git a/2dgk_7/2dgk_7/KShape.cpp b/2dgk_7/2dgk_7/KShape.cpp deleted file mode 100644 index d0a9a6b..0000000 --- a/2dgk_7/2dgk_7/KShape.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "KShape.h" -#include "KCircle.h" -#include "KRect.h" - -#include -#include - -#include "Constants.h" - -namespace KapitanGame { - std::atomic KShape::IdCounter{ 0 }; - - KShape::KShape(const KVector2D& position, const KVector2D& velocity, const KTexture& texture) : Id(++IdCounter), - Position(position), - Velocity(velocity), - Texture(texture) { - } - - KShape::~KShape() = default; - - void KShape::CollisionDetectionStep(const std::vector& shapes, const bool& shouldSeparate, - const bool& shouldReflect) { - for (auto& other : shapes) { - if (other.Id == Id) continue; - if (IsCollision(other)) { - auto separationVector = GetSeparationVector(other); - if (shouldSeparate) - Position += separationVector; - if (shouldReflect) - { - separationVector.Normalize(); - Velocity = Velocity.Reflect(separationVector); - } - } - } - } - - bool KShape::IsCollision(const KShape& other) const { - try { - auto& circle = dynamic_cast(other); - return IsCollision(circle); - } - catch (const std::bad_cast&) { - } - try { - auto& rect = dynamic_cast(other); - return IsCollision(rect); - } - catch (const std::bad_cast&) { - } - throw std::runtime_error("unsupported shape"); - } - - KVector2D KShape::GetSeparationVector(const KShape& other) const { - try { - auto& circle = dynamic_cast(other); - return GetSeparationVector(circle); - } - catch (const std::bad_cast&) { - } - try { - auto& circle = dynamic_cast(other); - return GetSeparationVector(circle); - } - catch (const std::bad_cast&) { - } - throw std::runtime_error("unsupported shape"); - } - - void KShape::MovementStep(const float& timeStep) { - Position += Velocity * timeStep; - } - - void KShape::Render(SDL_Renderer* renderer) const { - Texture.Render(renderer, static_cast(Position.X) - Texture.GetWidth() / 2, static_cast(Position.Y) - Texture.GetHeight() / 2); - } - - KVector2D KShape::GetPosition() const { - return Position; - } - - void KShape::AddMovementInput(const KVector2D& input) { - Velocity = input * Constants::SPEED * (1 - Constants::SMOOTH) + Velocity * Constants::SMOOTH; - } -} diff --git a/2dgk_7/2dgk_7/KShape.h b/2dgk_7/2dgk_7/KShape.h deleted file mode 100644 index 0455ff3..0000000 --- a/2dgk_7/2dgk_7/KShape.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include -#include -#include - -#include "KTexture.h" -#include "KVector2d.h" - -namespace KapitanGame { - class KRect; - class KCircle; - - class KShape - { - public: - KShape(const KVector2D& position, const KVector2D& velocity, const KTexture& texture); - virtual ~KShape(); - KShape() = delete; - KShape(const KShape& other) = default; - KShape(KShape&& other) = default; - KShape& operator=(KShape&& other) = delete; - KShape& operator=(const KShape& other) = delete; - void CollisionDetectionStep(const std::vector& shapes, const bool& shouldSeparate, const bool& shouldReflect); - void MovementStep(const float& timeStep); - bool IsCollision(const KShape& other) const; - KVector2D GetSeparationVector(const KShape& other) const; - void Render(SDL_Renderer* renderer) const; - virtual void CollisionDetectionWithMapStep(const SDL_Rect& map) = 0; - KVector2D GetPosition() const; - void AddMovementInput(const KVector2D& input); - const int Id; - static std::atomic IdCounter; - protected: - KVector2D Position{ 0.f, 0.f }; - KVector2D Velocity{ 0.f, 0.f }; - virtual KVector2D GetSeparationVector(const KCircle& other) const = 0; - virtual KVector2D GetSeparationVector(const KRect& other) const = 0; - virtual bool IsCollision(const KCircle& other) const = 0; - virtual bool IsCollision(const KRect& other) const = 0; - private: - const KTexture& Texture; - }; -} - - diff --git a/2dgk_7/2dgk_7/KTexture.cpp b/2dgk_7/2dgk_7/KTexture.cpp index e659cb6..5de09e4 100644 --- a/2dgk_7/2dgk_7/KTexture.cpp +++ b/2dgk_7/2dgk_7/KTexture.cpp @@ -1,27 +1,17 @@ #include "KTexture.h" namespace KapitanGame { - KTexture::KTexture() + KTexture::KTexture() : Texture(nullptr), Width(0), Height(0) { - //Initialize - Texture = nullptr; - Width = 0; - Height = 0; } KTexture::KTexture(KTexture&& other) noexcept : Texture(other.Texture), Width(other.Width), Height(other.Height) { - } - - KTexture& KTexture::operator=(const KTexture& other) { - if (this == &other) - return *this; - Texture = other.Texture; - Width = other.Width; - Height = other.Height; - return *this; + other.Texture = nullptr; + other.Width = 0; + other.Height = 0; } KTexture& KTexture::operator=(KTexture&& other) noexcept { @@ -30,6 +20,9 @@ namespace KapitanGame { Texture = other.Texture; Width = other.Width; Height = other.Height; + other.Texture = nullptr; + other.Width = 0; + other.Height = 0; return *this; } @@ -78,6 +71,22 @@ namespace KapitanGame { return Texture != nullptr; } + bool KTexture::LoadFromSurface(SDL_Surface* surface, SDL_Renderer* renderer) + { + Free(); + Texture = SDL_CreateTextureFromSurface(renderer, surface); + if (Texture == nullptr) + { + printf("Unable to create texture from surface! SDL Error: %s\n", SDL_GetError()); + } + else + { + Width = surface->w; + Height = surface->h; + } + return Texture != nullptr; + } + void KTexture::Free() { //Free texture if it exists @@ -90,12 +99,13 @@ namespace KapitanGame { } } - void KTexture::Render(SDL_Renderer* renderer, const int x, const int y, SDL_Rect* clip, const float scale) const + void KTexture::Render(SDL_Renderer* renderer, const float x, const float y, SDL_Rect* clip, const float scale) const { + if (Texture == nullptr) return; //Set rendering space and render to screen - SDL_Rect renderQuad = { - static_cast(static_cast(x) * scale), static_cast(static_cast(y) * scale), - static_cast(static_cast(Width) * scale), static_cast(static_cast(Height) * scale) + SDL_FRect renderQuad = { + x * scale, y * scale, + Width * scale, Height * scale }; //Set clip rendering dimensions @@ -106,7 +116,20 @@ namespace KapitanGame { } //Render to screen - SDL_RenderCopy(renderer, Texture, clip, &renderQuad); + SDL_RenderCopyF(renderer, Texture, clip, &renderQuad); + } + + void KTexture::RenderEx(SDL_Renderer* renderer, const float x, const float y, const double degrees) const + { + if (Texture == nullptr) return; + //Set rendering space and render to screen + const SDL_FRect renderQuad = { + x , y , + static_cast(Width) , static_cast(Height) + }; + + //Render to screen + SDL_RenderCopyExF(renderer, Texture, nullptr, &renderQuad, degrees, nullptr, SDL_FLIP_NONE); } int KTexture::GetWidth() const diff --git a/2dgk_7/2dgk_7/KTexture.h b/2dgk_7/2dgk_7/KTexture.h index 85aef92..def9cee 100644 --- a/2dgk_7/2dgk_7/KTexture.h +++ b/2dgk_7/2dgk_7/KTexture.h @@ -9,23 +9,28 @@ namespace KapitanGame { KTexture(); ~KTexture(); + - KTexture(const KTexture& other) = default; + KTexture(const KTexture& other) = delete; KTexture(KTexture&& other) noexcept; - KTexture& operator=(const KTexture& other); + KTexture& operator=(const KTexture& other) = delete; KTexture& operator=(KTexture&& other) noexcept; //Loads image at specified path bool LoadFromFile(const std::string& path, SDL_Renderer* renderer); + bool LoadFromSurface(SDL_Surface* surface, SDL_Renderer* renderer); + //Deallocates texture void Free(); //Renders texture at given point - void Render(SDL_Renderer* renderer, int x, int y, SDL_Rect* clip = nullptr, float scale = 1.f) const; + void Render(SDL_Renderer* renderer, float x, float y, SDL_Rect* clip = nullptr, float scale = 1.f) const; + + void RenderEx(SDL_Renderer* renderer, float x, float y, double degrees) const; //Gets image dimensions int GetWidth() const; diff --git a/2dgk_7/2dgk_7/KVector2d.h b/2dgk_7/2dgk_7/KVector2d.h index 933ea00..5150f64 100644 --- a/2dgk_7/2dgk_7/KVector2d.h +++ b/2dgk_7/2dgk_7/KVector2d.h @@ -1,4 +1,6 @@ #pragma once +#include +#define _USE_MATH_DEFINES #include namespace KapitanGame { diff --git a/2dgk_7/2dgk_7/KWall.cpp b/2dgk_7/2dgk_7/KWall.cpp new file mode 100644 index 0000000..d6c3f78 --- /dev/null +++ b/2dgk_7/2dgk_7/KWall.cpp @@ -0,0 +1,9 @@ +#include "KWall.h" + +namespace KapitanGame +{ + const KCollider* KWall::GetCollider() const + { + return &Collider; + } +} diff --git a/2dgk_7/2dgk_7/KWall.h b/2dgk_7/2dgk_7/KWall.h new file mode 100644 index 0000000..45ca443 --- /dev/null +++ b/2dgk_7/2dgk_7/KWall.h @@ -0,0 +1,22 @@ +#pragma once +#include "KObject.h" +#include "KRect.h" + +namespace KapitanGame +{ + class KWall final : + public KObject + { + public: + KWall(const KVector2D& position, const KTexture& texture) + : KObject(position, texture), + Collider(this, texture.GetWidth() * 1.f, texture.GetHeight() * 1.f) + { + } + + const KCollider* GetCollider() const override; + private: + KRect Collider; + }; +} + diff --git a/2dgk_7/2dgk_7/Utils.cpp b/2dgk_7/2dgk_7/Utils.cpp index 6d102ff..b889ed7 100644 --- a/2dgk_7/2dgk_7/Utils.cpp +++ b/2dgk_7/2dgk_7/Utils.cpp @@ -1,16 +1,7 @@ #include "Utils.h" -#include - namespace KapitanGame { namespace Utils { - double RandomNumber() { - // Making rng static ensures that it stays the same - // Between different invocations of the function - static std::default_random_engine rng(make_default_random_engine()); - - std::uniform_real_distribution dist(0.0, 1.0); - return dist(rng); - } + } } diff --git a/2dgk_7/2dgk_7/Utils.h b/2dgk_7/2dgk_7/Utils.h index 54aed2a..4b4ce7f 100644 --- a/2dgk_7/2dgk_7/Utils.h +++ b/2dgk_7/2dgk_7/Utils.h @@ -3,7 +3,10 @@ #include #include #include +#include + #include "KPlayer.h" + namespace KapitanGame { namespace Utils { @@ -18,19 +21,19 @@ namespace KapitanGame { return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside } template - constexpr const T& Clamp01(const T& x) - { - return Clamp(x, 0.f, 1.f); - } - template constexpr const T& Clamp(const T& x, const T& min, const T& max) { return std::max(std::min(max, x), min); } template + constexpr const T& Clamp01(const T& x) + { + return Clamp(x, 0.f, 1.f); + } + template constexpr const T& Lerp(const T& a, const T& b, const float& t) { - return a + (b - a) * t; + return a + (b - a) * Clamp01(t); } static std::default_random_engine make_default_random_engine() @@ -49,15 +52,49 @@ namespace KapitanGame { return std::default_random_engine{ seq }; } - double RandomNumber(); + inline std::default_random_engine& GetRandomEngine() + { + // Making rng static ensures that it stays the same + // Between different invocations of the function + static std::default_random_engine rng(make_default_random_engine()); + return rng; + } - const KPlayer GetPlayerFromString(const std::string& str) { - static std::unordered_map const table = { {"Player1",KPlayer::Player1},{"Player2",KPlayer::Player2} }; - auto it = table.find(str); - if (it != table.end()) { + inline double RandomNumber() { + const std::uniform_real_distribution dist(0.0, 1.0); + return dist(GetRandomEngine()); + } + + template + class Iterator { + typedef std::underlying_type_t ValT; + int Value; + public: + explicit Iterator(const C& f) : Value(static_cast(f)) {} + Iterator() : Value(static_cast(BeginVal)) {} + Iterator operator++() { + ++Value; + return *this; + } + C operator*() { return static_cast(Value); } + Iterator begin() { return *this; } //default ctor is good + Iterator end() { + static const Iterator END_ITERATE = ++Iterator(EndVal); // cache it + return END_ITERATE; + } + bool operator!=(const Iterator& i) { return Value != i.Value; } + }; + + inline KPlayer GetPlayerFromString(const std::string& str) + { + static std::unordered_map const TABLE = { {"Player1",KPlayer::Player1},{"Player2",KPlayer::Player2} }; + const auto it = TABLE.find(str); + if (it != TABLE.end()) { return it->second; } return KPlayer::Player1; } + + typedef Iterator KPlayerIterator; } -} \ No newline at end of file +} diff --git a/2dgk_7/2dgk_7/assets/fonts/LICENSE.txt b/2dgk_7/2dgk_7/assets/fonts/LICENSE.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/2dgk_7/2dgk_7/assets/fonts/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/2dgk_7/2dgk_7/assets/fonts/Roboto-Thin.ttf b/2dgk_7/2dgk_7/assets/fonts/Roboto-Thin.ttf new file mode 100644 index 0000000..b7afed0 --- /dev/null +++ b/2dgk_7/2dgk_7/assets/fonts/Roboto-Thin.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf9760a4821688d544ec7dafba7b060ab1fa758360403537579bf06792d290f8 +size 168488 diff --git a/2dgk_7/2dgk_7/assets/levels/level2.txt b/2dgk_7/2dgk_7/assets/levels/level2.txt index 1c71b6b..9d7cf99 100644 --- a/2dgk_7/2dgk_7/assets/levels/level2.txt +++ b/2dgk_7/2dgk_7/assets/levels/level2.txt @@ -24,7 +24,7 @@ # # # # # # # # # ### ##### ############# ### ##### # # # # # # # # # # -### # # ######### # # # # ### # ### # +### # # ######### # # # # # # # ### # # # # # # # # # # # # ##### ### ### # # ### # ### ##### # # # # # # # # # # # # # diff --git a/2dgk_7/2dgk_7/assets/textures/P1.bmp b/2dgk_7/2dgk_7/assets/textures/P1.bmp index f83e1fe..3f1c1f5 100644 --- a/2dgk_7/2dgk_7/assets/textures/P1.bmp +++ b/2dgk_7/2dgk_7/assets/textures/P1.bmp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b30a0d9f2b72be79604b33f38401c7991fb300fee9747786d51defe88800a071 +oid sha256:4648df597e5ecfa272152784dc7adc867cffed541e1784e8b337022a3438218b size 1782 diff --git a/2dgk_7/2dgk_7/assets/textures/P2.bmp b/2dgk_7/2dgk_7/assets/textures/P2.bmp index 61045f0..335f841 100644 --- a/2dgk_7/2dgk_7/assets/textures/P2.bmp +++ b/2dgk_7/2dgk_7/assets/textures/P2.bmp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:10e48bd872907ed9efe67269f21862a33948c31c53aa303b0a738e4317e03275 +oid sha256:a7c466c5e23dcedc4108ee4d7b64d39dc451f6c91f1f0fff50fb5a62eaf06ece size 1782 diff --git a/2dgk_7/2dgk_7/assets/textures/arrow.bmp b/2dgk_7/2dgk_7/assets/textures/arrow.bmp new file mode 100644 index 0000000..ee330c7 --- /dev/null +++ b/2dgk_7/2dgk_7/assets/textures/arrow.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9216fa8cd3c863a9ff910c86d4d7b7cf03fe2f8164cfccf41eaa80f5779d3721 +size 3126 diff --git a/2dgk_7/2dgk_7/config.default.ini b/2dgk_7/2dgk_7/config.default.ini deleted file mode 100644 index ff1fd5a..0000000 --- a/2dgk_7/2dgk_7/config.default.ini +++ /dev/null @@ -1,15 +0,0 @@ -[Input] -[.Player1] -AxisMappings=(AxisName="MoveY",Scale=-1.000000,Key=W) -AxisMappings=(AxisName="MoveY",Scale=1.000000,Key=S) -AxisMappings=(AxisName="MoveX",Scale=1.000000,Key=Gamepad1_LeftX) -AxisMappings=(AxisName="MoveX",Scale=1.000000,Key=D) -AxisMappings=(AxisName="MoveX",Scale=-1.000000,Key=A) -AxisMappings=(AxisName="MoveY",Scale=1.000000,Key=Gamepad1_LeftY) -[.Player2] -AxisMappings=(AxisName="MoveY",Scale=-1.000000,Key=I) -AxisMappings=(AxisName="MoveY",Scale=1.000000,Key=K) -AxisMappings=(AxisName="MoveX",Scale=1.000000,Key=L) -AxisMappings=(AxisName="MoveX",Scale=-1.000000,Key=J) -AxisMappings=(AxisName="MoveY",Scale=1.000000,Key=Gamepad2_LeftY) -AxisMappings=(AxisName="MoveX",Scale=1.000000,Key=Gamepad2_LeftX) diff --git a/2dgk_7/2dgk_7/config.json b/2dgk_7/2dgk_7/config.json index e57f294..b6ff979 100644 --- a/2dgk_7/2dgk_7/config.json +++ b/2dgk_7/2dgk_7/config.json @@ -24,13 +24,13 @@ }, { "AxisName": "MoveY", - "Scale": -1.000000, - "Key": "Gamepad1_LeftY" + "Scale": 1.000000, + "Key": "Gamepad0_LeftY" }, { "AxisName": "MoveX", "Scale": 1.000000, - "Key": "Gamepad1_LeftX" + "Key": "Gamepad0_LeftX" } ], "ActionMappings": [] @@ -49,23 +49,23 @@ }, { "AxisName": "MoveX", - "Scale": 1.000000, + "Scale": -1.000000, "Key": "J" }, { "AxisName": "MoveX", - "Scale": -1.000000, + "Scale": 1.000000, "Key": "L" }, { "AxisName": "MoveY", - "Scale": -1.000000, - "Key": "Gamepad2_LeftY" + "Scale": 1.000000, + "Key": "Gamepad1_LeftY" }, { "AxisName": "MoveX", "Scale": 1.000000, - "Key": "Gamepad2_LeftX" + "Key": "Gamepad1_LeftX" } ], "ActionMappings": [] diff --git a/2dgk_7/2dgk_7/level.txt b/2dgk_7/2dgk_7/level.txt deleted file mode 100644 index 41ca7c7..0000000 --- a/2dgk_7/2dgk_7/level.txt +++ /dev/null @@ -1,31 +0,0 @@ -/------------\/------------\ -|............||............| -|./--\./---\.||./---\./--\.| -|#| |.| |.||.| |.| |#| -|.`--'.`---'.`'.`---'.`--'.| -|..........................| -|./--\./\./------\./\./--\.| -|.`--'.||.`--\/--'.||.`--'.| -|......||....||....||......| -`----\.|`--\ || /--'|./----' - |.|/--' `' `--\|.| - |.|| ||.| - |.|| /--==--\ ||.| ------'.`' | | `'.`----- - . | | . ------\./\ | | /\./----- - |.|| `------' ||.| - |.|| ||.| - |.|| /------\ ||.| -/----'.`' `--\/--' `'.`----\ -|............||............| -|./--\./---\.||./---\./--\.| -|.`-\|.`---'.`'.`---'.|/-'.| -|#..||....... .......||..#| -`-\.||./\./------\./\.||./-' -/-'.`'.||.`--\/--'.||.`'.`-\ -|......||....||....||......| -|./----'`--\.||./--'`----\.| -|.`--------'.`'.`--------'.| -|..........................| -`--------------------------' \ No newline at end of file diff --git a/2dgk_7/2dgk_7/resource.h b/2dgk_7/2dgk_7/resource.h new file mode 100644 index 0000000..7144123 --- /dev/null +++ b/2dgk_7/2dgk_7/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by 2dgk_7.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/2dgk_7/2dgk_7/vcpkg.json b/2dgk_7/2dgk_7/vcpkg.json index e59b4ad..c9f47e3 100644 --- a/2dgk_7/2dgk_7/vcpkg.json +++ b/2dgk_7/2dgk_7/vcpkg.json @@ -4,6 +4,7 @@ "version": "0.1.0", "dependencies": [ "sdl2", - "nlohmann-json" + "nlohmann-json", + "sdl2-ttf" ] } \ No newline at end of file