diff --git a/2dgk_zad3/2dgk_zad3/2dgk_zad3.vcxproj b/2dgk_zad3/2dgk_zad3/2dgk_zad3.vcxproj
index c0a36d3..c4612ad 100644
--- a/2dgk_zad3/2dgk_zad3/2dgk_zad3.vcxproj
+++ b/2dgk_zad3/2dgk_zad3/2dgk_zad3.vcxproj
@@ -203,6 +203,7 @@
     
     
     
+    
     
     
     
@@ -249,4 +250,9 @@
   
   
   
+  
+    
+      
+    
+  
 
\ No newline at end of file
diff --git a/2dgk_zad3/2dgk_zad3/2dgk_zad3.vcxproj.filters b/2dgk_zad3/2dgk_zad3/2dgk_zad3.vcxproj.filters
index 74e4d9b..e8a8395 100644
--- a/2dgk_zad3/2dgk_zad3/2dgk_zad3.vcxproj.filters
+++ b/2dgk_zad3/2dgk_zad3/2dgk_zad3.vcxproj.filters
@@ -147,6 +147,9 @@
     
       Header Files
     
+    
+      Header Files
+    
   
   
     
diff --git a/2dgk_zad3/2dgk_zad3/Constants.h b/2dgk_zad3/2dgk_zad3/Constants.h
index 816a48e..5792a3f 100644
--- a/2dgk_zad3/2dgk_zad3/Constants.h
+++ b/2dgk_zad3/2dgk_zad3/Constants.h
@@ -1,22 +1,21 @@
 #pragma once
 
-namespace KapitanGame {
-	namespace Constants {
-		constexpr const char* WINDOW_TITLE = "2DGK - Zadanie 3 (Lab 11-12)";
-		//Analog joystick dead zone
-		constexpr int JOYSTICK_DEAD_ZONE = 8000;
-		//Screen dimension constants
-		constexpr int WINDOW_DEAD_ZONE = 100;
-		constexpr int SCREEN_WIDTH = 640;
-		constexpr int SCREEN_HEIGHT = 480;
-		constexpr float SCREEN_RATIO = static_cast(SCREEN_WIDTH) / SCREEN_HEIGHT;
-		constexpr int TILE_WIDTH = 32;
-		constexpr int TILE_HEIGHT = 32;
-		constexpr float SPEED = 200.f;
-		constexpr float SMOOTH = 0.4f;
-		constexpr float JUMP_SPEED = 300.f;
-		constexpr float GRAVITY = 450.f;
-		constexpr float MAX_JUMP_VELOCITY = 1000.f;
-		constexpr float MAX_GRAVITY = 1000.f;
-	}
+namespace KapitanGame::Constants
+{
+	constexpr const char* WINDOW_TITLE = "2DGK - Zadanie 3 (Lab 11-12)";
+	//Analog joystick dead zone
+	constexpr int JOYSTICK_DEAD_ZONE = 8000;
+	//Screen dimension constants
+	constexpr int WINDOW_DEAD_ZONE = 100;
+	constexpr int SCREEN_WIDTH = 640;
+	constexpr int SCREEN_HEIGHT = 480;
+	constexpr float SCREEN_RATIO = static_cast(SCREEN_WIDTH) / SCREEN_HEIGHT;
+	constexpr int TILE_WIDTH = 32;
+	constexpr int TILE_HEIGHT = 32;
+	constexpr float SPEED = 200.f;
+	constexpr float SMOOTH = 0.4f;
+	constexpr float JUMP_SPEED = 300.f;
+	constexpr float HORIZONTAL_DISTANCE_TO_MAX_JUMP_HEIGHT = TILE_WIDTH * 4.f;
+	constexpr float MAX_JUMP_HEIGHT = TILE_HEIGHT * 4.f;
+	constexpr float MAX_GRAVITY = 1000.f;
 }
diff --git a/2dgk_zad3/2dgk_zad3/KCircle.cpp b/2dgk_zad3/2dgk_zad3/KCircle.cpp
index 51d562c..2533f88 100644
--- a/2dgk_zad3/2dgk_zad3/KCircle.cpp
+++ b/2dgk_zad3/2dgk_zad3/KCircle.cpp
@@ -1,5 +1,6 @@
 #include "KCircle.h"
 
+#include 
 #include 
 
 #include "KRect.h"
@@ -13,13 +14,11 @@ namespace KapitanGame {
 
 	bool KCircle::IsCollision(const KCollider* other) const
 	{
-		const auto circle = dynamic_cast(other);
-		if (circle != nullptr)
+		if (const auto circle = dynamic_cast(other); circle != nullptr)
 			return IsCollision(circle);
 
 
-		const auto rect = dynamic_cast(other);
-		if (rect != nullptr)
+		if (const auto rect = dynamic_cast(other); rect != nullptr)
 			return IsCollision(rect);
 
 		throw std::runtime_error("unsupported shape");
@@ -27,12 +26,10 @@ namespace KapitanGame {
 
 	KVector2D KCircle::GetSeparationVector(const KCollider* other) const
 	{
-		const auto circle = dynamic_cast(other);
-		if (circle != nullptr)
+		if (const auto circle = dynamic_cast(other); circle != nullptr)
 			return GetSeparationVector(circle);
 
-		const auto rect = dynamic_cast(other);
-		if (rect != nullptr)
+		if (const auto rect = dynamic_cast(other); rect != nullptr)
 			return GetSeparationVector(rect);
 
 		throw std::runtime_error("unsupported shape");
diff --git a/2dgk_zad3/2dgk_zad3/KCircle.h b/2dgk_zad3/2dgk_zad3/KCircle.h
index a4db204..3081a5a 100644
--- a/2dgk_zad3/2dgk_zad3/KCircle.h
+++ b/2dgk_zad3/2dgk_zad3/KCircle.h
@@ -11,8 +11,8 @@ namespace KapitanGame {
 	class KCircle final : public KCollider
 	{
 	public:
-		KCircle(KObject* parent, const float radius);
-		float GetRadius() const;
+		KCircle(KObject* parent, float radius);
+		[[nodiscard]] float GetRadius() const;
 	private:
 		KVector2D GetSeparationVector(const KCircle* other) const;
 		KVector2D GetSeparationVector(const KRect* other) const;
@@ -21,9 +21,9 @@ namespace KapitanGame {
 	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;
+		[[nodiscard]] KVector2D GetSeparationVector(const SDL_FRect& map) const override;
+		[[nodiscard]] float GetWidth() const override;
+		[[nodiscard]] float GetHeight() const override;
 	private:
 		float Radius{ 1.f };
 	};
diff --git a/2dgk_zad3/2dgk_zad3/KCollider.h b/2dgk_zad3/2dgk_zad3/KCollider.h
index 77e8e07..eb14f63 100644
--- a/2dgk_zad3/2dgk_zad3/KCollider.h
+++ b/2dgk_zad3/2dgk_zad3/KCollider.h
@@ -23,10 +23,10 @@ namespace KapitanGame {
 		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;
+		[[nodiscard]] virtual KVector2D GetSeparationVector(const SDL_FRect& map) const = 0;
+		[[nodiscard]] virtual float GetWidth() const = 0;
+		[[nodiscard]] virtual float GetHeight() const = 0;
+		[[nodiscard]] KObject* GetParent() const;
 	private:
 		KObject* Parent;
 	};
diff --git a/2dgk_zad3/2dgk_zad3/KExit.h b/2dgk_zad3/2dgk_zad3/KExit.h
index 60c5d45..2c09a9b 100644
--- a/2dgk_zad3/2dgk_zad3/KExit.h
+++ b/2dgk_zad3/2dgk_zad3/KExit.h
@@ -10,11 +10,11 @@ namespace KapitanGame
 	public:
 		KExit(const KVector2D& position, const KTexture& texture)
 			: KObject(position, texture),
-			Collider(this, texture.GetWidth() * 1.f, texture.GetHeight() * 1.f)
+			Collider(this, static_cast(texture.GetWidth()), static_cast(texture.GetHeight()))
 		{
 		}
 
-		const KCollider* GetCollider() const override;
+		[[nodiscard]] const KCollider* GetCollider() const override;
 	private:
 		KRect Collider;
 	};
diff --git a/2dgk_zad3/2dgk_zad3/KFont.cpp b/2dgk_zad3/2dgk_zad3/KFont.cpp
index 7bbb11d..16dea77 100644
--- a/2dgk_zad3/2dgk_zad3/KFont.cpp
+++ b/2dgk_zad3/2dgk_zad3/KFont.cpp
@@ -1,5 +1,7 @@
 #include "KFont.h"
 
+#include 
+
 #include "KTexture.h"
 
 namespace KapitanGame
@@ -48,16 +50,49 @@ namespace KapitanGame
 	KTexture KFont::GetTextTexture(const std::string& text, const SDL_Color textColor, SDL_Renderer* renderer) const
 	{
 		KTexture texture;
-		SDL_Surface* textSurface = TTF_RenderText_Solid(Font, text.c_str(), textColor);
-		if (textSurface == nullptr)
+		constexpr int spacing = 1;
+		int width, height = width = 0;
+		std::istringstream inputText;
+		inputText.str(text);
+		for(std::string line; std::getline(inputText, line);)
 		{
-			printf("Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError());
+			int w, h;
+			TTF_SizeText(Font, line.c_str(), &w, &h);
+			if (w > width) width = w;
+			height += w+spacing;
 		}
-		else
+		if (height > 0)
+			height -= spacing;
+		inputText.clear();
+		inputText.seekg(0);
+		SDL_Surface* textureSurface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 8, SDL_PIXELFORMAT_INDEX8);
 		{
-			texture.LoadFromSurface(textSurface, renderer);
-			SDL_FreeSurface(textSurface);
+			const SDL_Palette* palette = textureSurface->format->palette;
+			palette->colors[0].r = 255 - textColor.r;
+			palette->colors[0].g = 255 - textColor.g;
+			palette->colors[0].b = 255 - textColor.b;
+			palette->colors[1].r = textColor.r;
+			palette->colors[1].g = textColor.g;
+			palette->colors[1].b = textColor.b;
+			palette->colors[1].a = textColor.a;
 		}
+		SDL_SetColorKey(textureSurface, SDL_TRUE, 0);
+		int y = 0;
+		for (std::string line; std::getline(inputText, line);) {
+			if (SDL_Surface* textSurface = TTF_RenderText_Solid(Font, line.c_str(), textColor); textSurface == nullptr)
+			{
+				printf("Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError());
+			}
+			else
+			{
+				SDL_Rect destRect{0, y, textSurface->w, textSurface->h};
+				SDL_BlitSurface(textSurface, nullptr, textureSurface, &destRect);
+				y += textSurface->h + spacing;
+				SDL_FreeSurface(textSurface);
+			}
+		}
+		texture.LoadFromSurface(textureSurface, renderer);
+		SDL_FreeSurface(textureSurface);
 		return texture;
 	}
 
diff --git a/2dgk_zad3/2dgk_zad3/KGame.cpp b/2dgk_zad3/2dgk_zad3/KGame.cpp
index 830be5a..418d9e5 100644
--- a/2dgk_zad3/2dgk_zad3/KGame.cpp
+++ b/2dgk_zad3/2dgk_zad3/KGame.cpp
@@ -11,18 +11,13 @@
 #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() : Time(0), PreviousTime(0), Map()
+	KGame::KGame() : Time(0), PreviousTime(0), Map(), Settings(Constants::MAX_JUMP_HEIGHT, Constants::HORIZONTAL_DISTANCE_TO_MAX_JUMP_HEIGHT)
 	{
 		//Initialize SDL
 		if (SDL_Init(SDL_INIT_VIDEO) < 0)
@@ -109,7 +104,10 @@ namespace KapitanGame {
 				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) };
+					KVector2D position{
+						static_cast(i * Constants::TILE_WIDTH + Constants::TILE_WIDTH / 2),  // NOLINT(bugprone-integer-division)
+						static_cast(y * Constants::TILE_HEIGHT + Constants::TILE_HEIGHT / 2)  // NOLINT(bugprone-integer-division)
+					};
 					switch (line[i])
 					{
 					case '#':
@@ -150,7 +148,7 @@ namespace KapitanGame {
 				break;
 			}
 
-			PlayerControllers.emplace_back(std::make_shared(player, this));
+			PlayerControllers.emplace_back(std::make_shared(player));
 			PlayerControllers.back()->SetupInputBindings(Input);
 		}
 		Textures.emplace("wall.bmp", KTexture());
@@ -168,11 +166,8 @@ namespace KapitanGame {
 			Fonts.erase("PressStart2P-Regular");
 			success = false;
 		}
-		//Textures.emplace("Text_Score", Fonts["Roboto-Thin"].GetTextWithOutlineTexture("0:0", { 0xFF,0xFF,0xFF,0xFF }, { 0,0,0,0xFF }, 1, Renderer));
-		//Textures.emplace("Text_Winner", KTexture());
 
-		std::ifstream configFile("config.json");
-		if (configFile.fail()) {
+		if (std::ifstream configFile("config.json"); configFile.fail()) {
 			printf("Failed to load config.json!\n");
 			success = false;
 		}
@@ -218,8 +213,7 @@ namespace KapitanGame {
 
 			camera.Update(Pawns, Map);
 
-			VelocityTextureDirty = true;
-			GravityTextureDirty = true;
+			SettingsTextTextureDirty = true;
 
 			Time = PreviousTime = SDL_GetTicks();
 			printf("\n");
@@ -229,7 +223,7 @@ namespace KapitanGame {
 			{
 				PreviousTime = Time;
 				Time = SDL_GetTicks();
-				float deltaTime = (Time - PreviousTime) * 0.001f;
+				float deltaTime = static_cast(Time - PreviousTime) * 0.001f;
 
 				Input.HandleInputPreEvents();
 
@@ -255,31 +249,28 @@ namespace KapitanGame {
 				if (devMode >= 1) {
 					if (Input.IsKeyboardButtonPressed(SDL_SCANCODE_F2))
 					{
-						CollisionEnabled = !CollisionEnabled;
+						Settings.CollisionEnabled = !Settings.CollisionEnabled;
 					}
 					if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_F3))
 					{
-						Settings.JumpVelocity -= 0.1f;
-						if (Settings.JumpVelocity < 0) Settings.JumpVelocity = 0;
-						VelocityTextureDirty = true;
+						Settings.MaxJumpHeight -= 0.1f;
+						//Settings.SetMaxJumpHeight(Settings.GetMaxJumpHeight() - 0.1f);
+						SettingsTextTextureDirty = true;
 					}
 					if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_F4))
 					{
-						Settings.JumpVelocity += 0.1f;
-						if (Settings.JumpVelocity > Constants::MAX_JUMP_VELOCITY) Settings.JumpVelocity = Constants::MAX_JUMP_VELOCITY;
-						VelocityTextureDirty = true;
+						Settings.MaxJumpHeight += 0.1f;
+						SettingsTextTextureDirty = true;
 					}
 					if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_F5))
 					{
-						Settings.Gravity -= 0.1f;
-						if (Settings.Gravity < 0) Settings.Gravity = 0;
-						GravityTextureDirty = true;
+						Settings.HorizontalDistanceToMaxJumpHeight -= 0.1f;
+						SettingsTextTextureDirty = true;
 					}
 					if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_F6))
 					{
-						Settings.Gravity += 0.1f;
-						if (Settings.Gravity > Constants::MAX_GRAVITY) Settings.Gravity = Constants::MAX_GRAVITY;
-						GravityTextureDirty = true;
+						Settings.HorizontalDistanceToMaxJumpHeight += 0.1f;
+						SettingsTextTextureDirty = true;
 					}
 				}
 
@@ -291,7 +282,7 @@ namespace KapitanGame {
 						if (!Playing) break;
 						pawn->MovementStep(deltaTime);
 					}
-					if (CollisionEnabled) {
+					if (Settings.CollisionEnabled) {
 						for (const auto& pawn : Pawns) {
 							if (!Playing) break;
 							pawn->CollisionDetectionStep(Objects);
@@ -309,14 +300,19 @@ namespace KapitanGame {
 					camera.Update(Pawns, Map);
 
 				}
-				if (VelocityTextureDirty) {
-					Textures.insert_or_assign("Text_Velocity", Fonts["PressStart2P-Regular"].GetTextTexture(Utils::StringFormat("Velocity: %f", Settings.JumpVelocity), { 0,0,0,0xFF }, Renderer));
-					VelocityTextureDirty = false;
-				}
-				if (GravityTextureDirty) {
-					Textures.insert_or_assign("Text_Gravity", Fonts["PressStart2P-Regular"].GetTextTexture(Utils::StringFormat("Gravity: %f", Settings.Gravity), { 0,0,0,0xFF }, Renderer));
-					GravityTextureDirty = false;
-				}
+				//if (SettingsTextTextureDirty) {
+					Textures.insert_or_assign("Text_Settings", Fonts["PressStart2P-Regular"].GetTextTexture(
+						Utils::StringFormat(
+							"Max Jump Height: %f\nHorizontal Distance to Max Jump Height: %f\nInitial Jump Velocity: %f\nGravity: %f\nPlayer Position X: %f\nPlayer Position Y: %f",
+							static_cast(Settings.MaxJumpHeight),
+							static_cast(Settings.HorizontalDistanceToMaxJumpHeight),
+							static_cast(Settings.JumpInitialVelocity),
+							static_cast(Settings.Gravity),
+							Pawns.back()->GetPosition().X,
+							Pawns.back()->GetPosition().Y), {0, 0, 0, 0xFF},
+						Renderer));
+					//SettingsTextTextureDirty = false;
+				//}
 
 
 				if (!Playing)
@@ -326,16 +322,6 @@ namespace KapitanGame {
 						LoadLevel();
 						debugCamera.SetDebug(Map);
 						camera.Update(Pawns, Map);
-						if (ShowWinner)
-						{
-							for (auto i : Utils::KPlayerIterator())
-							{
-								Scores[static_cast(i)] = 0;
-							}
-							//Textures.erase("Text_Score");
-							//Textures.emplace("Text_Score", Fonts["Roboto-Thin"].GetTextWithOutlineTexture(Utils::StringFormat("%d:%d", Scores[0], Scores[1]), { 0xFF,0xFF,0xFF,0xFF }, { 0,0,0,0xFF }, 1, Renderer));
-							ShowWinner = false;
-						}
 						Playing = true;
 						continue;
 					}
@@ -355,22 +341,10 @@ namespace KapitanGame {
 					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 (devMode >= 1) {
-					Textures["Text_Velocity"].Render(Renderer, 10.f, 25.f);
-					Textures["Text_Gravity"].Render(Renderer, 10.f, 30.f + Textures["Text_Velocity"].GetHeight());
+					Textures["Text_Settings"].Render(Renderer, 10.f, 25.f);
 				}
 				if (devMode >= 2)
 				{
diff --git a/2dgk_zad3/2dgk_zad3/KGame.h b/2dgk_zad3/2dgk_zad3/KGame.h
index d54b48f..6a4d391 100644
--- a/2dgk_zad3/2dgk_zad3/KGame.h
+++ b/2dgk_zad3/2dgk_zad3/KGame.h
@@ -20,7 +20,6 @@ namespace KapitanGame {
 	public:
 		KGame();
 		~KGame();
-		void Win(KPlayer player);
 		KGame(const KGame& other) = delete;
 		KGame(KGame&& other) noexcept = delete;
 		KGame& operator=(const KGame& other) = delete;
@@ -40,12 +39,9 @@ namespace KapitanGame {
 		uint32_t Time;
 		uint32_t PreviousTime;
 		SDL_FRect Map;
-		bool CollisionEnabled = true;
-		bool ShowWinner = false;
 		std::weak_ptr Exit;
 		KSettings Settings;
-		bool VelocityTextureDirty;
-		bool GravityTextureDirty;
+		bool SettingsTextTextureDirty = true;
 
 		bool LoadLevel();
 		bool LoadMedia();
@@ -53,7 +49,6 @@ namespace KapitanGame {
 		int LvlCounter = 1;
 		bool Playing = true;
 		uint32_t RestartTick = -1;
-		short Scores[static_cast(KPlayer::Player2) + 1] = { 0,0 };
 	};
 }
 
diff --git a/2dgk_zad3/2dgk_zad3/KInput.cpp b/2dgk_zad3/2dgk_zad3/KInput.cpp
index 0b5544b..a13b3c6 100644
--- a/2dgk_zad3/2dgk_zad3/KInput.cpp
+++ b/2dgk_zad3/2dgk_zad3/KInput.cpp
@@ -121,6 +121,7 @@ namespace KapitanGame {
 				}
 			}
 			break;
+		default: break;
 		}
 	}
 
diff --git a/2dgk_zad3/2dgk_zad3/KObject.cpp b/2dgk_zad3/2dgk_zad3/KObject.cpp
index d9cbed9..f11f666 100644
--- a/2dgk_zad3/2dgk_zad3/KObject.cpp
+++ b/2dgk_zad3/2dgk_zad3/KObject.cpp
@@ -1,5 +1,7 @@
 #include "KObject.h"
 
+#include 
+
 #include "KCamera.h"
 
 namespace KapitanGame
@@ -13,7 +15,7 @@ namespace KapitanGame
 
 	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());
+		Texture.Render(renderer, Position.X - Texture.GetWidth() / 2.f - camera.GetViewport().x, Position.Y - Texture.GetHeight() / 2.f - camera.GetViewport().y, nullptr, camera.GetScale());  // NOLINT(clang-diagnostic-implicit-int-float-conversion, bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions)
 	}
 
 	KVector2D KObject::GetPosition() const
diff --git a/2dgk_zad3/2dgk_zad3/KObject.h b/2dgk_zad3/2dgk_zad3/KObject.h
index 14482fa..b663278 100644
--- a/2dgk_zad3/2dgk_zad3/KObject.h
+++ b/2dgk_zad3/2dgk_zad3/KObject.h
@@ -1,5 +1,6 @@
 #pragma once
 #include 
+#include 
 
 #include "KTexture.h"
 #include "KVector2d.h"
@@ -15,8 +16,8 @@ namespace KapitanGame
 		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;
+		[[nodiscard]] KVector2D GetPosition() const;
+		[[nodiscard]] virtual const KCollider* GetCollider() const = 0;
 		const int Id;
 		static std::atomic IdCounter;
 	protected:
diff --git a/2dgk_zad3/2dgk_zad3/KPawn.cpp b/2dgk_zad3/2dgk_zad3/KPawn.cpp
index c8cc29a..72c2f3b 100644
--- a/2dgk_zad3/2dgk_zad3/KPawn.cpp
+++ b/2dgk_zad3/2dgk_zad3/KPawn.cpp
@@ -68,6 +68,10 @@ namespace KapitanGame
 			CanDoubleJump = true;
 			HasJumped = false;
 		}
+		if (separationVector.Y > 0)
+		{
+			Velocity.Y = 0;
+		}
 	}
 
 	void KPawn::AddXMovementInput(const float& input)
@@ -77,8 +81,8 @@ namespace KapitanGame
 
 	void KPawn::StopJump() {
 		if (!CanJump) {
-			if (Velocity.Y < -Settings->ShortJumpVelocity())
-				Velocity.Y = -Settings->ShortJumpVelocity();
+			if (Velocity.Y < -Settings->ShortJumpVelocity)
+				Velocity.Y = -Settings->ShortJumpVelocity;
 		}
 	}
 
@@ -90,12 +94,12 @@ namespace KapitanGame
 		if (CanJump) {
 			CanJump = false;
 			HasJumped = true;
-			Velocity.Y = -Settings->JumpVelocity;
+			Velocity.Y = -Settings->JumpInitialVelocity;
 		}
 		else if (HasJumped && CanDoubleJump)
 		{
 			CanDoubleJump = false;
-			Velocity.Y = -Settings->JumpVelocity;
+			Velocity.Y = -Settings->JumpInitialVelocity;
 		}
 	}
 }
diff --git a/2dgk_zad3/2dgk_zad3/KPawn.h b/2dgk_zad3/2dgk_zad3/KPawn.h
index f255102..dbb3eca 100644
--- a/2dgk_zad3/2dgk_zad3/KPawn.h
+++ b/2dgk_zad3/2dgk_zad3/KPawn.h
@@ -1,5 +1,6 @@
 #pragma once
 #include 
+#include 
 #include 
 
 #include "KObject.h"
@@ -7,7 +8,7 @@
 
 namespace KapitanGame
 {
-	struct KSettings;
+	class KSettings;
 	class KPlayerController;
 
 	class KPawn : public KObject
diff --git a/2dgk_zad3/2dgk_zad3/KPlayerController.cpp b/2dgk_zad3/2dgk_zad3/KPlayerController.cpp
index e7010d7..06665ba 100644
--- a/2dgk_zad3/2dgk_zad3/KPlayerController.cpp
+++ b/2dgk_zad3/2dgk_zad3/KPlayerController.cpp
@@ -1,6 +1,5 @@
 #include "KPlayerController.h"
 
-#include "KGame.h"
 #include "KInput.h"
 
 namespace KapitanGame {
diff --git a/2dgk_zad3/2dgk_zad3/KPlayerController.h b/2dgk_zad3/2dgk_zad3/KPlayerController.h
index 3b1913c..9b3b7ad 100644
--- a/2dgk_zad3/2dgk_zad3/KPlayerController.h
+++ b/2dgk_zad3/2dgk_zad3/KPlayerController.h
@@ -4,15 +4,13 @@
 #include "KVector2d.h"
 
 namespace KapitanGame {
-	class KGame;
 	class KInput;
 
 	class KPlayerController : public std::enable_shared_from_this
 	{
 	public:
-		KPlayerController(const KPlayer player, KGame* const game)
-			: Player(player),
-			Game(game)
+		explicit KPlayerController(const KPlayer player)
+			: Player(player)
 		{
 		}
 
@@ -21,7 +19,6 @@ namespace KapitanGame {
 		void StartJump();
 		void StopJump();
 		void Update(float deltaTime);
-		void NotifyWin() const;
 		void Possess(KPawn* pawn);
 		void UnPossess();
 		const KPlayer& GetPlayer() const;
@@ -29,7 +26,6 @@ namespace KapitanGame {
 		KVector2D Input{ 0.f, 0.f };
 		const KPlayer Player;
 		KPawn* Pawn{};
-		KGame* Game;
 		bool InputStartJump{};
 		bool InputStopJump{};
 	};
diff --git a/2dgk_zad3/2dgk_zad3/KRect.h b/2dgk_zad3/2dgk_zad3/KRect.h
index 66cd3ca..825aa05 100644
--- a/2dgk_zad3/2dgk_zad3/KRect.h
+++ b/2dgk_zad3/2dgk_zad3/KRect.h
@@ -15,20 +15,21 @@ namespace KapitanGame {
 			Height(height)
 		{
 		}
-		float GetWidth() const override;
-		float GetHeight() const override;
+
+		[[nodiscard]] float GetWidth() const override;
+		[[nodiscard]] float GetHeight() const override;
 		static KVector2D GetSeparationVector(float left, float right, float top, float bottom);
 		bool IsCollision(const KCollider* other) const override;
 		KVector2D GetSeparationVector(const KCollider* other) const override;
-		KVector2D GetSeparationVector(const SDL_FRect& map) const override;
+		[[nodiscard]] 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;
+		[[nodiscard]] float GetLeft() const;
+		[[nodiscard]] float GetRight() const;
+		[[nodiscard]] float GetBottom() const;
+		[[nodiscard]] float GetTop() const;
 		bool IsCollision(const KRect* other) const;
 		float Width;
 		float Height;
diff --git a/2dgk_zad3/2dgk_zad3/KSettings.cpp b/2dgk_zad3/2dgk_zad3/KSettings.cpp
index 1597b37..89deca4 100644
--- a/2dgk_zad3/2dgk_zad3/KSettings.cpp
+++ b/2dgk_zad3/2dgk_zad3/KSettings.cpp
@@ -1,9 +1,98 @@
 #include "KSettings.h"
 
+#include 
+#include 
+#include "Constants.h"
+
 namespace KapitanGame
 {
-	float KSettings::ShortJumpVelocity() const
+	KSettings::KSettings(const float maxJumpHeight, const float horizontalDistanceToMaxJumpHeight) : MaxJumpHeightValue(maxJumpHeight),
+		HorizontalDistanceToMaxJumpHeightValue(horizontalDistanceToMaxJumpHeight),
+		TimeToMaxHeightValue(NAN),
+		GravityValue(NAN),
+		JumpInitialVelocityValue(NAN),
+		ShortJumpVelocityValue(NAN),
+		CollisionEnabledValue(true),
+		Dirty(true),
+		MaxJumpHeight(this, &KSettings::GetMaxJumpHeight, &KSettings::SetMaxJumpHeight),
+		HorizontalDistanceToMaxJumpHeight(this, &KSettings::GetHorizontalDistanceToMaxJumpHeight, &KSettings::SetHorizontalDistanceToMaxJumpHeight),
+		TimeToMaxHeight(this, &KSettings::GetTimeToMaxHeight),
+		Gravity(this, &KSettings::GetGravity),
+		JumpInitialVelocity(this, &KSettings::GetJumpInitialVelocity),
+		ShortJumpVelocity(this, &KSettings::GetShortJumpVelocity),
+		CollisionEnabled(this, &KSettings::GetCollisionEnabled, &KSettings::SetCollisionEnabled)
 	{
-		return JumpVelocity / 2.f;
+	}
+
+	void KSettings::SetCollisionEnabled(const bool value)
+	{
+		if (value != CollisionEnabledValue)
+			CollisionEnabledValue = value;
+	}
+
+	void KSettings::SetMaxJumpHeight(const float h)
+	{
+		if (h <= 0.f && MaxJumpHeightValue <= 0.f) return;
+		if (MaxJumpHeightValue != h) {  // NOLINT(clang-diagnostic-float-equal)
+			MaxJumpHeightValue = std::max(h, 0.f);
+			Dirty = true;
+		}
+	}
+
+	void KSettings::SetHorizontalDistanceToMaxJumpHeight(const float xn)
+	{
+		if (xn <= 0.f && HorizontalDistanceToMaxJumpHeightValue <= 0.f) return;
+		if (HorizontalDistanceToMaxJumpHeightValue != xn) {  // NOLINT(clang-diagnostic-float-equal)
+			HorizontalDistanceToMaxJumpHeightValue = std::max(xn, 0.f);
+			Dirty = true;
+		}
+	}
+
+	// ReSharper disable once CppMemberFunctionMayBeConst
+	bool KSettings::GetCollisionEnabled()
+	{
+		return CollisionEnabledValue;
+	}
+
+	float KSettings::GetTimeToMaxHeight()
+	{
+		if (Dirty)
+			TimeToMaxHeightValue = HorizontalDistanceToMaxJumpHeightValue / Constants::SPEED;
+		return TimeToMaxHeightValue;
+	}
+
+	float KSettings::GetGravity()
+	{
+		if (Dirty) {
+			const auto timeToMaxHeight = GetTimeToMaxHeight();
+			GravityValue = 2.0f * MaxJumpHeightValue / (timeToMaxHeight * timeToMaxHeight);
+		}
+		return GravityValue;
+	}
+
+	float KSettings::GetJumpInitialVelocity()
+	{
+		if (Dirty)
+			JumpInitialVelocityValue = 2.0f * MaxJumpHeightValue / GetTimeToMaxHeight();
+		return JumpInitialVelocityValue;
+	}
+
+	float KSettings::GetShortJumpVelocity()
+	{
+		if (Dirty)
+			ShortJumpVelocityValue = GetJumpInitialVelocity() / 2.f;
+		return ShortJumpVelocityValue;
+	}
+
+	// ReSharper disable once CppMemberFunctionMayBeConst
+	float KSettings::GetMaxJumpHeight()
+	{
+		return MaxJumpHeightValue;
+	}
+
+	// ReSharper disable once CppMemberFunctionMayBeConst
+	float KSettings::GetHorizontalDistanceToMaxJumpHeight()
+	{
+		return HorizontalDistanceToMaxJumpHeightValue;
 	}
 }
diff --git a/2dgk_zad3/2dgk_zad3/KSettings.h b/2dgk_zad3/2dgk_zad3/KSettings.h
index 31b189d..2c160ac 100644
--- a/2dgk_zad3/2dgk_zad3/KSettings.h
+++ b/2dgk_zad3/2dgk_zad3/KSettings.h
@@ -1,14 +1,37 @@
 #pragma once
-#include "Constants.h"
+#include "Property.h"
 
 namespace KapitanGame
 {
-	struct KSettings
+	class KSettings final
 	{
-		float Gravity = Constants::GRAVITY;
-		float JumpVelocity = Constants::JUMP_SPEED;
+		float MaxJumpHeightValue;
+		float HorizontalDistanceToMaxJumpHeightValue;
+		float TimeToMaxHeightValue;
+		float GravityValue;
+		float JumpInitialVelocityValue;
+		float ShortJumpVelocityValue;
+		bool CollisionEnabledValue;
+		bool Dirty;
 
-		[[nodiscard]] float ShortJumpVelocity() const;
+	public:
+
+		KSettings(float maxJumpHeight, float horizontalDistanceToMaxJumpHeight);
+		const Property MaxJumpHeight, HorizontalDistanceToMaxJumpHeight;
+		const ReadOnlyProperty TimeToMaxHeight, Gravity, JumpInitialVelocity, ShortJumpVelocity;
+		const Property CollisionEnabled;
+
+	private:
+		void SetCollisionEnabled(bool value);
+		void SetMaxJumpHeight(float h);
+		void SetHorizontalDistanceToMaxJumpHeight(float xn);
+		bool GetCollisionEnabled();
+		float GetTimeToMaxHeight();
+		float GetGravity();
+		float GetJumpInitialVelocity();
+		float GetShortJumpVelocity();
+		float GetMaxJumpHeight();
+		float GetHorizontalDistanceToMaxJumpHeight();
 	};
 }
 
diff --git a/2dgk_zad3/2dgk_zad3/KTexture.cpp b/2dgk_zad3/2dgk_zad3/KTexture.cpp
index ac7798c..244cccf 100644
--- a/2dgk_zad3/2dgk_zad3/KTexture.cpp
+++ b/2dgk_zad3/2dgk_zad3/KTexture.cpp
@@ -1,5 +1,7 @@
 #include "KTexture.h"
 
+#include 
+
 namespace KapitanGame {
 	KTexture::KTexture() : Texture(nullptr), Width(0), Height(0)
 	{
@@ -142,4 +144,4 @@ namespace KapitanGame {
 	{
 		return Height;
 	}
-}
\ No newline at end of file
+}
diff --git a/2dgk_zad3/2dgk_zad3/Property.h b/2dgk_zad3/2dgk_zad3/Property.h
new file mode 100644
index 0000000..f4c6a5e
--- /dev/null
+++ b/2dgk_zad3/2dgk_zad3/Property.h
@@ -0,0 +1,54 @@
+#pragma once
+namespace KapitanGame
+{
+	template 
+	class ReadOnlyProperty {
+	protected:
+		C* Owner;
+		T(C::* Getter)();
+	public:
+		ReadOnlyProperty() : Owner(), Getter() {}
+		ReadOnlyProperty(C* owner, T(C::* getter)()) : Owner(owner), Getter(getter) {}
+
+		[[nodiscard]] T Get() const {
+			return (Owner->*Getter)();
+		}
+
+		// ReSharper disable once CppNonExplicitConversionOperator
+		operator T() const {
+			return Get();
+		}
+	};
+
+	template 
+	class Property : public ReadOnlyProperty {
+		void(C::* Setter)(T);
+	public:
+		Property() : ReadOnlyProperty(), Setter() {}
+		Property(C* owner, T(C::* getter)(), void(C::* setter)(T)) : ReadOnlyProperty(owner,getter), Setter(setter) {}
+		void Set(T value) const {
+			(this->Owner->*Setter)(value);
+		}
+
+		const Property& operator = (T value) const {  // NOLINT(misc-unconventional-assign-operator)
+			Set(value);
+			return *this;
+		}
+		const Property& operator -= (T value) const {  // NOLINT(misc-unconventional-assign-operator)
+			Set(this->Get() - value);
+			return *this;
+		}
+		const Property& operator += (T value) const {  // NOLINT(misc-unconventional-assign-operator)
+			Set(this->Get() + value);
+			return *this;
+		}
+		const Property& operator *= (T value) const {  // NOLINT(misc-unconventional-assign-operator)
+			Set(this->Get() * value);
+			return *this;
+		}
+		const Property& operator /= (T value) const {  // NOLINT(misc-unconventional-assign-operator)
+			Set(this->Get() / value);
+			return *this;
+		}
+	};
+}