Merge branch 'master' of ssh://git.mlesniak.pl:44933/kapitan/2dkg
This commit is contained in:
commit
59ee167f93
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1,3 +1,4 @@
|
|||||||
*.bmp filter=lfs diff=lfs merge=lfs -text
|
*.bmp filter=lfs diff=lfs merge=lfs -text
|
||||||
*.ttf filter=lfs diff=lfs merge=lfs -text
|
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||||
*.pdn filter=lfs diff=lfs merge=lfs -text
|
*.pdn filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.psd filter=lfs diff=lfs merge=lfs -text
|
||||||
|
@ -4,4 +4,13 @@ Biblioteki: SDL2, SDL2_ttf, nlohmann-json
|
|||||||
|
|
||||||
Przetestowane pady: DualSense, DualShock 3 (ze sterownikiem/wrapperem XInputowym ScpToolkit), telefon Android (ze sterownikiem/wrapperem XInputowym HandyGamePad).
|
Przetestowane pady: DualSense, DualShock 3 (ze sterownikiem/wrapperem XInputowym ScpToolkit), telefon Android (ze sterownikiem/wrapperem XInputowym HandyGamePad).
|
||||||
|
|
||||||
|
Sterowanie (możliwa zmiana w config.json):
|
||||||
|
AD/lewa gałka pada - ruch poziomy
|
||||||
|
Spacja/A na padzie - skok
|
||||||
|
|
||||||
|
F1 - tryb deweloperski
|
||||||
|
F2 (w trybie deweloperskim) - wł./wył. kolizji
|
||||||
|
F3/F4 - (w trybie deweloperskim) - zwiększ/zmiejsz maksymalną wysokość skoku.
|
||||||
|
F5/F6 - (w trybie deweloperskim) - zwiększ/zmiejsz maksymalną odległość poziomą skoku
|
||||||
|
|
||||||
Uwaga: Do pobrania bibliotek projekt wykorzystuje vcpkg, menedżer bibliotek C++, w trybie Manifest. Należy go pobrać i skonfigurować zgodnie z instrukcją: https://github.com/microsoft/vcpkg#getting-started
|
Uwaga: Do pobrania bibliotek projekt wykorzystuje vcpkg, menedżer bibliotek C++, w trybie Manifest. Należy go pobrać i skonfigurować zgodnie z instrukcją: https://github.com/microsoft/vcpkg#getting-started
|
||||||
|
31
2dkg_zad5/2dgk_zad5.sln
Normal file
31
2dkg_zad5/2dgk_zad5.sln
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.31729.503
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{423520C9-0301-4445-99D4-078B2842C600}") = "2dgk_zad5", "2dgk_zad5\2dgk_zad5.vcxproj", "{2696A0B3-E7C4-4876-9DF4-E7D3EC6C06F8}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{2696A0B3-E7C4-4876-9DF4-E7D3EC6C06F8}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{2696A0B3-E7C4-4876-9DF4-E7D3EC6C06F8}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{2696A0B3-E7C4-4876-9DF4-E7D3EC6C06F8}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{2696A0B3-E7C4-4876-9DF4-E7D3EC6C06F8}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{2696A0B3-E7C4-4876-9DF4-E7D3EC6C06F8}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{2696A0B3-E7C4-4876-9DF4-E7D3EC6C06F8}.Release|x64.Build.0 = Release|x64
|
||||||
|
{2696A0B3-E7C4-4876-9DF4-E7D3EC6C06F8}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{2696A0B3-E7C4-4876-9DF4-E7D3EC6C06F8}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {2292BE73-514E-4923-9A1A-5A991B0DE0DB}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
101
2dkg_zad5/2dgk_zad5/2dgk_zad5.rc
Normal file
101
2dkg_zad5/2dgk_zad5/2dgk_zad5.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_zad5.exe"
|
||||||
|
VALUE "LegalCopyright", "Copyright (C) 2022 Michał Leśniak"
|
||||||
|
VALUE "OriginalFilename", "2dgk_zad5.exe"
|
||||||
|
VALUE "ProductName", "2DKG_ZAD5"
|
||||||
|
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
|
||||||
|
|
252
2dkg_zad5/2dgk_zad5/2dgk_zad5.vcxproj
Normal file
252
2dkg_zad5/2dgk_zad5/2dgk_zad5.vcxproj
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{2696a0b3-e7c4-4876-9df4-e7d3ec6c06f8}</ProjectGuid>
|
||||||
|
<RootNamespace>My2dgk_zad5</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="Vcpkg">
|
||||||
|
<VcpkgEnableManifest>true</VcpkgEnableManifest>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>vcpkg_installed\x86-windows\x86-windows\include\SDL2</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>vcpkg_installed\x86-windows\x86-windows\debug\lib\manual-link;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>SDL2maind.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>vcpkg_installed\x86-windows\x86-windows\include\SDL2</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>vcpkg_installed\x86-windows\x86-windows\lib\manual-link;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>SDL2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>vcpkg_installed\x64-windows\x64-windows\include\SDL2</AdditionalIncludeDirectories>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>vcpkg_installed\x64-windows\x64-windows\debug\lib\manual-link;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>SDL2maind.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>vcpkg_installed\x64-windows\x64-windows\include\SDL2</AdditionalIncludeDirectories>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>vcpkg_installed\x64-windows\x64-windows\lib\manual-link;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>SDL2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="KCamera.cpp" />
|
||||||
|
<ClCompile Include="KCircle.cpp" />
|
||||||
|
<ClCompile Include="KCirclePawn.cpp" />
|
||||||
|
<ClCompile Include="KDrawable.cpp" />
|
||||||
|
<ClCompile Include="KFont.cpp" />
|
||||||
|
<ClCompile Include="KGame.cpp" />
|
||||||
|
<ClCompile Include="KInput.cpp" />
|
||||||
|
<ClCompile Include="KSolid.cpp" />
|
||||||
|
<ClCompile Include="KPawn.cpp" />
|
||||||
|
<ClCompile Include="KPlayerController.cpp" />
|
||||||
|
<ClCompile Include="KRect.cpp" />
|
||||||
|
<ClCompile Include="KCollider.cpp" />
|
||||||
|
<ClCompile Include="KRectPawn.cpp" />
|
||||||
|
<ClCompile Include="KSettings.cpp" />
|
||||||
|
<ClCompile Include="KTexture.cpp" />
|
||||||
|
<ClCompile Include="KSolidTile.cpp" />
|
||||||
|
<ClCompile Include="Main.cpp" />
|
||||||
|
<ClCompile Include="Utils.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="config.json">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</None>
|
||||||
|
<None Include="vcpkg.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Constants.h" />
|
||||||
|
<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="KDrawable.h" />
|
||||||
|
<ClInclude Include="KFont.h" />
|
||||||
|
<ClInclude Include="KGame.h" />
|
||||||
|
<ClInclude Include="KInput.h" />
|
||||||
|
<ClInclude Include="KSolid.h" />
|
||||||
|
<ClInclude Include="KPawn.h" />
|
||||||
|
<ClInclude Include="KPlayer.h" />
|
||||||
|
<ClInclude Include="KPlayerController.h" />
|
||||||
|
<ClInclude Include="KRect.h" />
|
||||||
|
<ClInclude Include="KCollider.h" />
|
||||||
|
<ClInclude Include="KRectPawn.h" />
|
||||||
|
<ClInclude Include="KSettings.h" />
|
||||||
|
<ClInclude Include="KTexture.h" />
|
||||||
|
<ClInclude Include="KSolidTile.h" />
|
||||||
|
<ClInclude Include="Property.h" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
<ClInclude Include="Utils.h" />
|
||||||
|
<ClInclude Include="KVector2d.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="2dgk_zad5.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Text Include="assets\fonts\LICENSE.txt">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</Text>
|
||||||
|
<Text Include="assets\levels\level1.txt">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</Text>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Font Include="assets\fonts\Roboto-Thin.ttf">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</Font>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="assets\textures\arrow.bmp">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</Image>
|
||||||
|
<Image Include="assets\textures\exit.bmp">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</Image>
|
||||||
|
<Image Include="assets\textures\P1.bmp">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</Image>
|
||||||
|
<Image Include="assets\textures\P2.bmp">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</Image>
|
||||||
|
<Image Include="assets\textures\wall.bmp">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</Image>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
<ProjectExtensions>
|
||||||
|
<VisualStudio>
|
||||||
|
<UserProperties />
|
||||||
|
</VisualStudio>
|
||||||
|
</ProjectExtensions>
|
||||||
|
</Project>
|
183
2dkg_zad5/2dgk_zad5/2dgk_zad5.vcxproj.filters
Normal file
183
2dkg_zad5/2dgk_zad5/2dgk_zad5.vcxproj.filters
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="Main.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KTexture.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KGame.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KInput.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KCircle.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Utils.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KPlayerController.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KCollider.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KRect.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KSolid.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KPawn.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KSolidTile.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="KCamera.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KFont.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KSettings.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="KDrawable.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="vcpkg.json" />
|
||||||
|
<None Include="config.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Utils.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Constants.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KVector2d.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KTexture.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KGame.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="GamePad.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KInput.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KCircle.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KPlayerController.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KCollider.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KRect.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KActionBind.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Controllers.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KPlayer.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KSolid.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KPawn.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KSolidTile.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="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>
|
||||||
|
<ClInclude Include="KSettings.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Property.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="KDrawable.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="2dgk_zad5.rc">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="assets\textures\arrow.bmp">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="assets\textures\exit.bmp">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="assets\textures\P1.bmp">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="assets\textures\P2.bmp">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="assets\textures\wall.bmp">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</Image>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Font Include="assets\fonts\Roboto-Thin.ttf" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Text Include="assets\fonts\LICENSE.txt" />
|
||||||
|
<Text Include="assets\levels\level1.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
24
2dkg_zad5/2dgk_zad5/Constants.h
Normal file
24
2dkg_zad5/2dgk_zad5/Constants.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace KapitanGame::Constants
|
||||||
|
{
|
||||||
|
constexpr const char* WINDOW_TITLE = "2DGK - Zadanie 5 (Lab 14)";
|
||||||
|
//Analog joystick dead zone
|
||||||
|
constexpr int JOYSTICK_DEAD_ZONE = 8000;
|
||||||
|
//Screen dimension constants
|
||||||
|
constexpr int WINDOW_DEAD_ZONE = 100;
|
||||||
|
constexpr int SCREEN_WIDTH = 640;
|
||||||
|
constexpr int SCREEN_HEIGHT = 480;
|
||||||
|
constexpr float SCREEN_RATIO = static_cast<float>(SCREEN_WIDTH) / SCREEN_HEIGHT;
|
||||||
|
constexpr int TILE_WIDTH = 32;
|
||||||
|
constexpr int TILE_HEIGHT = 32;
|
||||||
|
constexpr int TILE_COUNT = 8;
|
||||||
|
constexpr int BG_LAYER_COUNT = 3;
|
||||||
|
constexpr int FG_LAYER_COUNT = 1;
|
||||||
|
constexpr float SPEED = 200.f;
|
||||||
|
constexpr float SMOOTH = 0.4f;
|
||||||
|
constexpr float JUMP_SPEED = 300.f;
|
||||||
|
constexpr float HORIZONTAL_DISTANCE_TO_MAX_JUMP_HEIGHT = TILE_WIDTH * 4.f;
|
||||||
|
constexpr float MAX_JUMP_HEIGHT = TILE_HEIGHT * 4.f;
|
||||||
|
constexpr float MAX_GRAVITY = 1000.f;
|
||||||
|
}
|
9
2dkg_zad5/2dgk_zad5/Controllers.h
Normal file
9
2dkg_zad5/2dgk_zad5/Controllers.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
namespace KapitanGame {
|
||||||
|
enum class Controllers : int {
|
||||||
|
Controller1,
|
||||||
|
Controller2,
|
||||||
|
Controller3,
|
||||||
|
Controller4
|
||||||
|
};
|
||||||
|
}
|
8
2dkg_zad5/2dgk_zad5/GamePad.h
Normal file
8
2dkg_zad5/2dgk_zad5/GamePad.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <SDL_gamecontroller.h>
|
||||||
|
namespace KapitanGame {
|
||||||
|
struct GamePad {
|
||||||
|
bool Buttons[SDL_CONTROLLER_BUTTON_MAX];
|
||||||
|
int Axis[SDL_CONTROLLER_AXIS_MAX];
|
||||||
|
};
|
||||||
|
}
|
31
2dkg_zad5/2dgk_zad5/KActionBind.h
Normal file
31
2dkg_zad5/2dgk_zad5/KActionBind.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "KPlayer.h"
|
||||||
|
#include "KPlayerController.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
;
|
||||||
|
enum class InputState : int {
|
||||||
|
Pressed,
|
||||||
|
Released,
|
||||||
|
Hold
|
||||||
|
};
|
||||||
|
struct KActionBind {
|
||||||
|
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;
|
||||||
|
std::weak_ptr<KPlayerController> ControllerObject;
|
||||||
|
KPlayerCommand Command;
|
||||||
|
KPlayer Player;
|
||||||
|
};
|
||||||
|
struct KAxisBind
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
std::weak_ptr<KPlayerController> ControllerObject;
|
||||||
|
KPlayerAxisCommand AxisCommand;
|
||||||
|
KPlayer Player;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
46
2dkg_zad5/2dgk_zad5/KCamera.cpp
Normal file
46
2dkg_zad5/2dgk_zad5/KCamera.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#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::vector<std::shared_ptr<KPawn>>& pawns, const SDL_FRect& map)
|
||||||
|
{
|
||||||
|
FocusPoint = { 0.f,0.f };
|
||||||
|
for(const auto& pawn : pawns) {
|
||||||
|
FocusPoint += pawn->GetPosition();
|
||||||
|
}
|
||||||
|
FocusPoint *= 1.f / static_cast<float>(pawns.size());
|
||||||
|
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 = std::min(Constants::SCREEN_HEIGHT * 1.f / map.h, Constants::SCREEN_WIDTH * 1.f / map.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SDL_FRect& KCamera::GetPlayArea() const
|
||||||
|
{
|
||||||
|
return PlayArea;
|
||||||
|
}
|
||||||
|
}
|
43
2dkg_zad5/2dgk_zad5/KCamera.h
Normal file
43
2dkg_zad5/2dgk_zad5/KCamera.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include <SDL_rect.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#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::vector<std::shared_ptr<KPawn>>& pawns, 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
108
2dkg_zad5/2dgk_zad5/KCircle.cpp
Normal file
108
2dkg_zad5/2dgk_zad5/KCircle.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include "KCircle.h"
|
||||||
|
|
||||||
|
#include <SDL_rect.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "KRect.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
|
||||||
|
bool KCircle::IsCollision(const KCircle* other) const {
|
||||||
|
return (GetParent()->GetPosition() - other->GetParent()->GetPosition()).Length() < Radius + other->Radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KCircle::IsCollision(const KCollider* other) const
|
||||||
|
{
|
||||||
|
if (const auto circle = dynamic_cast<const KCircle*>(other); circle != nullptr)
|
||||||
|
return IsCollision(circle);
|
||||||
|
|
||||||
|
|
||||||
|
if (const auto rect = dynamic_cast<const KRect*>(other); rect != nullptr)
|
||||||
|
return IsCollision(rect);
|
||||||
|
|
||||||
|
throw std::runtime_error("unsupported shape");
|
||||||
|
}
|
||||||
|
|
||||||
|
KVector2D KCircle::GetSeparationVector(const KCollider* other) const
|
||||||
|
{
|
||||||
|
if (const auto circle = dynamic_cast<const KCircle*>(other); circle != nullptr)
|
||||||
|
return GetSeparationVector(circle);
|
||||||
|
|
||||||
|
if (const auto rect = dynamic_cast<const KRect*>(other); rect != nullptr)
|
||||||
|
return GetSeparationVector(rect);
|
||||||
|
|
||||||
|
throw std::runtime_error("unsupported shape");
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (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 (GetParent()->GetPosition() - f) / (GetParent()->GetPosition() - f).Length() * (Radius - (GetParent()->GetPosition() - f).Length());
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
float KCircle::GetWidth() const
|
||||||
|
{
|
||||||
|
return Radius * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
float KCircle::GetHeight() const
|
||||||
|
{
|
||||||
|
return Radius * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
KCircle::KCircle(KSolid* parent, const float radius): KCollider(parent),
|
||||||
|
Radius(radius)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
float KCircle::GetRadius() const {
|
||||||
|
return Radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
32
2dkg_zad5/2dgk_zad5/KCircle.h
Normal file
32
2dkg_zad5/2dgk_zad5/KCircle.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL_rect.h>
|
||||||
|
|
||||||
|
#include "KCollider.h"
|
||||||
|
#include "KVector2d.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
class KRect;
|
||||||
|
|
||||||
|
class KCircle final : public KCollider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KCircle(KSolid* parent, float radius);
|
||||||
|
[[nodiscard]] float GetRadius() const;
|
||||||
|
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;
|
||||||
|
[[nodiscard]] KVector2D GetSeparationVector(const SDL_FRect& map) const override;
|
||||||
|
[[nodiscard]] float GetWidth() const override;
|
||||||
|
[[nodiscard]] float GetHeight() const override;
|
||||||
|
private:
|
||||||
|
float Radius{ 1.f };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
15
2dkg_zad5/2dgk_zad5/KCirclePawn.cpp
Normal file
15
2dkg_zad5/2dgk_zad5/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, KSettings* settings) : KPawn(position, texture, playerController, settings),
|
||||||
|
Collider(this, static_cast<float>(texture.GetWidth())/2.0f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const KCollider* KCirclePawn::GetCollider() const
|
||||||
|
{
|
||||||
|
return &Collider;
|
||||||
|
}
|
||||||
|
}
|
18
2dkg_zad5/2dgk_zad5/KCirclePawn.h
Normal file
18
2dkg_zad5/2dgk_zad5/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, KSettings* settings);
|
||||||
|
|
||||||
|
const KCollider* GetCollider() const override;
|
||||||
|
private:
|
||||||
|
KCircle Collider;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
34
2dkg_zad5/2dgk_zad5/KCollider.cpp
Normal file
34
2dkg_zad5/2dgk_zad5/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(KSolid* parent): Parent(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KSolid* KCollider::GetParent() const
|
||||||
|
{
|
||||||
|
return Parent;
|
||||||
|
}
|
||||||
|
}
|
35
2dkg_zad5/2dgk_zad5/KCollider.h
Normal file
35
2dkg_zad5/2dgk_zad5/KCollider.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL_rect.h>
|
||||||
|
|
||||||
|
#include "KSolid.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(KSolid* parent);
|
||||||
|
|
||||||
|
virtual ~KCollider() = default;
|
||||||
|
virtual bool IsCollision(const KCollider* other) const = 0;
|
||||||
|
virtual KVector2D GetSeparationVector(const KCollider* other) const = 0;
|
||||||
|
[[nodiscard]] virtual KVector2D GetSeparationVector(const SDL_FRect& map) const = 0;
|
||||||
|
[[nodiscard]] virtual float GetWidth() const = 0;
|
||||||
|
[[nodiscard]] virtual float GetHeight() const = 0;
|
||||||
|
[[nodiscard]] KSolid* GetParent() const;
|
||||||
|
private:
|
||||||
|
KSolid* Parent;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
26
2dkg_zad5/2dgk_zad5/KDrawable.cpp
Normal file
26
2dkg_zad5/2dgk_zad5/KDrawable.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "KDrawable.h"
|
||||||
|
|
||||||
|
#include "KCamera.h"
|
||||||
|
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
std::atomic<int> KDrawable::IdCounter{ 0 };
|
||||||
|
|
||||||
|
KDrawable::KDrawable(const KVector2D& position, const KTexture& texture, SDL_Rect* tileClip, const SDL_RendererFlip flip) :
|
||||||
|
Id(++IdCounter), Position(position), Texture(texture), TileClip(tileClip), Flip(flip)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void KDrawable::Render(SDL_Renderer* renderer, const KCamera& camera, const float parallaxFactor) const
|
||||||
|
{
|
||||||
|
if (TileClip != nullptr)
|
||||||
|
Texture.RenderEx(renderer, Position.X - Constants::TILE_WIDTH / 2.f - camera.GetViewport().x * parallaxFactor, Position.Y - Constants::TILE_HEIGHT / 2.f - camera.GetViewport().y, 0, TileClip, camera.GetScale(), Flip); // NOLINT(clang-diagnostic-implicit-int-float-conversion, bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions)
|
||||||
|
else
|
||||||
|
Texture.Render(renderer, Position.X - Texture.GetWidth() / 2.f - camera.GetViewport().x * parallaxFactor, Position.Y - Texture.GetHeight() / 2.f - camera.GetViewport().y, nullptr, camera.GetScale()); // NOLINT(clang-diagnostic-implicit-int-float-conversion, bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions)
|
||||||
|
}
|
||||||
|
|
||||||
|
KVector2D KDrawable::GetPosition() const
|
||||||
|
{
|
||||||
|
return Position;
|
||||||
|
}
|
||||||
|
}
|
28
2dkg_zad5/2dgk_zad5/KDrawable.h
Normal file
28
2dkg_zad5/2dgk_zad5/KDrawable.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
#include "KTexture.h"
|
||||||
|
#include "KVector2d.h"
|
||||||
|
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
class KCamera;
|
||||||
|
|
||||||
|
class KDrawable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KDrawable(const KVector2D& position, const KTexture& texture, SDL_Rect* tileClip, SDL_RendererFlip flip = SDL_FLIP_NONE);
|
||||||
|
virtual ~KDrawable() = default;
|
||||||
|
void Render(SDL_Renderer* renderer, const KCamera& camera, float parallaxFactor = 1.f) const;
|
||||||
|
[[nodiscard]] KVector2D GetPosition() const;
|
||||||
|
const int Id;
|
||||||
|
static std::atomic<int> IdCounter;
|
||||||
|
protected:
|
||||||
|
KVector2D Position{ 0.f, 0.f };
|
||||||
|
private:
|
||||||
|
const KTexture& Texture;
|
||||||
|
SDL_Rect* TileClip;
|
||||||
|
const SDL_RendererFlip Flip;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
132
2dkg_zad5/2dgk_zad5/KFont.cpp
Normal file
132
2dkg_zad5/2dgk_zad5/KFont.cpp
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#include "KFont.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
constexpr int spacing = 1;
|
||||||
|
int width, height = width = 0;
|
||||||
|
std::istringstream inputText;
|
||||||
|
inputText.str(text);
|
||||||
|
for(std::string line; std::getline(inputText, line);)
|
||||||
|
{
|
||||||
|
int w, h;
|
||||||
|
TTF_SizeText(Font, line.c_str(), &w, &h);
|
||||||
|
if (w > width) width = w;
|
||||||
|
height += w+spacing;
|
||||||
|
}
|
||||||
|
if (height > 0)
|
||||||
|
height -= spacing;
|
||||||
|
inputText.clear();
|
||||||
|
inputText.seekg(0);
|
||||||
|
SDL_Surface* textureSurface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 8, SDL_PIXELFORMAT_INDEX8);
|
||||||
|
{
|
||||||
|
const SDL_Palette* palette = textureSurface->format->palette;
|
||||||
|
palette->colors[0].r = 255 - textColor.r;
|
||||||
|
palette->colors[0].g = 255 - textColor.g;
|
||||||
|
palette->colors[0].b = 255 - textColor.b;
|
||||||
|
palette->colors[1].r = textColor.r;
|
||||||
|
palette->colors[1].g = textColor.g;
|
||||||
|
palette->colors[1].b = textColor.b;
|
||||||
|
palette->colors[1].a = textColor.a;
|
||||||
|
}
|
||||||
|
SDL_SetColorKey(textureSurface, SDL_TRUE, 0);
|
||||||
|
int y = 0;
|
||||||
|
for (std::string line; std::getline(inputText, line);) {
|
||||||
|
if (SDL_Surface* textSurface = TTF_RenderText_Solid(Font, line.c_str(), textColor); textSurface == nullptr)
|
||||||
|
{
|
||||||
|
printf("Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_Rect destRect{0, y, textSurface->w, textSurface->h};
|
||||||
|
SDL_BlitSurface(textSurface, nullptr, textureSurface, &destRect);
|
||||||
|
y += textSurface->h + spacing;
|
||||||
|
SDL_FreeSurface(textSurface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
texture.LoadFromSurface(textureSurface, renderer);
|
||||||
|
SDL_FreeSurface(textureSurface);
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
KTexture KFont::GetTextWithOutlineTexture(const std::string& text, const SDL_Color fgColor, const SDL_Color bgColor,
|
||||||
|
const int outlineSize, SDL_Renderer* renderer) const
|
||||||
|
{
|
||||||
|
KTexture texture;
|
||||||
|
const int originalOutlineSize = TTF_GetFontOutline(Font);
|
||||||
|
|
||||||
|
if (SDL_Surface* fgSurface = TTF_RenderText_Blended(Font, text.c_str(), fgColor); fgSurface == nullptr)
|
||||||
|
{
|
||||||
|
printf("Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TTF_SetFontOutline(Font, outlineSize);
|
||||||
|
SDL_Surface* bgSurface = TTF_RenderText_Blended(Font, text.c_str(), bgColor);
|
||||||
|
TTF_SetFontOutline(Font, originalOutlineSize);
|
||||||
|
if (bgSurface == nullptr)
|
||||||
|
{
|
||||||
|
printf("Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_Rect rect = { outlineSize, outlineSize, fgSurface->w, fgSurface->h };
|
||||||
|
|
||||||
|
/* blit text onto its outline */
|
||||||
|
SDL_SetSurfaceBlendMode(fgSurface, SDL_BLENDMODE_BLEND);
|
||||||
|
SDL_BlitSurface(fgSurface, nullptr, bgSurface, &rect);
|
||||||
|
texture.LoadFromSurface(bgSurface, renderer);
|
||||||
|
SDL_FreeSurface(bgSurface);
|
||||||
|
}
|
||||||
|
SDL_FreeSurface(fgSurface);
|
||||||
|
}
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
}
|
37
2dkg_zad5/2dgk_zad5/KFont.h
Normal file
37
2dkg_zad5/2dgk_zad5/KFont.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#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;
|
||||||
|
KTexture GetTextWithOutlineTexture(const std::string& text, SDL_Color fgColor, SDL_Color bgColor, int outlineSize, SDL_Renderer* renderer) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//The actual hardware font
|
||||||
|
TTF_Font* Font{};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
473
2dkg_zad5/2dgk_zad5/KGame.cpp
Normal file
473
2dkg_zad5/2dgk_zad5/KGame.cpp
Normal file
@ -0,0 +1,473 @@
|
|||||||
|
#include "KGame.h"
|
||||||
|
#include "SDL.h"
|
||||||
|
#include <SDL_ttf.h>
|
||||||
|
#include <SDL_image.h>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Constants.h"
|
||||||
|
#include "KCamera.h"
|
||||||
|
#include "KCirclePawn.h"
|
||||||
|
#include "KTexture.h"
|
||||||
|
#include "KTile.h"
|
||||||
|
#include "KVector2d.h"
|
||||||
|
#include "KSolidTile.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
KGame::KGame() : Time(0), PreviousTime(0), Map(), Settings(Constants::MAX_JUMP_HEIGHT, Constants::HORIZONTAL_DISTANCE_TO_MAX_JUMP_HEIGHT)
|
||||||
|
{
|
||||||
|
//Initialize SDL
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error(Utils::StringFormat("SDL could not initialize! SDL_Error: %s", SDL_GetError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
////Set texture filtering to linear
|
||||||
|
//if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
|
||||||
|
//{
|
||||||
|
// printf("Warning: Linear texture filtering not enabled!\n");
|
||||||
|
//}
|
||||||
|
|
||||||
|
Input.Init();
|
||||||
|
|
||||||
|
if (TTF_Init() < 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error(Utils::StringFormat("SDL_TTF could not initialize! TTF_Error: %s", TTF_GetError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IMG_Init(IMG_INIT_PNG) < 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error(Utils::StringFormat("SDL_IMG could not initialize! IMG_Error: %s", IMG_GetError()));
|
||||||
|
}
|
||||||
|
//Create window
|
||||||
|
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()));
|
||||||
|
}
|
||||||
|
//Create renderer for window
|
||||||
|
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()));
|
||||||
|
}
|
||||||
|
//Initialize renderer color
|
||||||
|
SDL_SetRenderDrawColor(Renderer, 0, 0xFF, 0, 0xFF);
|
||||||
|
SDL_Log("KGame initialized...");
|
||||||
|
}
|
||||||
|
|
||||||
|
KGame::~KGame() {
|
||||||
|
//Free loaded images
|
||||||
|
Textures.clear();
|
||||||
|
for (auto& layer : BackgroundLayers)
|
||||||
|
{
|
||||||
|
layer.clear();
|
||||||
|
}
|
||||||
|
Objects.clear();
|
||||||
|
for (auto& layer : ForegroundLayers)
|
||||||
|
{
|
||||||
|
layer.clear();
|
||||||
|
}
|
||||||
|
Pawns.clear();
|
||||||
|
PlayerControllers.clear();
|
||||||
|
Fonts.clear();
|
||||||
|
TTF_Quit();
|
||||||
|
IMG_Quit();
|
||||||
|
Input.Free();
|
||||||
|
|
||||||
|
//Destroy window
|
||||||
|
SDL_DestroyRenderer(Renderer);
|
||||||
|
SDL_DestroyWindow(Window);
|
||||||
|
Window = nullptr;
|
||||||
|
Renderer = nullptr;
|
||||||
|
|
||||||
|
//Quit SDL subsystems
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KGame::LoadLevel()
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
Objects.clear();
|
||||||
|
Pawns.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;
|
||||||
|
int layer = 0;
|
||||||
|
float mapWidth = 0, mapHeight = 0;
|
||||||
|
KVector2D startPosition{ 0.f, 0.f };
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(levelFile, line)) {
|
||||||
|
if (line.length() > 0 && line[0] == '#')
|
||||||
|
{
|
||||||
|
std::string mapSizes = line.substr(1);
|
||||||
|
const auto delimPos = mapSizes.find(',');
|
||||||
|
mapWidth = std::stof(mapSizes.substr(0, delimPos)) * Constants::TILE_WIDTH;
|
||||||
|
mapHeight = std::stof(mapSizes.substr(delimPos + 1)) * Constants::TILE_HEIGHT;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.length() > 0 && line[0] == '!')
|
||||||
|
{
|
||||||
|
layer = std::stoi(line.substr(1));
|
||||||
|
y = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (auto i = 0ull; i < line.length(); ++i) {
|
||||||
|
KVector2D position{
|
||||||
|
static_cast<float>(i * Constants::TILE_WIDTH + Constants::TILE_WIDTH / 2), // NOLINT(bugprone-integer-division)
|
||||||
|
static_cast<float>(y * Constants::TILE_HEIGHT + Constants::TILE_HEIGHT / 2) // NOLINT(bugprone-integer-division)
|
||||||
|
};
|
||||||
|
if (layer == 3) {
|
||||||
|
switch (line[i])
|
||||||
|
{
|
||||||
|
case 'P':
|
||||||
|
startPosition = position;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
auto clip = -1;
|
||||||
|
SDL_RendererFlip flip = SDL_FLIP_NONE;
|
||||||
|
if (std::isdigit(line[i]))
|
||||||
|
{
|
||||||
|
clip = line[i] - '0';
|
||||||
|
}
|
||||||
|
else if (line[i] >= 'a' && line[i] <= 'z')
|
||||||
|
{
|
||||||
|
clip = line[i] - 'a';
|
||||||
|
flip = SDL_FLIP_HORIZONTAL;
|
||||||
|
}
|
||||||
|
if (clip >= 0)
|
||||||
|
Objects.emplace(std::make_pair(static_cast<int>(i), y), std::make_shared<KSolidTile>(position, Textures["tiles"], &TileClips[clip], flip));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (layer < 3)
|
||||||
|
{
|
||||||
|
auto clip = -1;
|
||||||
|
SDL_RendererFlip flip = SDL_FLIP_NONE;
|
||||||
|
if (std::isdigit(line[i]))
|
||||||
|
{
|
||||||
|
clip = line[i] - '0';
|
||||||
|
}
|
||||||
|
else if (line[i] >= 'a' && line[i] <= 'z')
|
||||||
|
{
|
||||||
|
clip = line[i] - 'a';
|
||||||
|
flip = SDL_FLIP_HORIZONTAL;
|
||||||
|
}
|
||||||
|
if (clip >= 0)
|
||||||
|
BackgroundLayers[layer].emplace(std::make_pair(static_cast<int>(i), y), std::make_shared<KDrawable>(position, Textures["tiles"], &TileClips[clip], flip));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto index = layer - 4;
|
||||||
|
auto clip = -1;
|
||||||
|
SDL_RendererFlip flip = SDL_FLIP_NONE;
|
||||||
|
if (std::isdigit(line[i]))
|
||||||
|
{
|
||||||
|
clip = line[i] - '0';
|
||||||
|
}
|
||||||
|
else if (line[i] >= 'a' && line[i] <= 'z')
|
||||||
|
{
|
||||||
|
clip = line[i] - 'a';
|
||||||
|
flip = SDL_FLIP_HORIZONTAL;
|
||||||
|
}
|
||||||
|
if (clip >= 0)
|
||||||
|
ForegroundLayers[index].emplace(std::make_pair(static_cast<int>(i), y), std::make_shared<KDrawable>(position, Textures["tiles"], &TileClips[clip], flip));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++y;
|
||||||
|
}
|
||||||
|
|
||||||
|
levelFile.close();
|
||||||
|
Map = { 0,0,mapWidth,mapHeight };
|
||||||
|
Pawns.emplace_back(std::make_shared<KCirclePawn>(startPosition, Textures["P1.bmp"], PlayerControllers[static_cast<int>(KPlayer::Player1)], &Settings));
|
||||||
|
PlayerControllers[static_cast<int>(KPlayer::Player1)]->Possess(Pawns.back().get());
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KGame::LoadMedia()
|
||||||
|
{
|
||||||
|
//Loading success flag
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
for (auto player : Utils::KPlayerIterator())
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
PlayerControllers.back()->SetupInputBindings(Input);
|
||||||
|
}
|
||||||
|
Textures.emplace("tiles", KTexture());
|
||||||
|
if (!Textures["tiles"].LoadFromFile("assets/textures/maptiles.png", Renderer))
|
||||||
|
{
|
||||||
|
printf("Failed to load map tiles texture image!\n");
|
||||||
|
Textures.erase("tiles");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Constants::TILE_COUNT; ++i)
|
||||||
|
{
|
||||||
|
TileClips[i].x = (i % 4) * Constants::TILE_WIDTH;
|
||||||
|
TileClips[i].y = (i / 4) * Constants::TILE_HEIGHT;
|
||||||
|
TileClips[i].w = Constants::TILE_WIDTH;
|
||||||
|
TileClips[i].h = Constants::TILE_HEIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Fonts.emplace("PressStart2P-Regular", KFont());
|
||||||
|
if (!Fonts["PressStart2P-Regular"].LoadFromFile("assets/fonts/PressStart2P-Regular.ttf", 8))
|
||||||
|
{
|
||||||
|
printf("Failed to load PressStart2P-Regular font!\n");
|
||||||
|
Fonts.erase("PressStart2P-Regular");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::ifstream configFile("config.json"); configFile.fail()) {
|
||||||
|
printf("Failed to load config.json!\n");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nlohmann::json configJson;
|
||||||
|
configFile >> configJson;
|
||||||
|
configFile.close();
|
||||||
|
for (auto& player : configJson["Input"].items()) {
|
||||||
|
const auto playerEnum = Utils::GetPlayerFromString(player.key());
|
||||||
|
for (auto& axisMapping : player.value()["AxisMappings"]) {
|
||||||
|
Input.AddAxisMapping(axisMapping["AxisName"].get<std::string>(), axisMapping["Scale"].get<float>(), axisMapping["Key"].get<std::string>(), playerEnum);
|
||||||
|
}
|
||||||
|
for (auto& actionMapping : player.value()["ActionMappings"]) {
|
||||||
|
Input.AddActionMapping(actionMapping["ActionName"].get<std::string>(), actionMapping["Key"].get<std::string>(), playerEnum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!LoadLevel())
|
||||||
|
success = false;
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
int KGame::Run(int argc, char* args[])
|
||||||
|
{
|
||||||
|
//Load media
|
||||||
|
if (!LoadMedia())
|
||||||
|
{
|
||||||
|
printf("Failed to load media!\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Main loop flag
|
||||||
|
bool quit = false;
|
||||||
|
|
||||||
|
//Event handler
|
||||||
|
SDL_Event e;
|
||||||
|
|
||||||
|
KCamera camera(Map);
|
||||||
|
KCamera debugCamera(Map);
|
||||||
|
debugCamera.SetDebug(Map);
|
||||||
|
|
||||||
|
char devMode = 0;
|
||||||
|
|
||||||
|
camera.Update(Pawns, Map);
|
||||||
|
|
||||||
|
SettingsTextTextureDirty = true;
|
||||||
|
|
||||||
|
Time = PreviousTime = SDL_GetTicks();
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
//While application is running
|
||||||
|
while (!quit)
|
||||||
|
{
|
||||||
|
PreviousTime = Time;
|
||||||
|
Time = SDL_GetTicks();
|
||||||
|
float deltaTime = static_cast<float>(Time - PreviousTime) * 0.001f;
|
||||||
|
|
||||||
|
Input.HandleInputPreEvents();
|
||||||
|
|
||||||
|
//Handle events on queue
|
||||||
|
while (SDL_PollEvent(&e))
|
||||||
|
{
|
||||||
|
//User requests quit
|
||||||
|
if (e.type == SDL_QUIT)
|
||||||
|
{
|
||||||
|
quit = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Input.HandleEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Input.HandleInputPostEvents(Playing);
|
||||||
|
|
||||||
|
if (Input.IsKeyboardButtonPressed(SDL_SCANCODE_F1))
|
||||||
|
{
|
||||||
|
if (++devMode > 2) devMode = 0;
|
||||||
|
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Changed devMode to %d\n", devMode);
|
||||||
|
}
|
||||||
|
if (devMode >= 1) {
|
||||||
|
if (Input.IsKeyboardButtonPressed(SDL_SCANCODE_F2))
|
||||||
|
{
|
||||||
|
Settings.CollisionEnabled = !Settings.CollisionEnabled;
|
||||||
|
}
|
||||||
|
if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_F3))
|
||||||
|
{
|
||||||
|
Settings.MaxJumpHeight -= 0.1f;
|
||||||
|
SettingsTextTextureDirty = true;
|
||||||
|
}
|
||||||
|
if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_F4))
|
||||||
|
{
|
||||||
|
Settings.MaxJumpHeight += 0.1f;
|
||||||
|
SettingsTextTextureDirty = true;
|
||||||
|
}
|
||||||
|
if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_F5))
|
||||||
|
{
|
||||||
|
Settings.HorizontalDistanceToMaxJumpHeight -= 0.1f;
|
||||||
|
SettingsTextTextureDirty = true;
|
||||||
|
}
|
||||||
|
if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_F6))
|
||||||
|
{
|
||||||
|
Settings.HorizontalDistanceToMaxJumpHeight += 0.1f;
|
||||||
|
SettingsTextTextureDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Playing) {
|
||||||
|
for (const auto& pc : PlayerControllers) {
|
||||||
|
pc->Update(deltaTime);
|
||||||
|
}
|
||||||
|
for (const auto& pawn : Pawns) {
|
||||||
|
if (!Playing) break;
|
||||||
|
pawn->MovementStep(deltaTime);
|
||||||
|
}
|
||||||
|
if (Settings.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());
|
||||||
|
}
|
||||||
|
|
||||||
|
camera.Update(Pawns, Map);
|
||||||
|
|
||||||
|
}
|
||||||
|
Textures.insert_or_assign("Text_Settings", Fonts["PressStart2P-Regular"].GetTextTexture(
|
||||||
|
Utils::StringFormat(
|
||||||
|
"Developer Mode (F1): %d\n"
|
||||||
|
"Collision Enabled (F2): %s\n"
|
||||||
|
"Max Jump Height (F3/F4): %f\n"
|
||||||
|
"Horizontal Distance to Max Jump Height (F5/F6): %f\n"
|
||||||
|
"Initial Jump Velocity: %f\n"
|
||||||
|
"Gravity: %f\n"
|
||||||
|
"Player Position X: %f\n"
|
||||||
|
"Player Position Y: %f",
|
||||||
|
static_cast<int>(devMode),
|
||||||
|
Settings.CollisionEnabled ? "True" : "False",
|
||||||
|
static_cast<float>(Settings.MaxJumpHeight),
|
||||||
|
static_cast<float>(Settings.HorizontalDistanceToMaxJumpHeight),
|
||||||
|
static_cast<float>(Settings.JumpInitialVelocity),
|
||||||
|
static_cast<float>(Settings.Gravity),
|
||||||
|
Pawns.back()->GetPosition().X,
|
||||||
|
Pawns.back()->GetPosition().Y), { 0, 0, 0, 0xFF },
|
||||||
|
Renderer));
|
||||||
|
|
||||||
|
|
||||||
|
if (!Playing)
|
||||||
|
{
|
||||||
|
if (Time > RestartTick)
|
||||||
|
{
|
||||||
|
LoadLevel();
|
||||||
|
debugCamera.SetDebug(Map);
|
||||||
|
camera.Update(Pawns, Map);
|
||||||
|
Playing = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Clear screen
|
||||||
|
//SDL_SetRenderDrawColor(Renderer, 66, 135, 245, 0xFF);
|
||||||
|
SDL_SetRenderDrawColor(Renderer, 21, 36, 143, 0xFF);
|
||||||
|
SDL_RenderClear(Renderer);
|
||||||
|
|
||||||
|
const auto& cameraInUse = devMode >= 2 ? debugCamera : camera;
|
||||||
|
|
||||||
|
|
||||||
|
if (Playing) {
|
||||||
|
for (int i = 0; i < Constants::BG_LAYER_COUNT; ++i)
|
||||||
|
{
|
||||||
|
for (const auto& [tile, drawable] : BackgroundLayers[i])
|
||||||
|
drawable->Render(Renderer, cameraInUse, 1.f - (Constants::BG_LAYER_COUNT - i - 1) * .25f); //TODO: Add controls for changing parallax factor
|
||||||
|
}
|
||||||
|
for (const auto& [tile, obj] : Objects)
|
||||||
|
obj->Render(Renderer, cameraInUse);
|
||||||
|
for (const auto& pawn : Pawns) {
|
||||||
|
pawn->Render(Renderer, cameraInUse);
|
||||||
|
}
|
||||||
|
for (auto& layer : ForegroundLayers)
|
||||||
|
{
|
||||||
|
for (const auto& [tile, drawable] : layer)
|
||||||
|
drawable->Render(Renderer, cameraInUse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devMode >= 1) {
|
||||||
|
Textures["Text_Settings"].Render(Renderer, 10.f, 25.f);
|
||||||
|
}
|
||||||
|
if (devMode >= 2)
|
||||||
|
{
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
59
2dkg_zad5/2dgk_zad5/KGame.h
Normal file
59
2dkg_zad5/2dgk_zad5/KGame.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "KTexture.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <SDL_render.h>
|
||||||
|
|
||||||
|
#include "Constants.h"
|
||||||
|
#include "KFont.h"
|
||||||
|
#include "KInput.h"
|
||||||
|
#include "KSettings.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
class KExit;
|
||||||
|
class KSolid;
|
||||||
|
|
||||||
|
class KGame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KGame();
|
||||||
|
~KGame();
|
||||||
|
KGame(const KGame& other) = delete;
|
||||||
|
KGame(KGame&& other) noexcept = delete;
|
||||||
|
KGame& operator=(const KGame& other) = delete;
|
||||||
|
KGame& operator=(KGame&& other) noexcept = delete;
|
||||||
|
int Run(int argc, char* args[]);
|
||||||
|
private:
|
||||||
|
SDL_Window* Window = nullptr;
|
||||||
|
|
||||||
|
SDL_Renderer* Renderer = nullptr;
|
||||||
|
|
||||||
|
std::unordered_map<std::pair<int, int>, std::shared_ptr<KDrawable>, Utils::PairHash> BackgroundLayers[Constants::BG_LAYER_COUNT];
|
||||||
|
std::unordered_map<std::pair<int, int>, std::shared_ptr<KDrawable>, Utils::PairHash> ForegroundLayers[Constants::FG_LAYER_COUNT];
|
||||||
|
std::unordered_map<std::pair<int, int>, std::shared_ptr<KSolid>, Utils::PairHash> 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;
|
||||||
|
SDL_Rect TileClips[Constants::TILE_COUNT];
|
||||||
|
KInput Input;
|
||||||
|
uint32_t Time;
|
||||||
|
uint32_t PreviousTime;
|
||||||
|
SDL_FRect Map;
|
||||||
|
std::weak_ptr<KSolid> Exit;
|
||||||
|
KSettings Settings;
|
||||||
|
bool SettingsTextTextureDirty = true;
|
||||||
|
|
||||||
|
bool LoadLevel();
|
||||||
|
bool LoadMedia();
|
||||||
|
|
||||||
|
int LvlCounter = 1;
|
||||||
|
bool Playing = true;
|
||||||
|
uint32_t RestartTick = -1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
307
2dkg_zad5/2dgk_zad5/KInput.cpp
Normal file
307
2dkg_zad5/2dgk_zad5/KInput.cpp
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
#include "KInput.h"
|
||||||
|
#include "Constants.h"
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
KInput::KInput() : GamePadsCount(0), Initialized(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void KInput::Init() {
|
||||||
|
if (Initialized) return;
|
||||||
|
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) != 1)
|
||||||
|
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||||
|
|
||||||
|
const int nJoysticks = SDL_NumJoysticks();
|
||||||
|
GamePadsCount = 0;
|
||||||
|
|
||||||
|
// Count how many controllers there are
|
||||||
|
for (int i = 0; i < nJoysticks; i++)
|
||||||
|
if (SDL_IsGameController(i))
|
||||||
|
GamePadsCount++;
|
||||||
|
|
||||||
|
// If we have some controllers attached
|
||||||
|
if (GamePadsCount > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < GamePadsCount; i++)
|
||||||
|
{
|
||||||
|
// Open the controller and add it to our list
|
||||||
|
SDL_GameController* pad = SDL_GameControllerOpen(i);
|
||||||
|
if (SDL_GameControllerGetAttached(pad) == 1)
|
||||||
|
ConnectedControllers.push_back(pad);
|
||||||
|
else
|
||||||
|
printf("SDL_GetError() = %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
SDL_GameControllerEventState(SDL_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vectors are empty to begin with, this sets their size
|
||||||
|
ControllerInputs.resize(GamePadsCount);
|
||||||
|
LastControllerInputs.resize(GamePadsCount);
|
||||||
|
|
||||||
|
// Set the status of the controllers to "nothing is happening"
|
||||||
|
for (int i = 0; i < GamePadsCount; i++) {
|
||||||
|
for (int a = 0; a < SDL_CONTROLLER_AXIS_MAX; a++) {
|
||||||
|
ControllerInputs[i].Axis[a] = 0;
|
||||||
|
LastControllerInputs[i].Axis[a] = 0;
|
||||||
|
}
|
||||||
|
for (int b = 0; b < SDL_CONTROLLER_BUTTON_MAX; b++) {
|
||||||
|
ControllerInputs[i].Buttons[b] = false;
|
||||||
|
LastControllerInputs[i].Buttons[b] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KInput::Free() {
|
||||||
|
for (const auto& pad : ConnectedControllers) {
|
||||||
|
SDL_GameControllerClose(pad);
|
||||||
|
}
|
||||||
|
ConnectedControllers.clear();
|
||||||
|
Actions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KInput::HandleInputPreEvents() {
|
||||||
|
for (int i = 0; i < GamePadsCount; i++) {
|
||||||
|
for (int a = 0; a < SDL_CONTROLLER_AXIS_MAX; a++) {
|
||||||
|
LastControllerInputs[i].Axis[a] = ControllerInputs[i].Axis[a];
|
||||||
|
}
|
||||||
|
for (int b = 0; b < SDL_CONTROLLER_BUTTON_MAX; b++) {
|
||||||
|
LastControllerInputs[i].Buttons[b] = ControllerInputs[i].Buttons[b];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LastKeyboardInputs = KeyboardInputs;
|
||||||
|
}
|
||||||
|
void KInput::HandleInputPostEvents(const bool processInput) {
|
||||||
|
int size = 0;
|
||||||
|
const Uint8* currentKeyStates = SDL_GetKeyboardState(&size);
|
||||||
|
KeyboardInputs = std::vector<Uint8>(currentKeyStates, currentKeyStates + size);
|
||||||
|
if (processInput) {
|
||||||
|
ProcessActions();
|
||||||
|
ProcessAxes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void KInput::HandleEvent(const SDL_Event& event) {
|
||||||
|
switch (event.type) {
|
||||||
|
// This happens when a device is added
|
||||||
|
// A future improvement is to cope with new controllers being plugged in
|
||||||
|
// when the game is running
|
||||||
|
case SDL_CONTROLLERDEVICEADDED:
|
||||||
|
printf("DEVICEADDED cdevice.which = %d\n", event.cdevice.which);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// If a controller button is pressed
|
||||||
|
case SDL_CONTROLLERBUTTONDOWN:
|
||||||
|
// Cycle through the controllers
|
||||||
|
for (int i = 0; i < GamePadsCount; i++) {
|
||||||
|
// Looking for the button that was pressed
|
||||||
|
if (event.cbutton.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(ConnectedControllers[i]))) {
|
||||||
|
// So the relevant state can be updated
|
||||||
|
ControllerInputs[i].Buttons[event.cbutton.button] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Do the same for releasing a button
|
||||||
|
case SDL_CONTROLLERBUTTONUP:
|
||||||
|
for (int i = 0; i < GamePadsCount; i++) {
|
||||||
|
if (event.cbutton.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(ConnectedControllers[i]))) {
|
||||||
|
ControllerInputs[i].Buttons[event.cbutton.button] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// And something similar for axis motion
|
||||||
|
case SDL_CONTROLLERAXISMOTION:
|
||||||
|
for (int i = 0; i < GamePadsCount; i++) {
|
||||||
|
if (event.cbutton.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(ConnectedControllers[i]))) {
|
||||||
|
ControllerInputs[i].Axis[event.caxis.axis] = event.caxis.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KInput::BindAction(const std::string& name, InputState expectedInputState,
|
||||||
|
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, const std::shared_ptr<KPlayerController>& controllerObject, KPlayerAxisCommand command, KPlayer player)
|
||||||
|
{
|
||||||
|
Axes.emplace_back(name, controllerObject, command, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KInput::CheckAction(const std::string& name, const InputState expectedInputState, KPlayer player) {
|
||||||
|
const auto keyBindRange = KeyBinds[static_cast<int>(player)].equal_range(name);
|
||||||
|
for (auto keyBind = keyBindRange.first; keyBind != keyBindRange.second; ++keyBind) {
|
||||||
|
switch (expectedInputState) {
|
||||||
|
case InputState::Pressed:
|
||||||
|
if (IsKeyboardButtonPressed(keyBind->second)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case InputState::Released:
|
||||||
|
if (IsKeyboardButtonReleased(keyBind->second)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case InputState::Hold:
|
||||||
|
if (IsKeyboardButtonHeld(keyBind->second)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto buttonBindRange = ButtonBinds[static_cast<int>(player)].equal_range(name);
|
||||||
|
for (auto buttonBind = buttonBindRange.first; buttonBind != buttonBindRange.second; ++buttonBind) {
|
||||||
|
switch (expectedInputState) {
|
||||||
|
case InputState::Pressed:
|
||||||
|
if (IsControllerButtonPressed(buttonBind->second.first, buttonBind->second.second)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case InputState::Released:
|
||||||
|
if (IsControllerButtonReleased(buttonBind->second.first, buttonBind->second.second)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case InputState::Hold:
|
||||||
|
if (IsControllerButtonHeld(buttonBind->second.first, buttonBind->second.second)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KInput::ProcessActions() {
|
||||||
|
for (auto& action : Actions) {
|
||||||
|
if (CheckAction(action.Name, action.ExpectedInputState, action.Player)) {
|
||||||
|
if (auto obj = action.ControllerObject.lock())
|
||||||
|
std::invoke(action.Command, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KInput::ProcessAxes()
|
||||||
|
{
|
||||||
|
for (auto& axis : Axes) {
|
||||||
|
if (auto obj = axis.ControllerObject.lock())
|
||||||
|
std::invoke(axis.AxisCommand, obj, GetAxisValue(axis.Name, axis.Player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KInput::AddAxisMapping(const std::string& name, const float& scale, const std::string& key, const KPlayer& player)
|
||||||
|
{
|
||||||
|
if (key.rfind("Gamepad", 0) == 0) {
|
||||||
|
const auto delimiterPosition = key.find('_', 7);
|
||||||
|
const auto controllerIndex = static_cast<Controllers>(std::stoi(key.substr(7, delimiterPosition)));
|
||||||
|
auto axis = key.substr(delimiterPosition + 1);
|
||||||
|
std::for_each(axis.begin(), axis.end(), [](char& c) {
|
||||||
|
c = ::tolower(c);
|
||||||
|
});
|
||||||
|
ControllerAxisBinds[static_cast<int>(player)].emplace(name, KControllerAxisMapping(controllerIndex, SDL_GameControllerGetAxisFromString(axis.c_str()), scale));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_Scancode scanCode = SDL_GetScancodeFromName(key.c_str());
|
||||||
|
if (scanCode != SDL_SCANCODE_UNKNOWN) {
|
||||||
|
KeyAxisBinds[static_cast<int>(player)].emplace(name, std::make_pair(scanCode, scale));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KInput::AddActionMapping(const std::string& name, const std::string& key, const KPlayer& player)
|
||||||
|
{
|
||||||
|
if (key.rfind("Gamepad", 0) == 0) {
|
||||||
|
const auto delimiterPosition = key.find('_', 7);
|
||||||
|
const auto controllerIndex = static_cast<Controllers>(std::stoi(key.substr(7, delimiterPosition)));
|
||||||
|
auto button = key.substr(delimiterPosition + 1);
|
||||||
|
std::for_each(button.begin(), button.end(), [](char& c) {
|
||||||
|
c = ::tolower(c);
|
||||||
|
});
|
||||||
|
ButtonBinds[static_cast<int>(player)].emplace(name, std::make_pair(controllerIndex, SDL_GameControllerGetButtonFromString(button.c_str())));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_Scancode scanCode = SDL_GetScancodeFromName(key.c_str());
|
||||||
|
if (scanCode != SDL_SCANCODE_UNKNOWN) {
|
||||||
|
KeyBinds[static_cast<int>(player)].emplace(name, scanCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KInput::IsControllerButtonPressed(const Controllers controllerId, const SDL_GameControllerButton button) const
|
||||||
|
{
|
||||||
|
if (controllerId < Controllers::Controller1 || controllerId > static_cast<Controllers>(GamePadsCount - 1)) return false;
|
||||||
|
|
||||||
|
return ControllerInputs[static_cast<int>(controllerId)].Buttons[button] && !LastControllerInputs[static_cast<int>(controllerId)].Buttons[button];
|
||||||
|
}
|
||||||
|
bool KInput::IsControllerButtonReleased(const Controllers controllerId, const SDL_GameControllerButton button) const
|
||||||
|
{
|
||||||
|
if (controllerId < Controllers::Controller1 || controllerId > static_cast<Controllers>(GamePadsCount - 1)) return false;
|
||||||
|
|
||||||
|
return !ControllerInputs[static_cast<int>(controllerId)].Buttons[button] && LastControllerInputs[static_cast<int>(controllerId)].Buttons[button];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KInput::IsControllerButtonHeld(const Controllers controllerId, const SDL_GameControllerButton button) const
|
||||||
|
{
|
||||||
|
if (controllerId < Controllers::Controller1 || controllerId > static_cast<Controllers>(GamePadsCount - 1)) return false;
|
||||||
|
|
||||||
|
return ControllerInputs[static_cast<int>(controllerId)].Buttons[button] && LastControllerInputs[static_cast<int>(controllerId)].Buttons[button];
|
||||||
|
}
|
||||||
|
|
||||||
|
float KInput::GetControllerAxis(const Controllers controllerId, const SDL_GameControllerAxis axis) const
|
||||||
|
{
|
||||||
|
if (controllerId <Controllers::Controller1 || controllerId > static_cast<Controllers>(GamePadsCount - 1)) return 0.0;
|
||||||
|
|
||||||
|
const int value = ControllerInputs[static_cast<int>(controllerId)].Axis[axis];
|
||||||
|
if (std::abs(value) < Constants::JOYSTICK_DEAD_ZONE) return 0.0;
|
||||||
|
|
||||||
|
return static_cast<float>(value) / 32768.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KInput::IsKeyboardButtonPressed(const Uint8 scanCode) const
|
||||||
|
{
|
||||||
|
if (scanCode > KeyboardInputs.size() || scanCode > LastKeyboardInputs.size())
|
||||||
|
return false;
|
||||||
|
return KeyboardInputs[scanCode] && KeyboardInputs[scanCode] != LastKeyboardInputs[scanCode];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KInput::IsKeyboardButtonReleased(const Uint8 scanCode) const
|
||||||
|
{
|
||||||
|
if (scanCode > KeyboardInputs.size() || scanCode > LastKeyboardInputs.size())
|
||||||
|
return false;
|
||||||
|
return !KeyboardInputs[scanCode] && KeyboardInputs[scanCode] != LastKeyboardInputs[scanCode];
|
||||||
|
}
|
||||||
|
|
||||||
|
float KInput::GetAxisValue(const std::string& name, const KPlayer& player) const
|
||||||
|
{
|
||||||
|
float value = 0.f;
|
||||||
|
const auto keyAxisBindRange = KeyAxisBinds[static_cast<int>(player)].equal_range(name);
|
||||||
|
for (auto keyAxisBind = keyAxisBindRange.first; keyAxisBind != keyAxisBindRange.second; ++keyAxisBind) {
|
||||||
|
if (IsKeyboardButtonHeld(keyAxisBind->second.first)) {
|
||||||
|
value += 1.0f * keyAxisBind->second.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto controllerAxisBindRange = ControllerAxisBinds[static_cast<int>(player)].equal_range(name);
|
||||||
|
for (auto controllerAxisBind = controllerAxisBindRange.first; controllerAxisBind != controllerAxisBindRange.second; ++controllerAxisBind) {
|
||||||
|
value += GetControllerAxis(controllerAxisBind->second.Controller, controllerAxisBind->second.Axis) * controllerAxisBind->second.Scale;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KInput::IsKeyboardButtonHeld(const Uint8 scanCode) const
|
||||||
|
{
|
||||||
|
if (scanCode > KeyboardInputs.size())
|
||||||
|
return false;
|
||||||
|
return KeyboardInputs[scanCode];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
61
2dkg_zad5/2dgk_zad5/KInput.h
Normal file
61
2dkg_zad5/2dgk_zad5/KInput.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <SDL_events.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Controllers.h"
|
||||||
|
#include "GamePad.h"
|
||||||
|
#include "KActionBind.h"
|
||||||
|
#include "KPlayer.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
struct KControllerAxisMapping {
|
||||||
|
KControllerAxisMapping(const Controllers controller, const SDL_GameControllerAxis axis, const float scale) : Controller(controller), Axis(axis), Scale(scale) {}
|
||||||
|
Controllers Controller;
|
||||||
|
SDL_GameControllerAxis Axis;
|
||||||
|
float Scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
class KInput {
|
||||||
|
std::vector<SDL_GameController*> ConnectedControllers;
|
||||||
|
std::vector<GamePad> ControllerInputs;
|
||||||
|
std::vector<GamePad> LastControllerInputs;
|
||||||
|
std::vector<Uint8> KeyboardInputs;
|
||||||
|
std::vector<Uint8> LastKeyboardInputs;
|
||||||
|
std::vector<KActionBind> Actions;
|
||||||
|
std::vector<KAxisBind> Axes;
|
||||||
|
std::unordered_multimap<std::string, Uint8> KeyBinds[static_cast<int>(KPlayer::Player2) + 1];
|
||||||
|
std::unordered_multimap<std::string, std::pair<Controllers, SDL_GameControllerButton>> ButtonBinds[static_cast<int>(KPlayer::Player2) + 1];
|
||||||
|
std::unordered_multimap<std::string, KControllerAxisMapping> ControllerAxisBinds[static_cast<int>(KPlayer::Player2) + 1];
|
||||||
|
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;
|
||||||
|
bool IsControllerButtonHeld(Controllers controllerId, SDL_GameControllerButton button) const;
|
||||||
|
float GetControllerAxis(Controllers controllerId, SDL_GameControllerAxis axis) const;
|
||||||
|
bool IsKeyboardButtonHeld(Uint8 scanCode) const;
|
||||||
|
bool IsKeyboardButtonPressed(Uint8 scanCode) const;
|
||||||
|
bool IsKeyboardButtonReleased(Uint8 scanCode) const;
|
||||||
|
float GetAxisValue(const std::string& name, const KPlayer& player) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
106
2dkg_zad5/2dgk_zad5/KPawn.cpp
Normal file
106
2dkg_zad5/2dgk_zad5/KPawn.cpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#include "KPawn.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
//#include <typeinfo>
|
||||||
|
|
||||||
|
#include "Constants.h"
|
||||||
|
#include "KCollider.h"
|
||||||
|
//#include "KPlayerController.h"
|
||||||
|
#include "KSettings.h"
|
||||||
|
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
void KPawn::CollisionDetectionStep(const std::unordered_map<std::pair<int, int>, std::shared_ptr<KSolid>, Utils::PairHash>& objects)
|
||||||
|
{
|
||||||
|
if (GetCollider() == nullptr) return;
|
||||||
|
|
||||||
|
const auto xPos = static_cast<int>(GetPosition().X / Constants::TILE_WIDTH);
|
||||||
|
const auto yPos = static_cast<int>(GetPosition().Y / Constants::TILE_HEIGHT);
|
||||||
|
|
||||||
|
for (const auto& [oX, oY] : std::initializer_list<std::pair<int, int>>{ {0, 0}, {-1,0}, {1,0}, {0,-1}, {0,1}, {-1,-1}, {1,1}, {1,-1}, {-1,1} })
|
||||||
|
{
|
||||||
|
auto it = objects.find({ xPos + oX, yPos + oY });
|
||||||
|
if (it == objects.end()) continue;
|
||||||
|
const auto& other = it->second;
|
||||||
|
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;
|
||||||
|
if (GetPosition().Y - GetCollider()->GetHeight() / 2.f >= other->GetPosition().Y + other->GetCollider()->GetHeight() / 2.f)
|
||||||
|
{
|
||||||
|
Velocity.Y = 0;
|
||||||
|
}
|
||||||
|
if (GetPosition().Y + GetCollider()->GetHeight() / 2.f <= other->GetPosition().Y - other->GetCollider()->GetHeight() / 2.f)
|
||||||
|
{
|
||||||
|
Velocity.Y = 0;
|
||||||
|
CanJump = true;
|
||||||
|
CanDoubleJump = true;
|
||||||
|
HasJumped = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPawn::MovementStep(const float& timeStep)
|
||||||
|
{
|
||||||
|
const float gravityScale = Velocity.Y > 0.f ? 3.f : 1.f;
|
||||||
|
Position.X += Velocity.X * timeStep;
|
||||||
|
Position.Y += Velocity.Y * timeStep + 1.f / 2.f * gravityScale * Settings->Gravity * timeStep * timeStep;
|
||||||
|
Velocity.Y += gravityScale * Settings->Gravity * timeStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPawn::CollisionDetectionWithMapStep(const SDL_FRect& map)
|
||||||
|
{
|
||||||
|
const auto separationVector = GetCollider()->GetSeparationVector(map);
|
||||||
|
Position += separationVector;
|
||||||
|
if (separationVector.Y < 0)
|
||||||
|
{
|
||||||
|
Velocity.Y = 0;
|
||||||
|
CanJump = true;
|
||||||
|
CanDoubleJump = true;
|
||||||
|
HasJumped = false;
|
||||||
|
}
|
||||||
|
if (separationVector.Y > 0)
|
||||||
|
{
|
||||||
|
Velocity.Y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPawn::AddXMovementInput(const float& input)
|
||||||
|
{
|
||||||
|
Velocity.X = input * Constants::SPEED * (1 - Constants::SMOOTH) + Velocity.X * Constants::SMOOTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPawn::StopJump() {
|
||||||
|
if (!CanJump) {
|
||||||
|
if (Velocity.Y < -Settings->ShortJumpVelocity)
|
||||||
|
Velocity.Y = -Settings->ShortJumpVelocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPawn::StartJump() {
|
||||||
|
if (Velocity.Y != 0.f)
|
||||||
|
{
|
||||||
|
CanJump = false;
|
||||||
|
}
|
||||||
|
if (CanJump) {
|
||||||
|
CanJump = false;
|
||||||
|
HasJumped = true;
|
||||||
|
Velocity.Y = -Settings->JumpInitialVelocity;
|
||||||
|
}
|
||||||
|
else if (HasJumped && CanDoubleJump)
|
||||||
|
{
|
||||||
|
CanDoubleJump = false;
|
||||||
|
Velocity.Y = -Settings->JumpInitialVelocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
39
2dkg_zad5/2dgk_zad5/KPawn.h
Normal file
39
2dkg_zad5/2dgk_zad5/KPawn.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include <SDL_rect.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "KSolid.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
class KSettings;
|
||||||
|
class KPlayerController;
|
||||||
|
|
||||||
|
class KPawn : public KSolid
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KPawn(const KVector2D& position, const KTexture& texture,
|
||||||
|
const std::shared_ptr<KPlayerController>& playerController, KSettings* settings)
|
||||||
|
: KSolid(position, texture, nullptr),
|
||||||
|
PlayerController(playerController), CanJump(false), CanDoubleJump(false), HasJumped(true), Settings(settings)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollisionDetectionStep(const std::unordered_map<std::pair<int, int>, std::shared_ptr<KSolid>, Utils::PairHash>& objects);
|
||||||
|
void MovementStep(const float& timeStep);
|
||||||
|
void CollisionDetectionWithMapStep(const SDL_FRect& map);
|
||||||
|
void AddXMovementInput(const float& input);
|
||||||
|
void StopJump();
|
||||||
|
void StartJump();
|
||||||
|
private:
|
||||||
|
const std::weak_ptr<KPlayerController> PlayerController;
|
||||||
|
KVector2D Velocity{ 0.f, 0.f };
|
||||||
|
bool CanJump;
|
||||||
|
bool CanDoubleJump;
|
||||||
|
bool HasJumped;
|
||||||
|
KSettings* Settings;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
8
2dkg_zad5/2dgk_zad5/KPlayer.h
Normal file
8
2dkg_zad5/2dgk_zad5/KPlayer.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
enum class KPlayer : int {
|
||||||
|
Player1,
|
||||||
|
Player2
|
||||||
|
};
|
||||||
|
}
|
55
2dkg_zad5/2dgk_zad5/KPlayerController.cpp
Normal file
55
2dkg_zad5/2dgk_zad5/KPlayerController.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include "KPlayerController.h"
|
||||||
|
|
||||||
|
#include "KInput.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
void KPlayerController::SetupInputBindings(KInput& input)
|
||||||
|
{
|
||||||
|
input.BindAxis("MoveX", shared_from_this(), &KPlayerController::MoveXAxis, Player);
|
||||||
|
input.BindAction("Jump", InputState::Pressed, shared_from_this(), &KPlayerController::StartJump, Player);
|
||||||
|
input.BindAction("Jump", InputState::Released, shared_from_this(), &KPlayerController::StopJump, Player);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPlayerController::MoveXAxis(const float axis)
|
||||||
|
{
|
||||||
|
Input.X += axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPlayerController::StartJump() {
|
||||||
|
InputStartJump = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPlayerController::StopJump() {
|
||||||
|
InputStopJump = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPlayerController::Update(float deltaTime)
|
||||||
|
{
|
||||||
|
Input.Normalize();
|
||||||
|
if (Pawn != nullptr) {
|
||||||
|
Pawn->AddXMovementInput(Input.X);
|
||||||
|
if (InputStartJump)
|
||||||
|
Pawn->StartJump();
|
||||||
|
if (InputStopJump)
|
||||||
|
Pawn->StopJump();
|
||||||
|
}
|
||||||
|
Input *= 0;
|
||||||
|
InputStartJump = false;
|
||||||
|
InputStopJump = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPlayerController::Possess(KPawn* pawn)
|
||||||
|
{
|
||||||
|
Pawn = pawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPlayerController::UnPossess()
|
||||||
|
{
|
||||||
|
Pawn = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const KPlayer& KPlayerController::GetPlayer() const
|
||||||
|
{
|
||||||
|
return Player;
|
||||||
|
}
|
||||||
|
}
|
36
2dkg_zad5/2dgk_zad5/KPlayerController.h
Normal file
36
2dkg_zad5/2dgk_zad5/KPlayerController.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "KPawn.h"
|
||||||
|
#include "KPlayer.h"
|
||||||
|
#include "KVector2d.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
class KInput;
|
||||||
|
|
||||||
|
class KPlayerController : public std::enable_shared_from_this<KPlayerController>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit KPlayerController(const KPlayer player)
|
||||||
|
: Player(player)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupInputBindings(KInput& input);
|
||||||
|
void MoveXAxis(float axis);
|
||||||
|
void StartJump();
|
||||||
|
void StopJump();
|
||||||
|
void Update(float deltaTime);
|
||||||
|
void Possess(KPawn* pawn);
|
||||||
|
void UnPossess();
|
||||||
|
const KPlayer& GetPlayer() const;
|
||||||
|
private:
|
||||||
|
KVector2D Input{ 0.f, 0.f };
|
||||||
|
const KPlayer Player;
|
||||||
|
KPawn* Pawn{};
|
||||||
|
bool InputStartJump{};
|
||||||
|
bool InputStopJump{};
|
||||||
|
};
|
||||||
|
typedef void (KPlayerController::* KPlayerCommand)();
|
||||||
|
typedef void (KPlayerController::* KPlayerAxisCommand)(float input);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
134
2dkg_zad5/2dgk_zad5/KRect.cpp
Normal file
134
2dkg_zad5/2dgk_zad5/KRect.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#include "KRect.h"
|
||||||
|
|
||||||
|
#include "KCircle.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
|
||||||
|
float KRect::GetWidth() const {
|
||||||
|
return Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
float KRect::GetHeight() const {
|
||||||
|
return Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
KVector2D KRect::GetSeparationVector(const float left, const float right, const float top, const float 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))
|
||||||
|
vY = 0;
|
||||||
|
if (fabs(x) > fabs(y))
|
||||||
|
vX = 0;
|
||||||
|
return { vX, vY };
|
||||||
|
}
|
||||||
|
|
||||||
|
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->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->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 = 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->GetParent()->GetPosition().X, GetLeft(), GetRight()),
|
||||||
|
Utils::Clamp(other->GetParent()->GetPosition().Y, GetTop(), GetBottom()));
|
||||||
|
|
||||||
|
return (other->GetParent()->GetPosition() - f).Length() < other->GetRadius();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
39
2dkg_zad5/2dgk_zad5/KRect.h
Normal file
39
2dkg_zad5/2dgk_zad5/KRect.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <SDL_rect.h>
|
||||||
|
|
||||||
|
#include "KCollider.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
class KCircle;
|
||||||
|
|
||||||
|
class KRect final : public KCollider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KRect(KSolid* parent, const float width, const float height)
|
||||||
|
: KCollider(parent),
|
||||||
|
Width(width),
|
||||||
|
Height(height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] float GetWidth() const override;
|
||||||
|
[[nodiscard]] float GetHeight() const override;
|
||||||
|
static KVector2D GetSeparationVector(float left, float right, float top, float bottom);
|
||||||
|
bool IsCollision(const KCollider* other) const override;
|
||||||
|
KVector2D GetSeparationVector(const KCollider* other) const override;
|
||||||
|
[[nodiscard]] KVector2D GetSeparationVector(const SDL_FRect& map) const override;
|
||||||
|
private:
|
||||||
|
KVector2D GetSeparationVector(const KCircle* other) const;
|
||||||
|
KVector2D GetSeparationVector(const KRect* other) const;
|
||||||
|
bool IsCollision(const KCircle* other) const;
|
||||||
|
[[nodiscard]] float GetLeft() const;
|
||||||
|
[[nodiscard]] float GetRight() const;
|
||||||
|
[[nodiscard]] float GetBottom() const;
|
||||||
|
[[nodiscard]] float GetTop() const;
|
||||||
|
bool IsCollision(const KRect* other) const;
|
||||||
|
float Width;
|
||||||
|
float Height;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
15
2dkg_zad5/2dgk_zad5/KRectPawn.cpp
Normal file
15
2dkg_zad5/2dgk_zad5/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, KSettings* settings) : KPawn(position, texture, playerController, settings),
|
||||||
|
Collider(this, texture.GetWidth(), texture.GetHeight())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const KCollider* KRectPawn::GetCollider() const
|
||||||
|
{
|
||||||
|
return &Collider;
|
||||||
|
}
|
||||||
|
}
|
20
2dkg_zad5/2dgk_zad5/KRectPawn.h
Normal file
20
2dkg_zad5/2dgk_zad5/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, KSettings* settings);
|
||||||
|
|
||||||
|
const KCollider* GetCollider() const override;
|
||||||
|
private:
|
||||||
|
KRect Collider;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
98
2dkg_zad5/2dgk_zad5/KSettings.cpp
Normal file
98
2dkg_zad5/2dgk_zad5/KSettings.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#include "KSettings.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
#include "Constants.h"
|
||||||
|
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
KSettings::KSettings(const float maxJumpHeight, const float horizontalDistanceToMaxJumpHeight) : MaxJumpHeightValue(maxJumpHeight),
|
||||||
|
HorizontalDistanceToMaxJumpHeightValue(horizontalDistanceToMaxJumpHeight),
|
||||||
|
TimeToMaxHeightValue(NAN),
|
||||||
|
GravityValue(NAN),
|
||||||
|
JumpInitialVelocityValue(NAN),
|
||||||
|
ShortJumpVelocityValue(NAN),
|
||||||
|
CollisionEnabledValue(true),
|
||||||
|
Dirty(true),
|
||||||
|
MaxJumpHeight(this, &KSettings::GetMaxJumpHeight, &KSettings::SetMaxJumpHeight),
|
||||||
|
HorizontalDistanceToMaxJumpHeight(this, &KSettings::GetHorizontalDistanceToMaxJumpHeight, &KSettings::SetHorizontalDistanceToMaxJumpHeight),
|
||||||
|
TimeToMaxHeight(this, &KSettings::GetTimeToMaxHeight),
|
||||||
|
Gravity(this, &KSettings::GetGravity),
|
||||||
|
JumpInitialVelocity(this, &KSettings::GetJumpInitialVelocity),
|
||||||
|
ShortJumpVelocity(this, &KSettings::GetShortJumpVelocity),
|
||||||
|
CollisionEnabled(this, &KSettings::GetCollisionEnabled, &KSettings::SetCollisionEnabled)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSettings::SetCollisionEnabled(const bool value)
|
||||||
|
{
|
||||||
|
if (value != CollisionEnabledValue)
|
||||||
|
CollisionEnabledValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSettings::SetMaxJumpHeight(const float h)
|
||||||
|
{
|
||||||
|
if (h <= 0.f && MaxJumpHeightValue <= 0.f) return;
|
||||||
|
if (MaxJumpHeightValue != h) { // NOLINT(clang-diagnostic-float-equal)
|
||||||
|
MaxJumpHeightValue = std::max(h, 0.f);
|
||||||
|
Dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSettings::SetHorizontalDistanceToMaxJumpHeight(const float xn)
|
||||||
|
{
|
||||||
|
if (xn <= 0.f && HorizontalDistanceToMaxJumpHeightValue <= 0.f) return;
|
||||||
|
if (HorizontalDistanceToMaxJumpHeightValue != xn) { // NOLINT(clang-diagnostic-float-equal)
|
||||||
|
HorizontalDistanceToMaxJumpHeightValue = std::max(xn, 0.f);
|
||||||
|
Dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once CppMemberFunctionMayBeConst
|
||||||
|
bool KSettings::GetCollisionEnabled()
|
||||||
|
{
|
||||||
|
return CollisionEnabledValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float KSettings::GetTimeToMaxHeight()
|
||||||
|
{
|
||||||
|
if (Dirty)
|
||||||
|
TimeToMaxHeightValue = HorizontalDistanceToMaxJumpHeightValue / Constants::SPEED;
|
||||||
|
return TimeToMaxHeightValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float KSettings::GetGravity()
|
||||||
|
{
|
||||||
|
if (Dirty) {
|
||||||
|
const auto timeToMaxHeight = GetTimeToMaxHeight();
|
||||||
|
GravityValue = 2.0f * MaxJumpHeightValue / (timeToMaxHeight * timeToMaxHeight);
|
||||||
|
}
|
||||||
|
return GravityValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float KSettings::GetJumpInitialVelocity()
|
||||||
|
{
|
||||||
|
if (Dirty)
|
||||||
|
JumpInitialVelocityValue = 2.0f * MaxJumpHeightValue / GetTimeToMaxHeight();
|
||||||
|
return JumpInitialVelocityValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float KSettings::GetShortJumpVelocity()
|
||||||
|
{
|
||||||
|
if (Dirty)
|
||||||
|
ShortJumpVelocityValue = GetJumpInitialVelocity() / 2.f;
|
||||||
|
return ShortJumpVelocityValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once CppMemberFunctionMayBeConst
|
||||||
|
float KSettings::GetMaxJumpHeight()
|
||||||
|
{
|
||||||
|
return MaxJumpHeightValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once CppMemberFunctionMayBeConst
|
||||||
|
float KSettings::GetHorizontalDistanceToMaxJumpHeight()
|
||||||
|
{
|
||||||
|
return HorizontalDistanceToMaxJumpHeightValue;
|
||||||
|
}
|
||||||
|
}
|
37
2dkg_zad5/2dgk_zad5/KSettings.h
Normal file
37
2dkg_zad5/2dgk_zad5/KSettings.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Property.h"
|
||||||
|
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
class KSettings final
|
||||||
|
{
|
||||||
|
float MaxJumpHeightValue;
|
||||||
|
float HorizontalDistanceToMaxJumpHeightValue;
|
||||||
|
float TimeToMaxHeightValue;
|
||||||
|
float GravityValue;
|
||||||
|
float JumpInitialVelocityValue;
|
||||||
|
float ShortJumpVelocityValue;
|
||||||
|
bool CollisionEnabledValue;
|
||||||
|
bool Dirty;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
KSettings(float maxJumpHeight, float horizontalDistanceToMaxJumpHeight);
|
||||||
|
const Property<float, KSettings> MaxJumpHeight, HorizontalDistanceToMaxJumpHeight;
|
||||||
|
const ReadOnlyProperty<float, KSettings> TimeToMaxHeight, Gravity, JumpInitialVelocity, ShortJumpVelocity;
|
||||||
|
const Property<bool, KSettings> CollisionEnabled;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetCollisionEnabled(bool value);
|
||||||
|
void SetMaxJumpHeight(float h);
|
||||||
|
void SetHorizontalDistanceToMaxJumpHeight(float xn);
|
||||||
|
bool GetCollisionEnabled();
|
||||||
|
float GetTimeToMaxHeight();
|
||||||
|
float GetGravity();
|
||||||
|
float GetJumpInitialVelocity();
|
||||||
|
float GetShortJumpVelocity();
|
||||||
|
float GetMaxJumpHeight();
|
||||||
|
float GetHorizontalDistanceToMaxJumpHeight();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
10
2dkg_zad5/2dgk_zad5/KSolid.cpp
Normal file
10
2dkg_zad5/2dgk_zad5/KSolid.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "KSolid.h"
|
||||||
|
|
||||||
|
#include "KCamera.h"
|
||||||
|
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
KSolid::KSolid(const KVector2D& position, const KTexture& texture, SDL_Rect* tileClip, const SDL_RendererFlip flip) : KDrawable(position, texture, tileClip, flip)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
21
2dkg_zad5/2dgk_zad5/KSolid.h
Normal file
21
2dkg_zad5/2dgk_zad5/KSolid.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <SDL_render.h>
|
||||||
|
|
||||||
|
#include "KDrawable.h"
|
||||||
|
#include "KTexture.h"
|
||||||
|
#include "KVector2d.h"
|
||||||
|
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
class KCamera;
|
||||||
|
class KCollider;
|
||||||
|
|
||||||
|
class KSolid : public KDrawable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KSolid(const KVector2D& position, const KTexture& texture, SDL_Rect* tileClip, SDL_RendererFlip flip = SDL_FLIP_NONE);
|
||||||
|
~KSolid() override = default;
|
||||||
|
[[nodiscard]] virtual const KCollider* GetCollider() const = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
9
2dkg_zad5/2dgk_zad5/KSolidTile.cpp
Normal file
9
2dkg_zad5/2dgk_zad5/KSolidTile.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "KSolidTile.h"
|
||||||
|
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
const KCollider* KSolidTile::GetCollider() const
|
||||||
|
{
|
||||||
|
return &Collider;
|
||||||
|
}
|
||||||
|
}
|
23
2dkg_zad5/2dgk_zad5/KSolidTile.h
Normal file
23
2dkg_zad5/2dgk_zad5/KSolidTile.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Constants.h"
|
||||||
|
#include "KSolid.h"
|
||||||
|
#include "KRect.h"
|
||||||
|
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
class KSolidTile final :
|
||||||
|
public KSolid
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KSolidTile(const KVector2D& position, const KTexture& texture, SDL_Rect* tileClip, const SDL_RendererFlip flip = SDL_FLIP_NONE)
|
||||||
|
: KSolid(position, texture, tileClip, flip),
|
||||||
|
Collider(this, tileClip != nullptr ? Constants::TILE_WIDTH * 1.f : texture.GetWidth() * 1.f, tileClip != nullptr ? Constants::TILE_HEIGHT * 1.f : texture.GetHeight() * 1.f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const KCollider* GetCollider() const override;
|
||||||
|
private:
|
||||||
|
KRect Collider;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
155
2dkg_zad5/2dgk_zad5/KTexture.cpp
Normal file
155
2dkg_zad5/2dgk_zad5/KTexture.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#include "KTexture.h"
|
||||||
|
|
||||||
|
#include <SDL_image.h>
|
||||||
|
#include <SDL_render.h>
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
KTexture::KTexture() : Texture(nullptr), Width(0), Height(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KTexture::KTexture(KTexture&& other) noexcept
|
||||||
|
: Texture(other.Texture),
|
||||||
|
Width(other.Width),
|
||||||
|
Height(other.Height) {
|
||||||
|
other.Texture = nullptr;
|
||||||
|
other.Width = 0;
|
||||||
|
other.Height = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
KTexture& KTexture::operator=(KTexture&& other) noexcept {
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
Free();
|
||||||
|
Texture = other.Texture;
|
||||||
|
Width = other.Width;
|
||||||
|
Height = other.Height;
|
||||||
|
other.Texture = nullptr;
|
||||||
|
other.Width = 0;
|
||||||
|
other.Height = 0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
KTexture::~KTexture()
|
||||||
|
{
|
||||||
|
//Deallocate
|
||||||
|
Free();
|
||||||
|
|
||||||
|
}
|
||||||
|
bool KTexture::LoadFromFile(const std::string& path, SDL_Renderer* renderer)
|
||||||
|
{
|
||||||
|
//Get rid of preexisting texture
|
||||||
|
Free();
|
||||||
|
//The final texture
|
||||||
|
SDL_Texture* newTexture = nullptr;
|
||||||
|
|
||||||
|
//Load image at specified path
|
||||||
|
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
|
||||||
|
if (loadedSurface == nullptr)
|
||||||
|
{
|
||||||
|
printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Color key image
|
||||||
|
SDL_SetColorKey(loadedSurface, SDL_TRUE, SDL_MapRGB(loadedSurface->format, 0xFF, 0, 0xFF));
|
||||||
|
//Create texture from surface pixels
|
||||||
|
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
|
||||||
|
if (newTexture == nullptr)
|
||||||
|
{
|
||||||
|
printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Get image dimensions
|
||||||
|
Width = loadedSurface->w;
|
||||||
|
Height = loadedSurface->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get rid of old loaded surface
|
||||||
|
SDL_FreeSurface(loadedSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return success
|
||||||
|
Texture = newTexture;
|
||||||
|
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
|
||||||
|
if (Texture != nullptr)
|
||||||
|
{
|
||||||
|
SDL_DestroyTexture(Texture);
|
||||||
|
Texture = nullptr;
|
||||||
|
Width = 0;
|
||||||
|
Height = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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_FRect renderQuad = {
|
||||||
|
x * scale, y * scale,
|
||||||
|
static_cast<float>(Width) * scale, static_cast<float>(Height) * scale
|
||||||
|
};
|
||||||
|
|
||||||
|
//Set clip rendering dimensions
|
||||||
|
if (clip != nullptr)
|
||||||
|
{
|
||||||
|
renderQuad.w = clip->w;
|
||||||
|
renderQuad.h = clip->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Render to screen
|
||||||
|
SDL_RenderCopyF(renderer, Texture, clip, &renderQuad);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KTexture::RenderEx(SDL_Renderer* renderer, const float x, const float y, const double degrees, SDL_Rect* clip, const float scale, const SDL_RendererFlip flip) const
|
||||||
|
{
|
||||||
|
if (Texture == nullptr) return;
|
||||||
|
//Set rendering space and render to screen
|
||||||
|
SDL_FRect renderQuad = {
|
||||||
|
x * scale, y * scale,
|
||||||
|
static_cast<float>(Width) * scale, static_cast<float>(Height) * scale
|
||||||
|
};
|
||||||
|
|
||||||
|
//Set clip rendering dimensions
|
||||||
|
if (clip != nullptr)
|
||||||
|
{
|
||||||
|
renderQuad.w = clip->w;
|
||||||
|
renderQuad.h = clip->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Render to screen
|
||||||
|
SDL_RenderCopyExF(renderer, Texture, clip, &renderQuad, degrees, nullptr, flip);
|
||||||
|
}
|
||||||
|
|
||||||
|
int KTexture::GetWidth() const
|
||||||
|
{
|
||||||
|
return Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int KTexture::GetHeight() const
|
||||||
|
{
|
||||||
|
return Height;
|
||||||
|
}
|
||||||
|
}
|
48
2dkg_zad5/2dgk_zad5/KTexture.h
Normal file
48
2dkg_zad5/2dgk_zad5/KTexture.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <SDL_render.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
//Texture wrapper class
|
||||||
|
class KTexture {
|
||||||
|
public:
|
||||||
|
KTexture();
|
||||||
|
|
||||||
|
~KTexture();
|
||||||
|
|
||||||
|
|
||||||
|
KTexture(const KTexture& other) = delete;
|
||||||
|
|
||||||
|
KTexture(KTexture&& other) noexcept;
|
||||||
|
|
||||||
|
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, float x, float y, SDL_Rect* clip = nullptr, float scale = 1.f) const;
|
||||||
|
|
||||||
|
void RenderEx(SDL_Renderer* renderer, float x, float y, double degrees = 0, SDL_Rect* clip = nullptr, float scale = 1.f, SDL_RendererFlip flip = SDL_FLIP_NONE) const;
|
||||||
|
|
||||||
|
//Gets image dimensions
|
||||||
|
int GetWidth() const;
|
||||||
|
int GetHeight() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//The actual hardware texture
|
||||||
|
SDL_Texture* Texture;
|
||||||
|
|
||||||
|
//Image dimensions
|
||||||
|
int Width;
|
||||||
|
int Height;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
33
2dkg_zad5/2dgk_zad5/KTile.cpp
Normal file
33
2dkg_zad5/2dgk_zad5/KTile.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include "KTile.h"
|
||||||
|
|
||||||
|
#include <SDL_render.h>
|
||||||
|
|
||||||
|
#include "Constants.h"
|
||||||
|
#include "KTexture.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
|
||||||
|
int KTile::GetType() const {
|
||||||
|
return static_cast<int>(Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Rect KTile::GetBox() const {
|
||||||
|
return Box;
|
||||||
|
}
|
||||||
|
|
||||||
|
KTile::KTile(const int x, const int y, const TileType tileType) {
|
||||||
|
//Get the offsets
|
||||||
|
Box.x = x;
|
||||||
|
Box.y = y;
|
||||||
|
|
||||||
|
Box.w = Constants::TILE_WIDTH;
|
||||||
|
Box.h = Constants::TILE_HEIGHT;
|
||||||
|
|
||||||
|
//Get the tile type
|
||||||
|
Type = tileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KTile::Render(SDL_Renderer* renderer, KTexture tileTextures[], const SDL_Rect& camera, const float scale) const {
|
||||||
|
tileTextures[GetType()].Render(renderer, Box.x - camera.x, Box.y - camera.y, nullptr, scale);
|
||||||
|
}
|
||||||
|
}
|
34
2dkg_zad5/2dgk_zad5/KTile.h
Normal file
34
2dkg_zad5/2dgk_zad5/KTile.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <SDL_rect.h>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <SDL_render.h>
|
||||||
|
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
class KTexture;
|
||||||
|
|
||||||
|
enum class TileType : std::uint32_t {
|
||||||
|
Default = 0,
|
||||||
|
Wall = 1
|
||||||
|
};
|
||||||
|
class KTile {
|
||||||
|
public:
|
||||||
|
//Initializes position and type
|
||||||
|
KTile(int x, int y, TileType tileType);
|
||||||
|
|
||||||
|
//Shows the tile
|
||||||
|
void Render(SDL_Renderer* renderer, KTexture tileTextures[], const SDL_Rect& camera, float scale = 1.f) const;
|
||||||
|
|
||||||
|
//Get the tile type
|
||||||
|
int GetType() const;
|
||||||
|
|
||||||
|
SDL_Rect GetBox() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//The attributes of the tile
|
||||||
|
SDL_Rect Box{};
|
||||||
|
|
||||||
|
//The tile type
|
||||||
|
TileType Type;
|
||||||
|
};
|
||||||
|
}
|
82
2dkg_zad5/2dgk_zad5/KVector2d.h
Normal file
82
2dkg_zad5/2dgk_zad5/KVector2d.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cfloat>
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
struct KVector2D {
|
||||||
|
float X;
|
||||||
|
float Y;
|
||||||
|
|
||||||
|
KVector2D(const float x, const float y) : X(x), Y(y) {}
|
||||||
|
|
||||||
|
float Length() const { return sqrt(X * X + Y * Y); }
|
||||||
|
float Length2() const { return X * X + Y * Y; }
|
||||||
|
|
||||||
|
bool operator==(const KVector2D& v2) const {
|
||||||
|
return (*this - v2).Length2() < FLT_EPSILON * FLT_EPSILON;
|
||||||
|
}
|
||||||
|
|
||||||
|
KVector2D operator+(const KVector2D& v2) const {
|
||||||
|
return { X + v2.X, Y + v2.Y };
|
||||||
|
}
|
||||||
|
|
||||||
|
friend KVector2D& operator+=(KVector2D& v1, const KVector2D& v2) {
|
||||||
|
v1.X += v2.X;
|
||||||
|
v1.Y += v2.Y;
|
||||||
|
return v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
KVector2D operator*(const float scalar) const
|
||||||
|
{
|
||||||
|
return { X * scalar, Y * scalar };
|
||||||
|
}
|
||||||
|
|
||||||
|
KVector2D& operator*=(const float scalar) {
|
||||||
|
X *= scalar;
|
||||||
|
Y *= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
KVector2D operator-(const KVector2D& v2) const {
|
||||||
|
return { X - v2.X, Y - v2.Y };
|
||||||
|
}
|
||||||
|
friend KVector2D& operator-=(KVector2D& v1, const KVector2D& v2) {
|
||||||
|
v1.X -= v2.X;
|
||||||
|
v1.Y -= v2.Y;
|
||||||
|
return v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
KVector2D operator/(const float scalar) const
|
||||||
|
{
|
||||||
|
return { X / scalar, Y / scalar };
|
||||||
|
}
|
||||||
|
KVector2D& operator/=(const float scalar) {
|
||||||
|
X /= scalar;
|
||||||
|
Y /= scalar;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
float DotProduct(const KVector2D& v2) const {
|
||||||
|
return DotProduct(*this, v2);
|
||||||
|
}
|
||||||
|
KVector2D Reflect(const KVector2D& normal) const {
|
||||||
|
return Reflect(normal, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Normalize() {
|
||||||
|
const float l = Length();
|
||||||
|
if (l > 1.f) {
|
||||||
|
(*this) *= 1 / l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static KVector2D Reflect(const KVector2D& normal, const KVector2D& vector) {
|
||||||
|
const float dn = 2 * vector.DotProduct(normal);
|
||||||
|
return vector - normal * dn;
|
||||||
|
}
|
||||||
|
static float DotProduct(const KVector2D& v1, const KVector2D& v2) {
|
||||||
|
return v1.X * v2.X + v1.Y * v2.Y ;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
8
2dkg_zad5/2dgk_zad5/Main.cpp
Normal file
8
2dkg_zad5/2dgk_zad5/Main.cpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "KGame.h"
|
||||||
|
|
||||||
|
int main(int argc, char* args[])
|
||||||
|
{
|
||||||
|
KapitanGame::KGame game;
|
||||||
|
|
||||||
|
return game.Run(argc, args);
|
||||||
|
}
|
54
2dkg_zad5/2dgk_zad5/Property.h
Normal file
54
2dkg_zad5/2dgk_zad5/Property.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
namespace KapitanGame
|
||||||
|
{
|
||||||
|
template <class T, class C>
|
||||||
|
class ReadOnlyProperty {
|
||||||
|
protected:
|
||||||
|
C* Owner;
|
||||||
|
T(C::* Getter)();
|
||||||
|
public:
|
||||||
|
ReadOnlyProperty() : Owner(), Getter() {}
|
||||||
|
ReadOnlyProperty(C* owner, T(C::* getter)()) : Owner(owner), Getter(getter) {}
|
||||||
|
|
||||||
|
[[nodiscard]] T Get() const {
|
||||||
|
return (Owner->*Getter)();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once CppNonExplicitConversionOperator
|
||||||
|
operator T() const {
|
||||||
|
return Get();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class C>
|
||||||
|
class Property : public ReadOnlyProperty<T,C> {
|
||||||
|
void(C::* Setter)(T);
|
||||||
|
public:
|
||||||
|
Property() : ReadOnlyProperty(), Setter() {}
|
||||||
|
Property(C* owner, T(C::* getter)(), void(C::* setter)(T)) : ReadOnlyProperty<T, C>(owner,getter), Setter(setter) {}
|
||||||
|
void Set(T value) const {
|
||||||
|
(this->Owner->*Setter)(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Property<T, C>& operator = (T value) const { // NOLINT(misc-unconventional-assign-operator)
|
||||||
|
Set(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
const Property<T, C>& operator -= (T value) const { // NOLINT(misc-unconventional-assign-operator)
|
||||||
|
Set(this->Get() - value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
const Property<T, C>& operator += (T value) const { // NOLINT(misc-unconventional-assign-operator)
|
||||||
|
Set(this->Get() + value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
const Property<T, C>& operator *= (T value) const { // NOLINT(misc-unconventional-assign-operator)
|
||||||
|
Set(this->Get() * value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
const Property<T, C>& operator /= (T value) const { // NOLINT(misc-unconventional-assign-operator)
|
||||||
|
Set(this->Get() / value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
7
2dkg_zad5/2dgk_zad5/Utils.cpp
Normal file
7
2dkg_zad5/2dgk_zad5/Utils.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
namespace Utils {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
109
2dkg_zad5/2dgk_zad5/Utils.h
Normal file
109
2dkg_zad5/2dgk_zad5/Utils.h
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <random>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "KPlayer.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
namespace Utils {
|
||||||
|
|
||||||
|
template<typename ... Args>
|
||||||
|
std::string StringFormat(const std::string& format, Args ... args)
|
||||||
|
{
|
||||||
|
const int sizeS = std::snprintf(nullptr, 0, format.c_str(), args ...) + 1; // Extra space for '\0'
|
||||||
|
if (sizeS <= 0) { throw std::runtime_error("Error during formatting."); }
|
||||||
|
const auto size = static_cast<size_t>(sizeS);
|
||||||
|
const auto buf = std::make_unique<char[]>(size);
|
||||||
|
std::snprintf(buf.get(), size, format.c_str(), args ...);
|
||||||
|
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||||
|
}
|
||||||
|
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) * Clamp01(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::default_random_engine make_default_random_engine()
|
||||||
|
{
|
||||||
|
// This gets a source of actual, honest-to-god randomness
|
||||||
|
std::random_device source;
|
||||||
|
|
||||||
|
// Here, we fill an array of random data from the source
|
||||||
|
unsigned int random_data[10];
|
||||||
|
for (auto& elem : random_data) {
|
||||||
|
elem = source();
|
||||||
|
}
|
||||||
|
|
||||||
|
// this creates the random seed sequence out of the random data
|
||||||
|
std::seed_seq seq(random_data + 0, random_data + 10);
|
||||||
|
return std::default_random_engine{ seq };
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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::Player1> KPlayerIterator;
|
||||||
|
|
||||||
|
struct PairHash {
|
||||||
|
template <class T1, class T2>
|
||||||
|
std::size_t operator () (const std::pair<T1, T2>& p) const {
|
||||||
|
auto h1 = std::hash<T1>{}(p.first);
|
||||||
|
auto h2 = std::hash<T2>{}(p.second);
|
||||||
|
return h1 ^ h2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
202
2dkg_zad5/2dgk_zad5/assets/fonts/LICENSE.txt
Normal file
202
2dkg_zad5/2dgk_zad5/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.
|
93
2dkg_zad5/2dgk_zad5/assets/fonts/OFL.txt
Normal file
93
2dkg_zad5/2dgk_zad5/assets/fonts/OFL.txt
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
Copyright 2012 The Press Start 2P Project Authors (cody@zone38.net), with Reserved Font Name "Press Start 2P".
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
BIN
2dkg_zad5/2dgk_zad5/assets/fonts/PressStart2P-Regular.ttf
(Stored with Git LFS)
Normal file
BIN
2dkg_zad5/2dgk_zad5/assets/fonts/PressStart2P-Regular.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
2dkg_zad5/2dgk_zad5/assets/fonts/Roboto-Thin.ttf
(Stored with Git LFS)
Normal file
BIN
2dkg_zad5/2dgk_zad5/assets/fonts/Roboto-Thin.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
79
2dkg_zad5/2dgk_zad5/assets/levels/level1.txt
Normal file
79
2dkg_zad5/2dgk_zad5/assets/levels/level1.txt
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#100,15
|
||||||
|
!0
|
||||||
|
|
||||||
|
3 3 3
|
||||||
|
3 3 3
|
||||||
|
3 3
|
||||||
|
g
|
||||||
|
hg 6g
|
||||||
|
5hg 6g 67hg
|
||||||
|
55hg 67hg 6g 6755hg 6
|
||||||
|
555hg 6755hg67hg 6g 675555hg 67
|
||||||
|
5555hg 675555h755hg 67hg 67555555hg 675
|
||||||
|
55555hg 675555555555hg 6755hg 675555555555555555555555555555555555555555555556755
|
||||||
|
5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
|
||||||
|
5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
|
||||||
|
5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
|
||||||
|
5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
|
||||||
|
!1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
44
|
||||||
|
4 444 44 4 4 4 44 444 4
|
||||||
|
44444 444 4 444 44 44 4444 4 4 4444 4 4 44 4444444444 4444 444 44
|
||||||
|
44444 444444444444 4 4444 4444444444444 44444444 4 4444 444444444444 44444444444 4444
|
||||||
|
4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
|
||||||
|
4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
|
||||||
|
4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
|
||||||
|
4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
|
||||||
|
!2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2222
|
||||||
|
222222222222
|
||||||
|
22222222222222
|
||||||
|
2222222222222222
|
||||||
|
22222222222222222
|
||||||
|
22222222222222222
|
||||||
|
2222222222 22222222222222222
|
||||||
|
2222222222 22222222222222222
|
||||||
|
2222222222 22222222222222222
|
||||||
|
2222222222 22222222222222222
|
||||||
|
|
||||||
|
|
||||||
|
!3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
0000
|
||||||
|
0000 000
|
||||||
|
0 000 00
|
||||||
|
000
|
||||||
|
000000
|
||||||
|
0000 0
|
||||||
|
0 00000 00 00 0
|
||||||
|
00 00 00 0000 0
|
||||||
|
00 00 00 00
|
||||||
|
P 00 00 00 00
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
!4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1111
|
||||||
|
1111
|
||||||
|
1 11
|
||||||
|
11
|
||||||
|
11111
|
||||||
|
1111
|
||||||
|
1 11111 1111111111
|
||||||
|
11 1111
|
||||||
|
11
|
||||||
|
|
||||||
|
1111111111111111111111111111 11111111 111111 111111 11111111111111111111111111111111111111111111
|
15
2dkg_zad5/2dgk_zad5/assets/levels/level1_bg.txt
Normal file
15
2dkg_zad5/2dgk_zad5/assets/levels/level1_bg.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3333
|
||||||
|
333344444111
|
||||||
|
3 33144444444411
|
||||||
|
3314444444444444
|
||||||
|
333311444444444444444
|
||||||
|
3333 14444444444444444
|
||||||
|
3 33333 3366666633 14444444444444444
|
||||||
|
33 1144444411 3333 14444444444444444
|
||||||
|
33 11 1144444411 44444444444444444
|
||||||
|
P 11 11 1144444411 44444444444444444
|
||||||
|
3333333333333333333333333333113333333311333333113333331133333333333333333333333333333333333333333333
|
||||||
|
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
|
BIN
2dkg_zad5/2dgk_zad5/assets/textures/P1.bmp
(Stored with Git LFS)
Normal file
BIN
2dkg_zad5/2dgk_zad5/assets/textures/P1.bmp
(Stored with Git LFS)
Normal file
Binary file not shown.
33
2dkg_zad5/2dgk_zad5/config.json
Normal file
33
2dkg_zad5/2dgk_zad5/config.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"Input": {
|
||||||
|
"Player1": {
|
||||||
|
"AxisMappings": [
|
||||||
|
{
|
||||||
|
"AxisName": "MoveX",
|
||||||
|
"Scale": 1.000000,
|
||||||
|
"Key": "D"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AxisName": "MoveX",
|
||||||
|
"Scale": -1.000000,
|
||||||
|
"Key": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AxisName": "MoveX",
|
||||||
|
"Scale": 1.000000,
|
||||||
|
"Key": "Gamepad0_LeftX"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ActionMappings": [
|
||||||
|
{
|
||||||
|
"ActionName": "Jump",
|
||||||
|
"Key": "Space"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ActionName": "Jump",
|
||||||
|
"Key": "Gamepad0_A"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
2dkg_zad5/2dgk_zad5/resource.h
Normal file
14
2dkg_zad5/2dgk_zad5/resource.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by 2dgk_zad5.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
|
11
2dkg_zad5/2dgk_zad5/vcpkg.json
Normal file
11
2dkg_zad5/2dgk_zad5/vcpkg.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
|
||||||
|
"name": "dgk-zad5",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"dependencies": [
|
||||||
|
"sdl2",
|
||||||
|
"nlohmann-json",
|
||||||
|
"sdl2-ttf",
|
||||||
|
"sdl2-image"
|
||||||
|
]
|
||||||
|
}
|
1
2dkg_zad5/assets_src/building.piskel
Normal file
1
2dkg_zad5/assets_src/building.piskel
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"modelVersion":2,"piskel":{"name":"building","description":"","fps":12,"height":32,"width":32,"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAsUlEQVRYR2NsbGz8zzCAgHFQOeDOYzZwWKjI/gLThPgV7ivB6jp2hhOlHt08kCaUECBkIbo81R0wEElhaKUBSoOc4jRAcweMpgFSg5hU9QTTAKkGkqqeoANG0wCpRTGl6imuC6jugNE0QGmQkpotqZ4GKHbAaBqgdpOLUJoimAZIjVNCFo7WBdgSOUXNclKDHD1KCaYBUi0gpJ6gA0bLAVKDkNJyg+Q0QKhcICSPrRwAAKcaoHCrImDsAAAAAElFTkSuQmCC\"}]}"]}}
|
1
2dkg_zad5/assets_src/cloud.piskel
Normal file
1
2dkg_zad5/assets_src/cloud.piskel
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"modelVersion":2,"piskel":{"name":"cloud","description":"","fps":12,"height":32,"width":32,"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAsklEQVRYR+2WwRGAIAwE5WcLVmTNVmQL/nR44ACSSY5g+MQ35HbukmBYwO86jzu/sm57AEsUx6HLtXis5ADaOMQRtOynskdiEQEg4glKCsEC9IgjsZAAWuE6HsqRD8BoYS6SF+AvYc6JYCVM9cV8gEg2w4XkiHkP1E1ZTIGlE2kszQDEe0DTE9L1m09EcxP2RjEMoPXKUVA9oqwDml8s9C77GqIF0fMO4A64A+6AOzDdgQdHX0u4c/gHsgAAAABJRU5ErkJggg==\"}]}"]}}
|
1
2dkg_zad5/assets_src/grass.piskel
Normal file
1
2dkg_zad5/assets_src/grass.piskel
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"modelVersion":2,"piskel":{"name":"grass","description":"","fps":12,"height":32,"width":32,"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAb0lEQVRYR+2T0QnAIAwFzRpO1VE7lWtYIlhE89FgJT/np5iXy6ly11xT4BIAwg3o9e9AXFJkJ+Mt1iAPSG88vl9vvZ5vAHOIBdP3rMZeiDFjAfjzR85GLPijAF+GAQADGMAABjCAAQxgAAMYCDfwANHJNNEYkYYOAAAAAElFTkSuQmCC\"}]}"]}}
|
1
2dkg_zad5/assets_src/ground.piskel
Normal file
1
2dkg_zad5/assets_src/ground.piskel
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"modelVersion":2,"piskel":{"name":"ground","description":"","fps":12,"height":32,"width":32,"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABPElEQVRYR91W2xHCQAg0xWgFtmEF2kx6sQO7sRmdywwZ5JZnEl/+RQ5ugVuWYRzHx0787rer/Gv+Ppwu0Gb5kAPyHc7H/QSAjJFAKGDGj2cwA1BT3tgw8BZUs6hibFX/GABqeRgAf0BrVKoD4AWVL5ifbzbPX2PCXAEvAKIQ+WQYJOO4ADTeWw9PSwbOgcaCyuD5HwA0Ca2Msm2ItIDOhCbhTwHw2CQr3YlROyCDZCqQBoDkWILwAGQvfVFDDUAURPVyqAXWYrJkEZFxeSzIAm20WnqQkWQeP0RDTUiq5X/LRmSJV/cI18jEWjzJhujtqmGlt5qPCQANoMzlfLNGfqjK3U64FESGquoc0JBqfbQ4bvmUAUSBeO0zJ2FWjDIsUndCjvjrAHgc37wCFYqhN6BuxZYKetlnqIsAPAF+tP9L2HSFWAAAAABJRU5ErkJggg==\"}]}"]}}
|
1
2dkg_zad5/assets_src/ground2.piskel
Normal file
1
2dkg_zad5/assets_src/ground2.piskel
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"modelVersion":2,"piskel":{"name":"ground2","description":"","fps":12,"height":32,"width":32,"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABN0lEQVRYR91WyRHDMAiUC/XPTaQCN5FfCk1GmcFD0HLazpWfg0ALaFmmeVnvTfxu14v8a/uelxXaLB9yQL5Ta+0JgIyRQChgxo9nsAFQUz7ZMPEWVLOoYuxV/xgAankYAH9AR1RqAOAFlS+Yn+82z19jwlYBLwCiEPlkGCTjuAA03lsPT0sGzoHOgsrg+R8ANAmtjLJtiLSAzoQm4U8B8NgkKz2IUT8gg2QqkAaA5FiC8ABkL31RQw1AFET1cqgF1mKyZxGRcXksyAJttFp6kJFkHj9EQ01IquV/y0ZkidfwCI/IxFo8yYbo7aphpbeajwkADaDM5XyzRn6oysNOuBdEhqrqHNCQan20OG75lAFEgXjtMydhVowyLFJ3Qo746wB4HD+9AhWKoTegbsWWCnrZZ6iLADwAcfPzMd769scAAAAASUVORK5CYII=\"}]}"]}}
|
BIN
2dkg_zad5/assets_src/maptiles.psd
(Stored with Git LFS)
Normal file
BIN
2dkg_zad5/assets_src/maptiles.psd
(Stored with Git LFS)
Normal file
Binary file not shown.
1
2dkg_zad5/assets_src/mountain.piskel
Normal file
1
2dkg_zad5/assets_src/mountain.piskel
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"modelVersion":2,"piskel":{"name":"mountain","description":"","fps":12,"height":32,"width":32,"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAANElEQVRYR+3QQREAAAQAQcJooI3+OYjhs5fgZnO6Nh5LAwQIECBAgAABAgQIECBAgMC3wAGoHDaB0QshaAAAAABJRU5ErkJggg==\"}]}"]}}
|
1
2dkg_zad5/assets_src/mountain2.piskel
Normal file
1
2dkg_zad5/assets_src/mountain2.piskel
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"modelVersion":2,"piskel":{"name":"mountain2","description":"","fps":12,"height":32,"width":32,"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+WXyQ2AIBBFpR3L8myhtmQ8aCAhMQjM+jFRC+D9ZVgM0+Bv3+bzjgyj+CU4c+ECWuB/CKDcxxSgFfQELOuRWoAJaMEzGDoDHOevCCjdQyrgRg9LoCag5hwiQOretQIN/DsCJNuuvPxcDiJt/C4VWOAwAb1t51qB1b0pAcvgmZ5k1B0viV+VgJdz8VFMOY8LSt2zE6DgGrAoAe/Y2UOIdE4mMALenIFR8IcACqyd9N7vX+BA8wKWaW+JYAtAwFMFnARQ8CjgApWjjZRhAQvBAAAAAElFTkSuQmCC\"}]}"]}}
|
1
2dkg_zad5/assets_src/mountain3.piskel
Normal file
1
2dkg_zad5/assets_src/mountain3.piskel
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"modelVersion":2,"piskel":{"name":"mountain3","description":"","fps":12,"height":32,"width":32,"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAWklEQVRYR2P8eULrPwMBkJTzm5ASsuUZB7UDaOlzWJBhDQF6WIzTAfS0HOQIxmgTVYKJkOwURoTGUQeMhsBoCIyGwGgIjIbAaAiMhsBoCIyGwGgIjIbAaAgAAGaSRYF+p7PUAAAAAElFTkSuQmCC\"}]}"]}}
|
16
2dkg_zad5/readme.txt
Normal file
16
2dkg_zad5/readme.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
IDE: Microsoft Visual Studio 2022
|
||||||
|
Kompilator: Microsoft Visual C++
|
||||||
|
Biblioteki: SDL2, SDL2_ttf, nlohmann-json
|
||||||
|
|
||||||
|
Przetestowane pady: DualSense, DualShock 3 (ze sterownikiem/wrapperem XInputowym ScpToolkit), telefon Android (ze sterownikiem/wrapperem XInputowym HandyGamePad).
|
||||||
|
|
||||||
|
Sterowanie (możliwa zmiana w config.json):
|
||||||
|
AD/lewa gałka pada - ruch poziomy
|
||||||
|
Spacja/A na padzie - skok
|
||||||
|
|
||||||
|
F1 - tryb deweloperski
|
||||||
|
F2 (w trybie deweloperskim) - wł./wył. kolizji
|
||||||
|
F3/F4 - (w trybie deweloperskim) - zwiększ/zmiejsz maksymalną wysokość skoku.
|
||||||
|
F5/F6 - (w trybie deweloperskim) - zwiększ/zmiejsz maksymalną odległość poziomą skoku
|
||||||
|
|
||||||
|
Uwaga: Do pobrania bibliotek projekt wykorzystuje vcpkg, menedżer bibliotek C++, w trybie Manifest. Należy go pobrać i skonfigurować zgodnie z instrukcją: https://github.com/microsoft/vcpkg#getting-started
|
Loading…
x
Reference in New Issue
Block a user