Zad2 final
This commit is contained in:
parent
7faaf63fb5
commit
4960cdb39b
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1 +1,2 @@
|
||||
*.bmp filter=lfs diff=lfs merge=lfs -text
|
||||
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||
|
101
2dgk_7/2dgk_7/2dgk_7.rc
Normal file
101
2dgk_7/2dgk_7/2dgk_7.rc
Normal file
@ -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
|
||||
|
@ -154,13 +154,21 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="KCamera.cpp" />
|
||||
<ClCompile Include="KCircle.cpp" />
|
||||
<ClCompile Include="KCirclePawn.cpp" />
|
||||
<ClCompile Include="KExit.cpp" />
|
||||
<ClCompile Include="KFont.cpp" />
|
||||
<ClCompile Include="KGame.cpp" />
|
||||
<ClCompile Include="KInput.cpp" />
|
||||
<ClCompile Include="KObject.cpp" />
|
||||
<ClCompile Include="KPawn.cpp" />
|
||||
<ClCompile Include="KPlayerController.cpp" />
|
||||
<ClCompile Include="KRect.cpp" />
|
||||
<ClCompile Include="KShape.cpp" />
|
||||
<ClCompile Include="KCollider.cpp" />
|
||||
<ClCompile Include="KRectPawn.cpp" />
|
||||
<ClCompile Include="KTexture.cpp" />
|
||||
<ClCompile Include="KWall.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="Utils.cpp" />
|
||||
</ItemGroup>
|
||||
@ -172,17 +180,29 @@
|
||||
<ClInclude Include="Controllers.h" />
|
||||
<ClInclude Include="GamePad.h" />
|
||||
<ClInclude Include="KActionBind.h" />
|
||||
<ClInclude Include="KCamera.h" />
|
||||
<ClInclude Include="KCircle.h" />
|
||||
<ClInclude Include="KCirclePawn.h" />
|
||||
<ClInclude Include="KExit.h" />
|
||||
<ClInclude Include="KFont.h" />
|
||||
<ClInclude Include="KGame.h" />
|
||||
<ClInclude Include="KInput.h" />
|
||||
<ClInclude Include="KObject.h" />
|
||||
<ClInclude Include="KPawn.h" />
|
||||
<ClInclude Include="KPlayer.h" />
|
||||
<ClInclude Include="KPlayerController.h" />
|
||||
<ClInclude Include="KRect.h" />
|
||||
<ClInclude Include="KShape.h" />
|
||||
<ClInclude Include="KCollider.h" />
|
||||
<ClInclude Include="KRectPawn.h" />
|
||||
<ClInclude Include="KTexture.h" />
|
||||
<ClInclude Include="KWall.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="Utils.h" />
|
||||
<ClInclude Include="KVector2d.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="2dgk_7.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -36,12 +36,36 @@
|
||||
<ClCompile Include="KPlayerController.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KShape.cpp">
|
||||
<ClCompile Include="KCollider.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KRect.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KObject.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KPawn.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KWall.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KRectPawn.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KCirclePawn.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KExit.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KCamera.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KFont.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="vcpkg.json" />
|
||||
@ -74,7 +98,7 @@
|
||||
<ClInclude Include="KPlayerController.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KShape.h">
|
||||
<ClInclude Include="KCollider.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KRect.h">
|
||||
@ -89,5 +113,37 @@
|
||||
<ClInclude Include="KPlayer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KObject.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KPawn.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KWall.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KRectPawn.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KCirclePawn.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KExit.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KCamera.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KFont.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="2dgk_7.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -11,8 +11,7 @@ namespace KapitanGame {
|
||||
constexpr float SCREEN_RATIO = static_cast<float>(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;
|
||||
}
|
||||
}
|
||||
|
@ -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<KPlayerController>& 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<KPlayerController> 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<KPlayerController>& 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<KPlayerController> ControllerObject;
|
||||
KPlayerAxisCommand AxisCommand;
|
||||
KPlayer Player;
|
||||
};
|
||||
|
42
2dgk_7/2dgk_7/KCamera.cpp
Normal file
42
2dgk_7/2dgk_7/KCamera.cpp
Normal file
@ -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<KPawn>& playerOne, const std::shared_ptr<KPawn>& 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<float>(-Constants::WINDOW_DEAD_ZONE), map.w + static_cast<float>(Constants::WINDOW_DEAD_ZONE));
|
||||
PlayArea.y = Utils::Clamp(FocusPoint.Y - PlayArea.h / 2.f, static_cast<float>(-Constants::WINDOW_DEAD_ZONE), map.h + static_cast<float>(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;
|
||||
}
|
||||
}
|
42
2dgk_7/2dgk_7/KCamera.h
Normal file
42
2dgk_7/2dgk_7/KCamera.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <SDL_rect.h>
|
||||
|
||||
#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<KPawn>& playerOne, const std::shared_ptr<KPawn>& 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;
|
||||
};
|
||||
}
|
||||
|
@ -1,70 +1,106 @@
|
||||
#include "KCircle.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#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<const KCircle*>(other);
|
||||
if (circle != nullptr)
|
||||
return IsCollision(circle);
|
||||
|
||||
|
||||
const auto rect = dynamic_cast<const KRect*>(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<const KCircle*>(other);
|
||||
if (circle != nullptr)
|
||||
return GetSeparationVector(circle);
|
||||
|
||||
return (Position - f).Length() < Radius;
|
||||
const auto rect = dynamic_cast<const KRect*>(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 {
|
||||
|
@ -1,21 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "KShape.h"
|
||||
#include "KTexture.h"
|
||||
#include <SDL_rect.h>
|
||||
|
||||
#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 };
|
||||
};
|
||||
|
15
2dgk_7/2dgk_7/KCirclePawn.cpp
Normal file
15
2dgk_7/2dgk_7/KCirclePawn.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "KCirclePawn.h"
|
||||
|
||||
namespace KapitanGame
|
||||
{
|
||||
KCirclePawn::KCirclePawn(const KVector2D& position, const KTexture& texture,
|
||||
const std::shared_ptr<KPlayerController>& playerController) : KPawn(position, texture, playerController),
|
||||
Collider(this, static_cast<float>(texture.GetWidth())/2.0f)
|
||||
{
|
||||
}
|
||||
|
||||
const KCollider* KCirclePawn::GetCollider() const
|
||||
{
|
||||
return &Collider;
|
||||
}
|
||||
}
|
18
2dgk_7/2dgk_7/KCirclePawn.h
Normal file
18
2dgk_7/2dgk_7/KCirclePawn.h
Normal file
@ -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<KPlayerController>& playerController);
|
||||
|
||||
const KCollider* GetCollider() const override;
|
||||
private:
|
||||
KCircle Collider;
|
||||
};
|
||||
}
|
||||
|
34
2dgk_7/2dgk_7/KCollider.cpp
Normal file
34
2dgk_7/2dgk_7/KCollider.cpp
Normal file
@ -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;
|
||||
}
|
||||
}
|
35
2dgk_7/2dgk_7/KCollider.h
Normal file
35
2dgk_7/2dgk_7/KCollider.h
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL_rect.h>
|
||||
|
||||
#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;
|
||||
};
|
||||
}
|
||||
|
||||
|
9
2dgk_7/2dgk_7/KExit.cpp
Normal file
9
2dgk_7/2dgk_7/KExit.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include "KExit.h"
|
||||
|
||||
namespace KapitanGame
|
||||
{
|
||||
const KCollider* KExit::GetCollider() const
|
||||
{
|
||||
return &Collider;
|
||||
}
|
||||
}
|
22
2dgk_7/2dgk_7/KExit.h
Normal file
22
2dgk_7/2dgk_7/KExit.h
Normal file
@ -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;
|
||||
};
|
||||
}
|
||||
|
63
2dgk_7/2dgk_7/KFont.cpp
Normal file
63
2dgk_7/2dgk_7/KFont.cpp
Normal file
@ -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;
|
||||
}
|
||||
}
|
36
2dgk_7/2dgk_7/KFont.h
Normal file
36
2dgk_7/2dgk_7/KFont.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include <SDL_ttf.h>
|
||||
#include <string>
|
||||
|
||||
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{};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,20 +1,29 @@
|
||||
#include "KGame.h"
|
||||
#include "SDL.h"
|
||||
#include <SDL_ttf.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#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<int>(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<int>(KPlayer::Player2) + 1; ++i)
|
||||
{
|
||||
if (max < Scores[i])
|
||||
{
|
||||
max = Scores[i];
|
||||
winner = static_cast<KPlayer>(i);
|
||||
}
|
||||
}
|
||||
ShowWinner = true;
|
||||
Textures.erase("Text_Winner");
|
||||
Textures.emplace("Text_Winner", Fonts["Roboto-Thin"].GetTextTexture(Utils::StringFormat("Player %d won!", static_cast<int>(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<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) };
|
||||
switch (line[i])
|
||||
{
|
||||
case '#':
|
||||
Objects.emplace_back(std::make_shared<KWall>(position, Textures["wall.bmp"]));
|
||||
break;
|
||||
case ' ':
|
||||
FreePositions.emplace_back(position);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
++y;
|
||||
}
|
||||
const auto mapHeight = static_cast<float>(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<KExit>(FreePositions.back(), Textures["exit.bmp"]));
|
||||
Exit = Objects.back();
|
||||
FreePositions.pop_back();
|
||||
|
||||
Pawns.emplace_back(std::make_shared<KCirclePawn>(FreePositions.back(), Textures["P1.bmp"], PlayerControllers[static_cast<int>(KPlayer::Player1)]));
|
||||
FreePositions.pop_back();
|
||||
PlayerControllers[static_cast<int>(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<KRectPawn>(FreePositions.back(), Textures["P2.bmp"], PlayerControllers[static_cast<int>(KPlayer::Player2)]));
|
||||
FreePositions.pop_back();
|
||||
PlayerControllers[static_cast<int>(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<int>(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<KPlayerController>(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<int>(line.length() * Constants::TILE_WIDTH))
|
||||
MapWidth = static_cast<int>(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<int>(KPlayer::Player1)], Pawns[static_cast<int>(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<int>(KPlayer::Player1)], Pawns[static_cast<int>(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<int>(KPlayer::Player1)], Pawns[static_cast<int>(KPlayer::Player2)], 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"].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<float>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,24 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
|
||||
#include "KTexture.h"
|
||||
#include <vector>
|
||||
#include <SDL_render.h>
|
||||
|
||||
#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<KCircle> Circles;
|
||||
std::vector<std::shared_ptr<KObject>> Objects;
|
||||
std::vector<std::shared_ptr<KPawn>> Pawns;
|
||||
std::vector<std::shared_ptr<KPlayerController>> PlayerControllers;
|
||||
std::unordered_map<std::string, KTexture> Textures;
|
||||
std::unordered_map<std::string, KFont> Fonts;
|
||||
std::vector<KVector2D> 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<KObject> 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<int>(KPlayer::Player2) + 1] = { 0,0 };
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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<Uint8>(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<KPlayerController>& 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<KPlayerController>& 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,13 +3,14 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#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<std::string, std::pair<Uint8, float>> KeyAxisBinds[static_cast<int>(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<KPlayerController>& controllerObject, KPlayerCommand command, KPlayer player);
|
||||
void BindAxis(const std::string& name, const std::shared_ptr<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);
|
||||
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
||||
|
23
2dgk_7/2dgk_7/KObject.cpp
Normal file
23
2dgk_7/2dgk_7/KObject.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "KObject.h"
|
||||
|
||||
#include "KCamera.h"
|
||||
|
||||
namespace KapitanGame
|
||||
{
|
||||
std::atomic<int> 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;
|
||||
}
|
||||
}
|
28
2dgk_7/2dgk_7/KObject.h
Normal file
28
2dgk_7/2dgk_7/KObject.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include <atomic>
|
||||
|
||||
#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<int> IdCounter;
|
||||
protected:
|
||||
KVector2D Position{ 0.f, 0.f };
|
||||
private:
|
||||
const KTexture& Texture;
|
||||
};
|
||||
}
|
||||
|
46
2dgk_7/2dgk_7/KPawn.cpp
Normal file
46
2dgk_7/2dgk_7/KPawn.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "KPawn.h"
|
||||
|
||||
#include <memory>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "Constants.h"
|
||||
#include "KPlayerController.h"
|
||||
#include "KExit.h"
|
||||
|
||||
namespace KapitanGame
|
||||
{
|
||||
void KPawn::CollisionDetectionStep(const std::vector<std::shared_ptr<KObject>>& 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;
|
||||
}
|
||||
}
|
||||
|
29
2dgk_7/2dgk_7/KPawn.h
Normal file
29
2dgk_7/2dgk_7/KPawn.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "KObject.h"
|
||||
|
||||
namespace KapitanGame
|
||||
{
|
||||
class KPlayerController;
|
||||
|
||||
class KPawn : public KObject
|
||||
{
|
||||
public:
|
||||
KPawn(const KVector2D& position, const KTexture& texture,
|
||||
const std::shared_ptr<KPlayerController>& playerController)
|
||||
: KObject(position, texture),
|
||||
PlayerController(playerController)
|
||||
{
|
||||
}
|
||||
void CollisionDetectionStep(const std::vector<std::shared_ptr<KObject>>& objects);
|
||||
void MovementStep(const float& timeStep);
|
||||
void CollisionDetectionWithMapStep(const SDL_FRect& map);
|
||||
void AddMovementInput(const KVector2D& input);
|
||||
private:
|
||||
const std::weak_ptr<KPlayerController> PlayerController;
|
||||
KVector2D Velocity{ 0.f, 0.f };
|
||||
};
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
namespace KapitanGame {
|
||||
enum class KPlayer : int {
|
||||
Player1,
|
||||
Player2
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<KPlayerController>
|
||||
{
|
||||
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);
|
||||
|
@ -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<const KCircle*>(other);
|
||||
if (circle != nullptr)
|
||||
return IsCollision(circle);
|
||||
|
||||
const auto rect = dynamic_cast<const KRect*>(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<const KCircle*>(other);
|
||||
if (circle != nullptr)
|
||||
return GetSeparationVector(circle);
|
||||
|
||||
const auto rect = dynamic_cast<const KRect*>(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;
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,35 @@
|
||||
#pragma once
|
||||
#include "KShape.h"
|
||||
#include <SDL_rect.h>
|
||||
|
||||
#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;
|
||||
};
|
||||
|
15
2dgk_7/2dgk_7/KRectPawn.cpp
Normal file
15
2dgk_7/2dgk_7/KRectPawn.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "KRectPawn.h"
|
||||
|
||||
namespace KapitanGame
|
||||
{
|
||||
KRectPawn::KRectPawn(const KVector2D& position, const KTexture& texture,
|
||||
const std::shared_ptr<KPlayerController>& playerController) : KPawn(position, texture, playerController),
|
||||
Collider(this, texture.GetWidth(), texture.GetHeight())
|
||||
{
|
||||
}
|
||||
|
||||
const KCollider* KRectPawn::GetCollider() const
|
||||
{
|
||||
return &Collider;
|
||||
}
|
||||
}
|
20
2dgk_7/2dgk_7/KRectPawn.h
Normal file
20
2dgk_7/2dgk_7/KRectPawn.h
Normal file
@ -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<KPlayerController>& playerController);
|
||||
|
||||
const KCollider* GetCollider() const override;
|
||||
private:
|
||||
KRect Collider;
|
||||
};
|
||||
|
||||
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
#include "KShape.h"
|
||||
#include "KCircle.h"
|
||||
#include "KRect.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "Constants.h"
|
||||
|
||||
namespace KapitanGame {
|
||||
std::atomic<int> 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<KShape>& 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<const KCircle&>(other);
|
||||
return IsCollision(circle);
|
||||
}
|
||||
catch (const std::bad_cast&) {
|
||||
}
|
||||
try {
|
||||
auto& rect = dynamic_cast<const KRect&>(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<const KCircle&>(other);
|
||||
return GetSeparationVector(circle);
|
||||
}
|
||||
catch (const std::bad_cast&) {
|
||||
}
|
||||
try {
|
||||
auto& circle = dynamic_cast<const KRect&>(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<int>(Position.X) - Texture.GetWidth() / 2, static_cast<int>(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;
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
#include <atomic>
|
||||
#include <SDL_render.h>
|
||||
#include <vector>
|
||||
|
||||
#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<KShape>& 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<int> 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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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<int>(static_cast<float>(x) * scale), static_cast<int>(static_cast<float>(y) * scale),
|
||||
static_cast<int>(static_cast<float>(Width) * scale), static_cast<int>(static_cast<float>(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<float>(Width) , static_cast<float>(Height)
|
||||
};
|
||||
|
||||
//Render to screen
|
||||
SDL_RenderCopyExF(renderer, Texture, nullptr, &renderQuad, degrees, nullptr, SDL_FLIP_NONE);
|
||||
}
|
||||
|
||||
int KTexture::GetWidth() const
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
#include <cfloat>
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
|
||||
namespace KapitanGame {
|
||||
|
9
2dgk_7/2dgk_7/KWall.cpp
Normal file
9
2dgk_7/2dgk_7/KWall.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include "KWall.h"
|
||||
|
||||
namespace KapitanGame
|
||||
{
|
||||
const KCollider* KWall::GetCollider() const
|
||||
{
|
||||
return &Collider;
|
||||
}
|
||||
}
|
22
2dgk_7/2dgk_7/KWall.h
Normal file
22
2dgk_7/2dgk_7/KWall.h
Normal file
@ -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;
|
||||
};
|
||||
}
|
||||
|
@ -1,16 +1,7 @@
|
||||
#include "Utils.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
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<double> dist(0.0, 1.0);
|
||||
return dist(rng);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,10 @@
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <random>
|
||||
#include <unordered_map>
|
||||
|
||||
#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 <class T>
|
||||
constexpr const T& Clamp01(const T& x)
|
||||
{
|
||||
return Clamp(x, 0.f, 1.f);
|
||||
}
|
||||
template <class T>
|
||||
constexpr const T& Clamp(const T& x, const T& min, const T& max)
|
||||
{
|
||||
return std::max(std::min(max, x), min);
|
||||
}
|
||||
template <class T>
|
||||
constexpr const T& Clamp01(const T& x)
|
||||
{
|
||||
return Clamp(x, 0.f, 1.f);
|
||||
}
|
||||
template <class T>
|
||||
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<std::string, KPlayer> 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<double> dist(0.0, 1.0);
|
||||
return dist(GetRandomEngine());
|
||||
}
|
||||
|
||||
template <typename C, C BeginVal, C EndVal>
|
||||
class Iterator {
|
||||
typedef std::underlying_type_t<C> ValT;
|
||||
int Value;
|
||||
public:
|
||||
explicit Iterator(const C& f) : Value(static_cast<ValT>(f)) {}
|
||||
Iterator() : Value(static_cast<ValT>(BeginVal)) {}
|
||||
Iterator operator++() {
|
||||
++Value;
|
||||
return *this;
|
||||
}
|
||||
C operator*() { return static_cast<C>(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<std::string, KPlayer> 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<KPlayer, KPlayer::Player1, KPlayer::Player2> KPlayerIterator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
202
2dgk_7/2dgk_7/assets/fonts/LICENSE.txt
Normal file
202
2dgk_7/2dgk_7/assets/fonts/LICENSE.txt
Normal file
@ -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.
|
BIN
2dgk_7/2dgk_7/assets/fonts/Roboto-Thin.ttf
(Stored with Git LFS)
Normal file
BIN
2dgk_7/2dgk_7/assets/fonts/Roboto-Thin.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -24,7 +24,7 @@
|
||||
# # # # # # #
|
||||
# # ### ##### ############# ### #####
|
||||
# # # # # # # # # #
|
||||
### # # ######### # # # # ### # ### #
|
||||
### # # ######### # # # # # # # ### #
|
||||
# # # # # # # # # #
|
||||
# ##### ### ### # # ### # ### ##### #
|
||||
# # # # # # # # # # # #
|
||||
|
BIN
2dgk_7/2dgk_7/assets/textures/P1.bmp
(Stored with Git LFS)
BIN
2dgk_7/2dgk_7/assets/textures/P1.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
2dgk_7/2dgk_7/assets/textures/P2.bmp
(Stored with Git LFS)
BIN
2dgk_7/2dgk_7/assets/textures/P2.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
2dgk_7/2dgk_7/assets/textures/arrow.bmp
(Stored with Git LFS)
Normal file
BIN
2dgk_7/2dgk_7/assets/textures/arrow.bmp
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -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)
|
@ -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": []
|
||||
|
@ -1,31 +0,0 @@
|
||||
/------------\/------------\
|
||||
|............||............|
|
||||
|./--\./---\.||./---\./--\.|
|
||||
|#| |.| |.||.| |.| |#|
|
||||
|.`--'.`---'.`'.`---'.`--'.|
|
||||
|..........................|
|
||||
|./--\./\./------\./\./--\.|
|
||||
|.`--'.||.`--\/--'.||.`--'.|
|
||||
|......||....||....||......|
|
||||
`----\.|`--\ || /--'|./----'
|
||||
|.|/--' `' `--\|.|
|
||||
|.|| ||.|
|
||||
|.|| /--==--\ ||.|
|
||||
-----'.`' | | `'.`-----
|
||||
. | | .
|
||||
-----\./\ | | /\./-----
|
||||
|.|| `------' ||.|
|
||||
|.|| ||.|
|
||||
|.|| /------\ ||.|
|
||||
/----'.`' `--\/--' `'.`----\
|
||||
|............||............|
|
||||
|./--\./---\.||./---\./--\.|
|
||||
|.`-\|.`---'.`'.`---'.|/-'.|
|
||||
|#..||....... .......||..#|
|
||||
`-\.||./\./------\./\.||./-'
|
||||
/-'.`'.||.`--\/--'.||.`'.`-\
|
||||
|......||....||....||......|
|
||||
|./----'`--\.||./--'`----\.|
|
||||
|.`--------'.`'.`--------'.|
|
||||
|..........................|
|
||||
`--------------------------'
|
14
2dgk_7/2dgk_7/resource.h
Normal file
14
2dgk_7/2dgk_7/resource.h
Normal file
@ -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
|
@ -4,6 +4,7 @@
|
||||
"version": "0.1.0",
|
||||
"dependencies": [
|
||||
"sdl2",
|
||||
"nlohmann-json"
|
||||
"nlohmann-json",
|
||||
"sdl2-ttf"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user