Zad 3 final
This commit is contained in:
parent
9674806687
commit
faa6e109f6
@ -203,6 +203,7 @@
|
||||
<ClInclude Include="KSettings.h" />
|
||||
<ClInclude Include="KTexture.h" />
|
||||
<ClInclude Include="KWall.h" />
|
||||
<ClInclude Include="Property.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="Utils.h" />
|
||||
<ClInclude Include="KVector2d.h" />
|
||||
@ -249,4 +250,9 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
@ -147,6 +147,9 @@
|
||||
<ClInclude Include="KSettings.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Property.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="2dgk_zad3.rc">
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace KapitanGame {
|
||||
namespace Constants {
|
||||
namespace KapitanGame::Constants
|
||||
{
|
||||
constexpr const char* WINDOW_TITLE = "2DGK - Zadanie 3 (Lab 11-12)";
|
||||
//Analog joystick dead zone
|
||||
constexpr int JOYSTICK_DEAD_ZONE = 8000;
|
||||
@ -15,8 +15,7 @@ namespace KapitanGame {
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "KCircle.h"
|
||||
|
||||
#include <SDL_rect.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "KRect.h"
|
||||
@ -13,13 +14,11 @@ namespace KapitanGame {
|
||||
|
||||
bool KCircle::IsCollision(const KCollider* other) const
|
||||
{
|
||||
const auto circle = dynamic_cast<const KCircle*>(other);
|
||||
if (circle != nullptr)
|
||||
if (const auto circle = dynamic_cast<const KCircle*>(other); circle != nullptr)
|
||||
return IsCollision(circle);
|
||||
|
||||
|
||||
const auto rect = dynamic_cast<const KRect*>(other);
|
||||
if (rect != nullptr)
|
||||
if (const auto rect = dynamic_cast<const KRect*>(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<const KCircle*>(other);
|
||||
if (circle != nullptr)
|
||||
if (const auto circle = dynamic_cast<const KCircle*>(other); circle != nullptr)
|
||||
return GetSeparationVector(circle);
|
||||
|
||||
const auto rect = dynamic_cast<const KRect*>(other);
|
||||
if (rect != nullptr)
|
||||
if (const auto rect = dynamic_cast<const KRect*>(other); rect != nullptr)
|
||||
return GetSeparationVector(rect);
|
||||
|
||||
throw std::runtime_error("unsupported shape");
|
||||
|
@ -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 };
|
||||
};
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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<float>(texture.GetWidth()), static_cast<float>(texture.GetHeight()))
|
||||
{
|
||||
}
|
||||
|
||||
const KCollider* GetCollider() const override;
|
||||
[[nodiscard]] const KCollider* GetCollider() const override;
|
||||
private:
|
||||
KRect Collider;
|
||||
};
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "KFont.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#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);)
|
||||
{
|
||||
int w, h;
|
||||
TTF_SizeText(Font, line.c_str(), &w, &h);
|
||||
if (w > width) width = w;
|
||||
height += w+spacing;
|
||||
}
|
||||
if (height > 0)
|
||||
height -= spacing;
|
||||
inputText.clear();
|
||||
inputText.seekg(0);
|
||||
SDL_Surface* textureSurface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 8, SDL_PIXELFORMAT_INDEX8);
|
||||
{
|
||||
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
|
||||
{
|
||||
texture.LoadFromSurface(textSurface, renderer);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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<float>(line.length() * Constants::TILE_WIDTH))
|
||||
mapWidth = static_cast<float>(line.length()) * Constants::TILE_WIDTH;
|
||||
for (auto i = 0ull; i < line.length(); ++i) {
|
||||
KVector2D position{ static_cast<float>(i * Constants::TILE_WIDTH + Constants::TILE_WIDTH / 2) , static_cast<float>(y * Constants::TILE_HEIGHT + Constants::TILE_HEIGHT / 2) };
|
||||
KVector2D position{
|
||||
static_cast<float>(i * Constants::TILE_WIDTH + Constants::TILE_WIDTH / 2), // NOLINT(bugprone-integer-division)
|
||||
static_cast<float>(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<KPlayerController>(player, this));
|
||||
PlayerControllers.emplace_back(std::make_shared<KPlayerController>(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<float>(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<float>(Settings.MaxJumpHeight),
|
||||
static_cast<float>(Settings.HorizontalDistanceToMaxJumpHeight),
|
||||
static_cast<float>(Settings.JumpInitialVelocity),
|
||||
static_cast<float>(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<int>(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)
|
||||
{
|
||||
|
@ -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<KObject> 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<int>(KPlayer::Player2) + 1] = { 0,0 };
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -121,6 +121,7 @@ namespace KapitanGame {
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "KObject.h"
|
||||
|
||||
#include <SDL_render.h>
|
||||
|
||||
#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
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <atomic>
|
||||
#include <SDL_render.h>
|
||||
|
||||
#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<int> IdCounter;
|
||||
protected:
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <SDL_rect.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "KObject.h"
|
||||
@ -7,7 +8,7 @@
|
||||
|
||||
namespace KapitanGame
|
||||
{
|
||||
struct KSettings;
|
||||
class KSettings;
|
||||
class KPlayerController;
|
||||
|
||||
class KPawn : public KObject
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "KPlayerController.h"
|
||||
|
||||
#include "KGame.h"
|
||||
#include "KInput.h"
|
||||
|
||||
namespace KapitanGame {
|
||||
|
@ -4,15 +4,13 @@
|
||||
#include "KVector2d.h"
|
||||
|
||||
namespace KapitanGame {
|
||||
class KGame;
|
||||
class KInput;
|
||||
|
||||
class KPlayerController : public std::enable_shared_from_this<KPlayerController>
|
||||
{
|
||||
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{};
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -1,9 +1,98 @@
|
||||
#include "KSettings.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
@ -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<float, KSettings> MaxJumpHeight, HorizontalDistanceToMaxJumpHeight;
|
||||
const ReadOnlyProperty<float, KSettings> TimeToMaxHeight, Gravity, JumpInitialVelocity, ShortJumpVelocity;
|
||||
const Property<bool, KSettings> 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();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "KTexture.h"
|
||||
|
||||
#include <SDL_render.h>
|
||||
|
||||
namespace KapitanGame {
|
||||
KTexture::KTexture() : Texture(nullptr), Width(0), Height(0)
|
||||
{
|
||||
|
54
2dgk_zad3/2dgk_zad3/Property.h
Normal file
54
2dgk_zad3/2dgk_zad3/Property.h
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
namespace KapitanGame
|
||||
{
|
||||
template <class T, class C>
|
||||
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 T, class C>
|
||||
class Property : public ReadOnlyProperty<T,C> {
|
||||
void(C::* Setter)(T);
|
||||
public:
|
||||
Property() : ReadOnlyProperty(), Setter() {}
|
||||
Property(C* owner, T(C::* getter)(), void(C::* setter)(T)) : ReadOnlyProperty<T, C>(owner,getter), Setter(setter) {}
|
||||
void Set(T value) const {
|
||||
(this->Owner->*Setter)(value);
|
||||
}
|
||||
|
||||
const Property<T, C>& operator = (T value) const { // NOLINT(misc-unconventional-assign-operator)
|
||||
Set(value);
|
||||
return *this;
|
||||
}
|
||||
const Property<T, C>& operator -= (T value) const { // NOLINT(misc-unconventional-assign-operator)
|
||||
Set(this->Get() - value);
|
||||
return *this;
|
||||
}
|
||||
const Property<T, C>& operator += (T value) const { // NOLINT(misc-unconventional-assign-operator)
|
||||
Set(this->Get() + value);
|
||||
return *this;
|
||||
}
|
||||
const Property<T, C>& operator *= (T value) const { // NOLINT(misc-unconventional-assign-operator)
|
||||
Set(this->Get() * value);
|
||||
return *this;
|
||||
}
|
||||
const Property<T, C>& operator /= (T value) const { // NOLINT(misc-unconventional-assign-operator)
|
||||
Set(this->Get() / value);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user