Add project files.
This commit is contained in:
parent
0e2ae1bf70
commit
a6301c6f6e
31
olcCodeJam2023Entry.sln
Normal file
31
olcCodeJam2023Entry.sln
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.5.33516.290
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "olcCodeJam2023Entry", "olcCodeJam2023Entry\olcCodeJam2023Entry.vcxproj", "{FA5243BE-6446-44B1-ADE6-EB26118F6B3E}"
|
||||||
|
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
|
||||||
|
{FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Release|x64.Build.0 = Release|x64
|
||||||
|
{FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {59D77397-F63B-47B2-B936-7BB19452CD50}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
32
olcCodeJam2023Entry/VirusAttack.cpp
Normal file
32
olcCodeJam2023Entry/VirusAttack.cpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#define OLC_PGE_APPLICATION
|
||||||
|
#include "olcPixelGameEngine.h"
|
||||||
|
#define OLC_SOUNDWAVE
|
||||||
|
#include "olcSoundWaveEngine.h"
|
||||||
|
#include "VirusAttack.h"
|
||||||
|
|
||||||
|
VirusAttack::VirusAttack()
|
||||||
|
{
|
||||||
|
// Name your application
|
||||||
|
sAppName = "olcCodeJam 2023 Entry";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirusAttack::OnUserCreate(){
|
||||||
|
// Called once at the start, so create things here
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirusAttack::OnUserUpdate(float fElapsedTime){
|
||||||
|
// Called once per frame, draws random coloured pixels
|
||||||
|
for (int x = 0; x < ScreenWidth(); x++)
|
||||||
|
for (int y = 0; y < ScreenHeight(); y++)
|
||||||
|
Draw(x, y, olc::Pixel(rand() % 256, rand() % 256, rand() % 256));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
VirusAttack app;
|
||||||
|
if (app.Construct(256, 240, 4, 4))
|
||||||
|
app.Start();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
13
olcCodeJam2023Entry/VirusAttack.h
Normal file
13
olcCodeJam2023Entry/VirusAttack.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "olcPixelGameEngine.h"
|
||||||
|
#include "olcSoundWaveEngine.h"
|
||||||
|
|
||||||
|
class VirusAttack : public olc::PixelGameEngine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VirusAttack();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool OnUserCreate() override;
|
||||||
|
|
||||||
|
bool OnUserUpdate(float fElapsedTime) override;
|
||||||
|
};
|
||||||
BIN
olcCodeJam2023Entry/assets/MAINICON.ico
Normal file
BIN
olcCodeJam2023Entry/assets/MAINICON.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 766 B |
BIN
olcCodeJam2023Entry/assets/Vast Horizons.wav
Normal file
BIN
olcCodeJam2023Entry/assets/Vast Horizons.wav
Normal file
Binary file not shown.
2
olcCodeJam2023Entry/emscripten_build.ps1
Normal file
2
olcCodeJam2023Entry/emscripten_build.ps1
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
~\Documents\emsdk\emsdk_env.ps1 activate latest
|
||||||
|
em++ -std=c++20 -gsource-map -s ALLOW_MEMORY_GROWTH=1 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_LIBPNG=1 -s USE_SDL_MIXER=2 $(Get-ChildItem *.cpp) -o pge.html --preload-file assets
|
||||||
BIN
olcCodeJam2023Entry/icon.png
Normal file
BIN
olcCodeJam2023Entry/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 610 B |
BIN
olcCodeJam2023Entry/olcCodeJam2023Entry.rc
Normal file
BIN
olcCodeJam2023Entry/olcCodeJam2023Entry.rc
Normal file
Binary file not shown.
158
olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj
Normal file
158
olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
<?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>{fa5243be-6446-44b1-ade6-eb26118f6b3e}</ProjectGuid>
|
||||||
|
<RootNamespace>olcCodeJam2023Entry</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" />
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</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>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</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>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="olcPGEX_PopUpMenu.h" />
|
||||||
|
<ClInclude Include="olcPGEX_QuickGUI.h" />
|
||||||
|
<ClInclude Include="olcPGEX_SplashScreen.h" />
|
||||||
|
<ClInclude Include="olcPGEX_TransformedView.h" />
|
||||||
|
<ClInclude Include="olcPixelGameEngine.h" />
|
||||||
|
<ClInclude Include="olcSoundWaveEngine.h" />
|
||||||
|
<ClInclude Include="olcUTIL_Camera2D.h" />
|
||||||
|
<ClInclude Include="olcUTIL_Geometry2D.h" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
<ClInclude Include="resource1.h" />
|
||||||
|
<ClInclude Include="VirusAttack.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="VirusAttack.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="olcCodeJam2023Entry.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="assets\MAINICON.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
67
olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj.filters
Normal file
67
olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj.filters
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?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>
|
||||||
|
<ClInclude Include="olcPixelGameEngine.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="olcSoundWaveEngine.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="olcPGEX_PopUpMenu.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="olcPGEX_QuickGUI.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="olcPGEX_SplashScreen.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="olcPGEX_TransformedView.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="olcUTIL_Camera2D.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="olcUTIL_Geometry2D.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="resource.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="resource1.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="VirusAttack.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="VirusAttack.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="olcCodeJam2023Entry.rc">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="assets\MAINICON.ico">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</Image>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
585
olcCodeJam2023Entry/olcPGEX_PopUpMenu.h
Normal file
585
olcCodeJam2023Entry/olcPGEX_PopUpMenu.h
Normal file
@ -0,0 +1,585 @@
|
|||||||
|
/*
|
||||||
|
olcPGEX_PopUp.h
|
||||||
|
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
| OneLoneCoder Pixel Game Engine Extension |
|
||||||
|
| Retro PopUp Menu 1.0 |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|
||||||
|
What is this?
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
This is an extension to the olcPixelGameEngine, which provides
|
||||||
|
a quick and easy to use, flexible, skinnable context pop-up
|
||||||
|
menu system.
|
||||||
|
|
||||||
|
License (OLC-3)
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Copyright 2018 - 2020 OneLoneCoder.com
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions or derivations of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions or derivative works in binary form must reproduce
|
||||||
|
the above copyright notice. This list of conditions and the following
|
||||||
|
disclaimer must be reproduced in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
Links
|
||||||
|
~~~~~
|
||||||
|
YouTube: https://www.youtube.com/javidx9
|
||||||
|
Discord: https://discord.gg/WhwHUMV
|
||||||
|
Twitter: https://www.twitter.com/javidx9
|
||||||
|
Twitch: https://www.twitch.tv/javidx9
|
||||||
|
GitHub: https://www.github.com/onelonecoder
|
||||||
|
Homepage: https://www.onelonecoder.com
|
||||||
|
|
||||||
|
Author
|
||||||
|
~~~~~~
|
||||||
|
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Example
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
#define OLC_PGEX_POPUPMENU
|
||||||
|
#include "olcPGEX_PopUpMenu.h"
|
||||||
|
|
||||||
|
NOTE: Requires a 9-patch sprite, by default each patch is
|
||||||
|
8x8 pixels, patches are as follows:
|
||||||
|
|
||||||
|
| PANEL TL | PANEL T | PANEL TR | SCROLL UP | CURSOR TL | CURSOR TR |
|
||||||
|
| PANEL L | PANEL M | PANEL R | SUBMENU | CURSOR BL | CURSOR BR |
|
||||||
|
| PANEL BL | PANEL B | PANEL BR | SCROLL DOWN | UNUSED | UNUSED |
|
||||||
|
|
||||||
|
You can find an example sprite here:
|
||||||
|
https://github.com/OneLoneCoder/olcPixelGameEngine/blob/master/Videos/RetroMenu.png
|
||||||
|
|
||||||
|
Constructing A Menu
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Declaration (presumably inside class)
|
||||||
|
olc::popup::Menu m;
|
||||||
|
|
||||||
|
// Construction (root menu is a 1x5 table)
|
||||||
|
m.SetTable(1, 5);
|
||||||
|
|
||||||
|
// Add first item to root menu (A 1x5 submenu)
|
||||||
|
m["Menu1"].SetTable(1, 5);
|
||||||
|
|
||||||
|
// Add items to first item
|
||||||
|
m["Menu1"]["Item1"];
|
||||||
|
m["Menu1"]["Item2"];
|
||||||
|
|
||||||
|
// Add a 4x3 submenu
|
||||||
|
m["Menu1"]["Item3"].SetTable(4, 3);
|
||||||
|
m["Menu1"]["Item3"]["Option1"];
|
||||||
|
m["Menu1"]["Item3"]["Option2"];
|
||||||
|
|
||||||
|
// Set properties of specific item
|
||||||
|
m["Menu1"]["Item3"]["Option3"].Enable(false);
|
||||||
|
m["Menu1"]["Item3"]["Option4"];
|
||||||
|
m["Menu1"]["Item3"]["Option5"];
|
||||||
|
m["Menu1"]["Item4"];
|
||||||
|
|
||||||
|
// Add second item to root menu
|
||||||
|
m["Menu2"].SetTable(3, 3);
|
||||||
|
m["Menu2"]["Item1"];
|
||||||
|
m["Menu2"]["Item2"].SetID(1001).Enable(true);
|
||||||
|
m["Menu2"]["Item3"];
|
||||||
|
|
||||||
|
// Construct the menu structure
|
||||||
|
m.Build();
|
||||||
|
|
||||||
|
|
||||||
|
Displaying a Menu
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Declaration of menu manager (presumably inside class)
|
||||||
|
olc::popup::Manager man;
|
||||||
|
|
||||||
|
// Set the Menu object to the MenuManager (call once per pop)
|
||||||
|
man.Open(&m);
|
||||||
|
|
||||||
|
// Draw Menu at position (30, 30), using "patch sprite"
|
||||||
|
man.Draw(sprGFX, { 30,30 });
|
||||||
|
|
||||||
|
|
||||||
|
Interacting with menu
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Send key events to menu
|
||||||
|
if (GetKey(olc::Key::UP).bPressed) man.OnUp();
|
||||||
|
if (GetKey(olc::Key::DOWN).bPressed) man.OnDown();
|
||||||
|
if (GetKey(olc::Key::LEFT).bPressed) man.OnLeft();
|
||||||
|
if (GetKey(olc::Key::RIGHT).bPressed) man.OnRight();
|
||||||
|
if (GetKey(olc::Key::Z).bPressed) man.OnBack();
|
||||||
|
|
||||||
|
// "Confirm/Action" Key does something, if it returns non-null
|
||||||
|
// then a menu item has been selected. The specific item will
|
||||||
|
// be returned
|
||||||
|
olc::popup::Menu* command = nullptr;
|
||||||
|
if (GetKey(olc::Key::SPACE).bPressed) command = man.OnConfirm();
|
||||||
|
if (command != nullptr)
|
||||||
|
{
|
||||||
|
std::string sLastAction =
|
||||||
|
"Selected: " + command->GetName() +
|
||||||
|
" ID: " + std::to_string(command->GetID());
|
||||||
|
|
||||||
|
// Optionally close menu?
|
||||||
|
man.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OLC_PGEX_POPUPMENU_H
|
||||||
|
#define OLC_PGEX_POPUPMENU_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace olc
|
||||||
|
{
|
||||||
|
namespace popup
|
||||||
|
{
|
||||||
|
constexpr int32_t nPatch = 8;
|
||||||
|
|
||||||
|
class Menu
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Menu();
|
||||||
|
Menu(const std::string n);
|
||||||
|
|
||||||
|
Menu& SetTable(int32_t nColumns, int32_t nRows);
|
||||||
|
Menu& SetID(int32_t id);
|
||||||
|
Menu& Enable(bool b);
|
||||||
|
|
||||||
|
int32_t GetID();
|
||||||
|
std::string& GetName();
|
||||||
|
bool Enabled();
|
||||||
|
bool HasChildren();
|
||||||
|
olc::vi2d GetSize();
|
||||||
|
olc::vi2d& GetCursorPosition();
|
||||||
|
Menu& operator[](const std::string& name);
|
||||||
|
void Build();
|
||||||
|
void DrawSelf(olc::PixelGameEngine& pge, olc::Sprite* sprGFX, olc::vi2d vScreenOffset);
|
||||||
|
void ClampCursor();
|
||||||
|
void OnUp();
|
||||||
|
void OnDown();
|
||||||
|
void OnLeft();
|
||||||
|
void OnRight();
|
||||||
|
Menu* OnConfirm();
|
||||||
|
Menu* GetSelectedItem();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int32_t nID = -1;
|
||||||
|
olc::vi2d vCellTable = { 1, 0 };
|
||||||
|
std::unordered_map<std::string, size_t> itemPointer;
|
||||||
|
std::vector<olc::popup::Menu> items;
|
||||||
|
olc::vi2d vSizeInPatches = { 0, 0 };
|
||||||
|
olc::vi2d vCellSize = { 0, 0 };
|
||||||
|
olc::vi2d vCellPadding = { 2, 0 };
|
||||||
|
olc::vi2d vCellCursor = { 0, 0 };
|
||||||
|
int32_t nCursorItem = 0;
|
||||||
|
int32_t nTopVisibleRow = 0;
|
||||||
|
int32_t nTotalRows = 0;
|
||||||
|
const olc::vi2d vPatchSize = { nPatch, nPatch };
|
||||||
|
std::string sName;
|
||||||
|
olc::vi2d vCursorPos = { 0, 0 };
|
||||||
|
bool bEnabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Manager : public olc::PGEX
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Manager();
|
||||||
|
void Open(Menu* mo);
|
||||||
|
void Close();
|
||||||
|
void OnUp();
|
||||||
|
void OnDown();
|
||||||
|
void OnLeft();
|
||||||
|
void OnRight();
|
||||||
|
void OnBack();
|
||||||
|
Menu* OnConfirm();
|
||||||
|
void Draw(olc::Sprite* sprGFX, olc::vi2d vScreenOffset);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::list<Menu*> panels;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef OLC_PGEX_POPUPMENU
|
||||||
|
#undef OLC_PGEX_POPUPMENU
|
||||||
|
|
||||||
|
namespace olc
|
||||||
|
{
|
||||||
|
namespace popup
|
||||||
|
{
|
||||||
|
Menu::Menu()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu::Menu(const std::string n)
|
||||||
|
{
|
||||||
|
sName = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Menu& Menu::SetTable(int32_t nColumns, int32_t nRows)
|
||||||
|
{
|
||||||
|
vCellTable = { nColumns, nRows };
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu& Menu::SetID(int32_t id)
|
||||||
|
{
|
||||||
|
nID = id;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu& Menu::Enable(bool b)
|
||||||
|
{
|
||||||
|
bEnabled = b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t Menu::GetID()
|
||||||
|
{
|
||||||
|
return nID;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string& Menu::GetName()
|
||||||
|
{
|
||||||
|
return sName;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Menu::Enabled()
|
||||||
|
{
|
||||||
|
return bEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Menu::HasChildren()
|
||||||
|
{
|
||||||
|
return !items.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vi2d Menu::GetSize()
|
||||||
|
{
|
||||||
|
return { int32_t(sName.size()), 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vi2d& Menu::GetCursorPosition()
|
||||||
|
{
|
||||||
|
return vCursorPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu& Menu::operator[](const std::string& name)
|
||||||
|
{
|
||||||
|
if (itemPointer.count(name) == 0)
|
||||||
|
{
|
||||||
|
itemPointer[name] = items.size();
|
||||||
|
items.push_back(Menu(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return items[itemPointer[name]];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Menu::Build()
|
||||||
|
{
|
||||||
|
// Recursively build all children, so they can determine their size, use
|
||||||
|
// that size to indicate cell sizes if this object contains more than
|
||||||
|
// one item
|
||||||
|
for (auto& m : items)
|
||||||
|
{
|
||||||
|
if (m.HasChildren())
|
||||||
|
{
|
||||||
|
m.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Longest child name determines cell width
|
||||||
|
vCellSize.x = std::max(m.GetSize().x, vCellSize.x);
|
||||||
|
vCellSize.y = std::max(m.GetSize().y, vCellSize.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust size of this object (in patches) if it were rendered as a panel
|
||||||
|
vSizeInPatches.x = vCellTable.x * vCellSize.x + (vCellTable.x - 1) * vCellPadding.x + 2;
|
||||||
|
vSizeInPatches.y = vCellTable.y * vCellSize.y + (vCellTable.y - 1) * vCellPadding.y + 2;
|
||||||
|
|
||||||
|
// Calculate how many rows this item has to hold
|
||||||
|
nTotalRows = (items.size() / vCellTable.x) + (((items.size() % vCellTable.x) > 0) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Menu::DrawSelf(olc::PixelGameEngine& pge, olc::Sprite* sprGFX, olc::vi2d vScreenOffset)
|
||||||
|
{
|
||||||
|
// === Draw Panel
|
||||||
|
|
||||||
|
// Record current pixel mode user is using
|
||||||
|
olc::Pixel::Mode currentPixelMode = pge.GetPixelMode();
|
||||||
|
pge.SetPixelMode(olc::Pixel::MASK);
|
||||||
|
|
||||||
|
// Draw Panel & Border
|
||||||
|
olc::vi2d vPatchPos = { 0,0 };
|
||||||
|
for (vPatchPos.x = 0; vPatchPos.x < vSizeInPatches.x; vPatchPos.x++)
|
||||||
|
{
|
||||||
|
for (vPatchPos.y = 0; vPatchPos.y < vSizeInPatches.y; vPatchPos.y++)
|
||||||
|
{
|
||||||
|
// Determine position in screen space
|
||||||
|
olc::vi2d vScreenLocation = vPatchPos * nPatch + vScreenOffset;
|
||||||
|
|
||||||
|
// Calculate which patch is needed
|
||||||
|
olc::vi2d vSourcePatch = { 0, 0 };
|
||||||
|
if (vPatchPos.x > 0) vSourcePatch.x = 1;
|
||||||
|
if (vPatchPos.x == vSizeInPatches.x - 1) vSourcePatch.x = 2;
|
||||||
|
if (vPatchPos.y > 0) vSourcePatch.y = 1;
|
||||||
|
if (vPatchPos.y == vSizeInPatches.y - 1) vSourcePatch.y = 2;
|
||||||
|
|
||||||
|
// Draw Actual Patch
|
||||||
|
pge.DrawPartialSprite(vScreenLocation, sprGFX, vSourcePatch * nPatch, vPatchSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Draw Panel Contents
|
||||||
|
olc::vi2d vCell = { 0,0 };
|
||||||
|
vPatchPos = { 1,1 };
|
||||||
|
|
||||||
|
// Work out visible items
|
||||||
|
int32_t nTopLeftItem = nTopVisibleRow * vCellTable.x;
|
||||||
|
int32_t nBottomRightItem = vCellTable.y * vCellTable.x + nTopLeftItem;
|
||||||
|
|
||||||
|
// Clamp to size of child item vector
|
||||||
|
nBottomRightItem = std::min(int32_t(items.size()), nBottomRightItem);
|
||||||
|
int32_t nVisibleItems = nBottomRightItem - nTopLeftItem;
|
||||||
|
|
||||||
|
// Draw Scroll Markers (if required)
|
||||||
|
if (nTopVisibleRow > 0)
|
||||||
|
{
|
||||||
|
vPatchPos = { vSizeInPatches.x - 2, 0 };
|
||||||
|
olc::vi2d vScreenLocation = vPatchPos * nPatch + vScreenOffset;
|
||||||
|
olc::vi2d vSourcePatch = { 3, 0 };
|
||||||
|
pge.DrawPartialSprite(vScreenLocation, sprGFX, vSourcePatch * nPatch, vPatchSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((nTotalRows - nTopVisibleRow) > vCellTable.y)
|
||||||
|
{
|
||||||
|
vPatchPos = { vSizeInPatches.x - 2, vSizeInPatches.y - 1 };
|
||||||
|
olc::vi2d vScreenLocation = vPatchPos * nPatch + vScreenOffset;
|
||||||
|
olc::vi2d vSourcePatch = { 3, 2 };
|
||||||
|
pge.DrawPartialSprite(vScreenLocation, sprGFX, vSourcePatch * nPatch, vPatchSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw Visible Items
|
||||||
|
for (int32_t i = 0; i < nVisibleItems; i++)
|
||||||
|
{
|
||||||
|
// Cell location
|
||||||
|
vCell.x = i % vCellTable.x;
|
||||||
|
vCell.y = i / vCellTable.x;
|
||||||
|
|
||||||
|
// Patch location (including border offset and padding)
|
||||||
|
vPatchPos.x = vCell.x * (vCellSize.x + vCellPadding.x) + 1;
|
||||||
|
vPatchPos.y = vCell.y * (vCellSize.y + vCellPadding.y) + 1;
|
||||||
|
|
||||||
|
// Actual screen location in pixels
|
||||||
|
olc::vi2d vScreenLocation = vPatchPos * nPatch + vScreenOffset;
|
||||||
|
|
||||||
|
// Display Item Header
|
||||||
|
pge.DrawString(vScreenLocation, items[nTopLeftItem + i].sName, items[nTopLeftItem + i].bEnabled ? olc::WHITE : olc::DARK_GREY);
|
||||||
|
|
||||||
|
if (items[nTopLeftItem + i].HasChildren())
|
||||||
|
{
|
||||||
|
// Display Indicator that panel has a sub panel
|
||||||
|
vPatchPos.x = vCell.x * (vCellSize.x + vCellPadding.x) + 1 + vCellSize.x;
|
||||||
|
vPatchPos.y = vCell.y * (vCellSize.y + vCellPadding.y) + 1;
|
||||||
|
olc::vi2d vSourcePatch = { 3, 1 };
|
||||||
|
vScreenLocation = vPatchPos * nPatch + vScreenOffset;
|
||||||
|
pge.DrawPartialSprite(vScreenLocation, sprGFX, vSourcePatch * nPatch, vPatchSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate cursor position in screen space in case system draws it
|
||||||
|
vCursorPos.x = (vCellCursor.x * (vCellSize.x + vCellPadding.x)) * nPatch + vScreenOffset.x - nPatch;
|
||||||
|
vCursorPos.y = ((vCellCursor.y - nTopVisibleRow) * (vCellSize.y + vCellPadding.y)) * nPatch + vScreenOffset.y + nPatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Menu::ClampCursor()
|
||||||
|
{
|
||||||
|
// Find item in children
|
||||||
|
nCursorItem = vCellCursor.y * vCellTable.x + vCellCursor.x;
|
||||||
|
|
||||||
|
// Clamp Cursor
|
||||||
|
if (nCursorItem >= int32_t(items.size()))
|
||||||
|
{
|
||||||
|
vCellCursor.y = (items.size() / vCellTable.x);
|
||||||
|
vCellCursor.x = (items.size() % vCellTable.x) - 1;
|
||||||
|
nCursorItem = items.size() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Menu::OnUp()
|
||||||
|
{
|
||||||
|
vCellCursor.y--;
|
||||||
|
if (vCellCursor.y < 0) vCellCursor.y = 0;
|
||||||
|
|
||||||
|
if (vCellCursor.y < nTopVisibleRow)
|
||||||
|
{
|
||||||
|
nTopVisibleRow--;
|
||||||
|
if (nTopVisibleRow < 0) nTopVisibleRow = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClampCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Menu::OnDown()
|
||||||
|
{
|
||||||
|
vCellCursor.y++;
|
||||||
|
if (vCellCursor.y == nTotalRows) vCellCursor.y = nTotalRows - 1;
|
||||||
|
|
||||||
|
if (vCellCursor.y > (nTopVisibleRow + vCellTable.y - 1))
|
||||||
|
{
|
||||||
|
nTopVisibleRow++;
|
||||||
|
if (nTopVisibleRow > (nTotalRows - vCellTable.y))
|
||||||
|
nTopVisibleRow = nTotalRows - vCellTable.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClampCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Menu::OnLeft()
|
||||||
|
{
|
||||||
|
vCellCursor.x--;
|
||||||
|
if (vCellCursor.x < 0) vCellCursor.x = 0;
|
||||||
|
ClampCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Menu::OnRight()
|
||||||
|
{
|
||||||
|
vCellCursor.x++;
|
||||||
|
if (vCellCursor.x == vCellTable.x) vCellCursor.x = vCellTable.x - 1;
|
||||||
|
ClampCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu* Menu::OnConfirm()
|
||||||
|
{
|
||||||
|
// Check if selected item has children
|
||||||
|
if (items[nCursorItem].HasChildren())
|
||||||
|
{
|
||||||
|
return &items[nCursorItem];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu* Menu::GetSelectedItem()
|
||||||
|
{
|
||||||
|
return &items[nCursorItem];
|
||||||
|
}
|
||||||
|
|
||||||
|
// =====================================================================
|
||||||
|
|
||||||
|
Manager::Manager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::Open(Menu* mo)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
panels.push_back(mo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::Close()
|
||||||
|
{
|
||||||
|
panels.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::OnUp()
|
||||||
|
{
|
||||||
|
if (!panels.empty()) panels.back()->OnUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::OnDown()
|
||||||
|
{
|
||||||
|
if (!panels.empty()) panels.back()->OnDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::OnLeft()
|
||||||
|
{
|
||||||
|
if (!panels.empty()) panels.back()->OnLeft();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::OnRight()
|
||||||
|
{
|
||||||
|
if (!panels.empty()) panels.back()->OnRight();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::OnBack()
|
||||||
|
{
|
||||||
|
if (!panels.empty()) panels.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu* Manager::OnConfirm()
|
||||||
|
{
|
||||||
|
if (panels.empty()) return nullptr;
|
||||||
|
|
||||||
|
Menu* next = panels.back()->OnConfirm();
|
||||||
|
if (next == panels.back())
|
||||||
|
{
|
||||||
|
if (panels.back()->GetSelectedItem()->Enabled())
|
||||||
|
return panels.back()->GetSelectedItem();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (next->Enabled())
|
||||||
|
panels.push_back(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::Draw(olc::Sprite* sprGFX, olc::vi2d vScreenOffset)
|
||||||
|
{
|
||||||
|
if (panels.empty()) return;
|
||||||
|
|
||||||
|
// Draw Visible Menu System
|
||||||
|
for (auto& p : panels)
|
||||||
|
{
|
||||||
|
p->DrawSelf(*pge, sprGFX, vScreenOffset);
|
||||||
|
vScreenOffset += {10, 10};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw Cursor
|
||||||
|
olc::Pixel::Mode currentPixelMode = pge->GetPixelMode();
|
||||||
|
pge->SetPixelMode(olc::Pixel::ALPHA);
|
||||||
|
pge->DrawPartialSprite(panels.back()->GetCursorPosition(), sprGFX, olc::vi2d(4, 0) * nPatch, { nPatch * 2, nPatch * 2 });
|
||||||
|
pge->SetPixelMode(currentPixelMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
1170
olcCodeJam2023Entry/olcPGEX_QuickGUI.h
Normal file
1170
olcCodeJam2023Entry/olcPGEX_QuickGUI.h
Normal file
File diff suppressed because it is too large
Load Diff
220
olcCodeJam2023Entry/olcPGEX_SplashScreen.h
Normal file
220
olcCodeJam2023Entry/olcPGEX_SplashScreen.h
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
olcPGEX_SplashScreen.h
|
||||||
|
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
| OneLoneCoder Pixel Game Engine Extension |
|
||||||
|
| Splash Screen v1.0 |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|
||||||
|
NOTE: UNDER ACTIVE DEVELOPMENT - THERE ARE BUGS/GLITCHES
|
||||||
|
|
||||||
|
What is this?
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
This extension produces an animated splashscreen and copyright notice
|
||||||
|
at the beginning of a PGE application, for the purposes of remaining
|
||||||
|
OLC-3 compliant should it be ambiguous in your deployment.
|
||||||
|
|
||||||
|
License (OLC-3)
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Copyright 2018 - 2022 OneLoneCoder.com
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions or derivations of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions or derivative works in binary form must reproduce
|
||||||
|
the above copyright notice. This list of conditions and the following
|
||||||
|
disclaimer must be reproduced in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
Links
|
||||||
|
~~~~~
|
||||||
|
YouTube: https://www.youtube.com/javidx9
|
||||||
|
Discord: https://discord.gg/WhwHUMV
|
||||||
|
Twitter: https://www.twitter.com/javidx9
|
||||||
|
Twitch: https://www.twitch.tv/javidx9
|
||||||
|
GitHub: https://www.github.com/onelonecoder
|
||||||
|
Homepage: https://www.onelonecoder.com
|
||||||
|
|
||||||
|
Author
|
||||||
|
~~~~~~
|
||||||
|
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020, 2021, 2022
|
||||||
|
|
||||||
|
Revisions:
|
||||||
|
1.00: Initial Release
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "olcPixelGameEngine.h"
|
||||||
|
|
||||||
|
namespace olc
|
||||||
|
{
|
||||||
|
class SplashScreen : public olc::PGEX
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SplashScreen();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void OnAfterUserCreate() override;
|
||||||
|
virtual bool OnBeforeUserUpdate(float& fElapsedTime) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
olc::Renderable spr;
|
||||||
|
std::vector<std::pair<olc::vf2d, olc::vf2d>> vBoom;
|
||||||
|
olc::vf2d vScale;
|
||||||
|
olc::vf2d vPosition;
|
||||||
|
float fParticleTime = 0.0f;
|
||||||
|
float fAspect = 0.0f;
|
||||||
|
bool bComplete = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OLC_PGEX_SPLASHSCREEN
|
||||||
|
#undef OLC_PGEX_SPLASHSCREEN
|
||||||
|
|
||||||
|
namespace olc
|
||||||
|
{
|
||||||
|
SplashScreen::SplashScreen() : olc::PGEX(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplashScreen::OnAfterUserCreate()
|
||||||
|
{
|
||||||
|
const char logo[] =
|
||||||
|
"000000000000000000000000000000000000000000000000000000000000000000005"
|
||||||
|
"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED1EE"
|
||||||
|
"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED5EEE"
|
||||||
|
"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE@E@000"
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000001E1D:ZZZZ"
|
||||||
|
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ1D5BZZZZZZ"
|
||||||
|
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ5@E:P0002Z0"
|
||||||
|
"02ZZX000000000000ZP0000000000000000000000000000ZX000Z002XE1DX?o`o:Poo"
|
||||||
|
"800SooaE5@E1ED5BX?ol5E@E0E1ED?oo5@E1ED5DE1D5E@ZQEEBPEE2QD5BSooclZ?olQ"
|
||||||
|
"AB?oo5DEEDEEDE:SooaEEAE5DEEDoolEADEEDEAE5AEEBZ5EE:5EE:5@E:?oo?bXoob55"
|
||||||
|
"8o3lEAEEAD5ADZ?oo5@E5EEAD5Cl01E5AD5AE5DE5@E:X01DXEEDXE1DXo3lo:Sl0800S"
|
||||||
|
"ooaE1ED5EE5BXo00EEDEEE5EE?oo5EE5EE5DEEDEEDZQEEBQD5BQD5BSl?cl0?`0ZZZ?o"
|
||||||
|
"o5D5E@EEDE03loaEEAEEDEEDoolEED5EDEAEEAEEBZ5EE:5@E:5@E:?oo?oloob008o00"
|
||||||
|
"EAEEAD01EE?co5EE5EEAD03l01DE@05AE5AE5@0:XE000EEDXE1DXooloocoo8DDSlZQE"
|
||||||
|
"5EE5EE5EDoolE1DE4E5EE?oo5AE5EE5DE5DEEDZQEEAAEEBQD5BPoo3oo3olQAB?bZ5DE"
|
||||||
|
"1D5EDEE@ooaD5AD1D5EDoolE1DEE@EAD5@EEBZ5EE51ED:5@E:P000000020080:X0000"
|
||||||
|
"00000000000000000000000000000000000:X0000002XE1DZZZZZZZZZZZZZZZZZZZZZ"
|
||||||
|
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZQD5@ZZZZZZZZZZZZZZZZZZZZZZ"
|
||||||
|
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZX5@E@00000000000000000000000"
|
||||||
|
"00000000000000000000000000000000000000001E1EEEEEEEEEEEEEEEEEEEEEEEEEE"
|
||||||
|
"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED5EEEEEEEEEEEEEEEEEEEEEEEEEEE"
|
||||||
|
"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE@5EEEEEEEEEEEEEEEEEEEEEEEEEEEE"
|
||||||
|
"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED0000000000000000000000000000000"
|
||||||
|
"0000000000000000000000000000000000000";
|
||||||
|
|
||||||
|
spr.Create(203, 24);
|
||||||
|
int px = 0, py = 0;
|
||||||
|
for (size_t b = 0; b < 1624; b += 4)
|
||||||
|
{
|
||||||
|
uint32_t sym1 = (uint32_t)logo[b + 0] - 48;
|
||||||
|
uint32_t sym2 = (uint32_t)logo[b + 1] - 48;
|
||||||
|
uint32_t sym3 = (uint32_t)logo[b + 2] - 48;
|
||||||
|
uint32_t sym4 = (uint32_t)logo[b + 3] - 48;
|
||||||
|
uint32_t r = sym1 << 18 | sym2 << 12 | sym3 << 6 | sym4;
|
||||||
|
|
||||||
|
for (int i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
olc::Pixel p = olc::RED;
|
||||||
|
switch ((r & 0xC00000) >> 22)
|
||||||
|
{
|
||||||
|
case 0: p = olc::Pixel(0, 0, 0, 255); break;
|
||||||
|
case 1: p = olc::Pixel(255, 255, 255, 255); break;
|
||||||
|
case 2: p = olc::Pixel(255, 120, 26, 255); break;
|
||||||
|
case 3: p = olc::Pixel(79, 193, 255, 255); break;
|
||||||
|
}
|
||||||
|
spr.Sprite()->SetPixel(px, py, p);
|
||||||
|
if (++px == 203) { py++; px = 0; }
|
||||||
|
r <<= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spr.Decal()->Update();
|
||||||
|
vBoom.resize(spr.Sprite()->width * spr.Sprite()->height);
|
||||||
|
vScale = { float(pge->ScreenWidth()) / 500.0f, float(pge->ScreenWidth()) / 500.0f };
|
||||||
|
fAspect = float(pge->ScreenWidth()) / float(pge->ScreenHeight());
|
||||||
|
vPosition = olc::vf2d(
|
||||||
|
(250 - spr.Sprite()->width) / 2.0f,
|
||||||
|
(250 - spr.Sprite()->height) / 2.0f / fAspect);
|
||||||
|
for (int y = 0; y < spr.Sprite()->height; y++)
|
||||||
|
for (int x = 0; x < spr.Sprite()->width; x++)
|
||||||
|
vBoom[y * spr.Sprite()->width + x] = std::make_pair(
|
||||||
|
vPosition + olc::vf2d(x, y),
|
||||||
|
olc::vf2d(
|
||||||
|
(float(rand()) / float(RAND_MAX)) * 10.0f - 5.0f,
|
||||||
|
(float(rand()) / float(RAND_MAX)) * 10.0f - 5.0f)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SplashScreen::OnBeforeUserUpdate(float& fElapsedTime)
|
||||||
|
{
|
||||||
|
if (bComplete) return false;
|
||||||
|
|
||||||
|
fParticleTime += fElapsedTime;
|
||||||
|
|
||||||
|
for (int y = 0; y < spr.Sprite()->height; y++)
|
||||||
|
for (int x = 0; x < spr.Sprite()->width; x++)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (fParticleTime < 1.0f)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (fParticleTime < 2.0f)
|
||||||
|
{
|
||||||
|
vBoom[y * spr.Sprite()->width + x].first =
|
||||||
|
olc::vf2d(
|
||||||
|
(250 - spr.Sprite()->width) / 2.0f + float(x),
|
||||||
|
(250 - spr.Sprite()->height) / 2.0f / fAspect + float(y)
|
||||||
|
) +
|
||||||
|
olc::vf2d(
|
||||||
|
(float(rand()) / float(RAND_MAX)) * 0.5f - 0.25f,
|
||||||
|
(float(rand()) / float(RAND_MAX)) * 0.5f - 0.25f);
|
||||||
|
}
|
||||||
|
else if(fParticleTime < 5.0f)
|
||||||
|
{
|
||||||
|
vBoom[y * spr.Sprite()->width + x].first += vBoom[y * spr.Sprite()->width + x].second * fElapsedTime * 20.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bComplete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pge->DrawPartialDecal(vScale * vBoom[y * spr.Sprite()->width + x].first * 2.0f, spr.Decal(), olc::vf2d(x, y), { 1, 1 }, vScale * 2.0f, olc::PixelF(1.0f, 1.0f, 1.0f, std::min(1.0f, std::max(4.0f - fParticleTime, 0.0f))));
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vi2d vSize = pge->GetTextSizeProp("Copyright OneLoneCoder.com 2022");
|
||||||
|
pge->DrawStringPropDecal(olc::vf2d(float(pge->ScreenWidth()/2) - vSize.x/2, float(pge->ScreenHeight()) - vSize.y * 3.0f), "Copyright OneLoneCoder.com 2022", olc::PixelF(1.0f, 1.0f, 1.0f, 0.5f), olc::vf2d(1.0, 2.0f));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
746
olcCodeJam2023Entry/olcPGEX_TransformedView.h
Normal file
746
olcCodeJam2023Entry/olcPGEX_TransformedView.h
Normal file
@ -0,0 +1,746 @@
|
|||||||
|
/*
|
||||||
|
olcPGEX_TransformedView.h
|
||||||
|
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
| OneLoneCoder Pixel Game Engine Extension |
|
||||||
|
| Transformed View v1.08 |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
|
||||||
|
NOTE: UNDER ACTIVE DEVELOPMENT - THERE ARE BUGS/GLITCHES
|
||||||
|
|
||||||
|
What is this?
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
This extension provides drawing routines that are compatible with
|
||||||
|
changeable world and screen spaces. For example you can pan and
|
||||||
|
zoom, and all PGE drawing routines will automatically adopt the current
|
||||||
|
world scales and offsets.
|
||||||
|
|
||||||
|
License (OLC-3)
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Copyright 2018 - 2022 OneLoneCoder.com
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions or derivations of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions or derivative works in binary form must reproduce
|
||||||
|
the above copyright notice. This list of conditions and the following
|
||||||
|
disclaimer must be reproduced in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
Links
|
||||||
|
~~~~~
|
||||||
|
YouTube: https://www.youtube.com/javidx9
|
||||||
|
Discord: https://discord.gg/WhwHUMV
|
||||||
|
Twitter: https://www.twitter.com/javidx9
|
||||||
|
Twitch: https://www.twitch.tv/javidx9
|
||||||
|
GitHub: https://www.github.com/onelonecoder
|
||||||
|
Homepage: https://www.onelonecoder.com
|
||||||
|
|
||||||
|
Author
|
||||||
|
~~~~~~
|
||||||
|
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020, 2021, 2022
|
||||||
|
|
||||||
|
Revisions:
|
||||||
|
1.00: Initial Release
|
||||||
|
1.01: Fix for rounding error when scaling to screen
|
||||||
|
1.02: Added DrawLineDecal for convenience
|
||||||
|
1.03: Removed std::floor from WorldToScreen()
|
||||||
|
Added HandlePanAndZoom(...) convenience function
|
||||||
|
Removed unused "range" facility in TileTransformView
|
||||||
|
1.04: Added DrawPolygonDecal() for arbitrary polygons
|
||||||
|
1.05: Clipped DrawSprite() to visible area, massive performance increase
|
||||||
|
1.06: Fixed error in DrawLine() - Thanks CraisyDaisyRecords (& Fern)!
|
||||||
|
1.07: +DrawRectDecal()
|
||||||
|
+GetPGE()
|
||||||
|
1.08: +DrawPolygonDecal() with tint overload, akin to PGE
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef OLC_PGEX_TRANSFORMEDVIEW_H
|
||||||
|
#define OLC_PGEX_TRANSFORMEDVIEW_H
|
||||||
|
|
||||||
|
#include "olcPixelGameEngine.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace olc
|
||||||
|
{
|
||||||
|
class TransformedView : public olc::PGEX
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TransformedView() = default;
|
||||||
|
virtual void Initialise(const olc::vi2d& vViewArea, const olc::vf2d& vPixelScale = { 1.0f, 1.0f });
|
||||||
|
|
||||||
|
olc::PixelGameEngine* GetPGE();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void SetWorldOffset(const olc::vf2d& vOffset);
|
||||||
|
void MoveWorldOffset(const olc::vf2d& vDeltaOffset);
|
||||||
|
void SetWorldScale(const olc::vf2d& vScale);
|
||||||
|
void SetViewArea(const olc::vi2d& vViewArea);
|
||||||
|
olc::vf2d GetWorldTL() const;
|
||||||
|
olc::vf2d GetWorldBR() const;
|
||||||
|
olc::vf2d GetWorldVisibleArea() const;
|
||||||
|
void ZoomAtScreenPos(const float fDeltaZoom, const olc::vi2d& vPos);
|
||||||
|
void SetZoom(const float fZoom, const olc::vf2d& vPos);
|
||||||
|
void StartPan(const olc::vi2d& vPos);
|
||||||
|
void UpdatePan(const olc::vi2d& vPos);
|
||||||
|
void EndPan(const olc::vi2d& vPos);
|
||||||
|
const olc::vf2d& GetWorldOffset() const;
|
||||||
|
const olc::vf2d& GetWorldScale() const;
|
||||||
|
virtual olc::vf2d WorldToScreen(const olc::vf2d& vWorldPos) const;
|
||||||
|
virtual olc::vf2d ScreenToWorld(const olc::vf2d& vScreenPos) const;
|
||||||
|
virtual olc::vf2d ScaleToWorld(const olc::vf2d& vScreenSize) const;
|
||||||
|
virtual olc::vf2d ScaleToScreen(const olc::vf2d& vWorldSize) const;
|
||||||
|
virtual bool IsPointVisible(const olc::vf2d& vPos) const;
|
||||||
|
virtual bool IsRectVisible(const olc::vf2d& vPos, const olc::vf2d& vSize) const;
|
||||||
|
virtual void HandlePanAndZoom(const int nMouseButton = 2, const float fZoomRate = 0.1f, const bool bPan = true, const bool bZoom = true);
|
||||||
|
protected:
|
||||||
|
olc::vf2d m_vWorldOffset = { 0.0f, 0.0f };
|
||||||
|
olc::vf2d m_vWorldScale = { 1.0f, 1.0f };
|
||||||
|
olc::vf2d m_vRecipPixel = { 1.0f, 1.0f };
|
||||||
|
olc::vf2d m_vPixelScale = { 1.0f, 1.0f };
|
||||||
|
bool m_bPanning = false;
|
||||||
|
olc::vf2d m_vStartPan = { 0.0f, 0.0f };
|
||||||
|
olc::vi2d m_vViewArea;
|
||||||
|
|
||||||
|
public: // Hopefully, these should look familiar!
|
||||||
|
// Plots a single point
|
||||||
|
virtual bool Draw(float x, float y, olc::Pixel p = olc::WHITE);
|
||||||
|
bool Draw(const olc::vf2d& pos, olc::Pixel p = olc::WHITE);
|
||||||
|
// Draws a line from (x1,y1) to (x2,y2)
|
||||||
|
void DrawLine(float x1, float y1, float x2, float y2, olc::Pixel p = olc::WHITE, uint32_t pattern = 0xFFFFFFFF);
|
||||||
|
void DrawLine(const olc::vf2d& pos1, const olc::vf2d& pos2, olc::Pixel p = olc::WHITE, uint32_t pattern = 0xFFFFFFFF);
|
||||||
|
// Draws a circle located at (x,y) with radius
|
||||||
|
void DrawCircle(float x, float y, float radius, olc::Pixel p = olc::WHITE, uint8_t mask = 0xFF);
|
||||||
|
void DrawCircle(const olc::vf2d& pos, float radius, olc::Pixel p = olc::WHITE, uint8_t mask = 0xFF);
|
||||||
|
// Fills a circle located at (x,y) with radius
|
||||||
|
void FillCircle(float x, float y, float radius, olc::Pixel p = olc::WHITE);
|
||||||
|
void FillCircle(const olc::vf2d& pos, float radius, olc::Pixel p = olc::WHITE);
|
||||||
|
// Draws a rectangle at (x,y) to (x+w,y+h)
|
||||||
|
void DrawRect(float x, float y, float w, float h, olc::Pixel p = olc::WHITE);
|
||||||
|
void DrawRect(const olc::vf2d& pos, const olc::vf2d& size, olc::Pixel p = olc::WHITE);
|
||||||
|
// Fills a rectangle at (x,y) to (x+w,y+h)
|
||||||
|
void FillRect(float x, float y, float w, float h, olc::Pixel p = olc::WHITE);
|
||||||
|
void FillRect(const olc::vf2d& pos, const olc::vf2d& size, olc::Pixel p = olc::WHITE);
|
||||||
|
// Draws a triangle between points (x1,y1), (x2,y2) and (x3,y3)
|
||||||
|
void DrawTriangle(float x1, float y1, float x2, float y2, float x3, float y3, olc::Pixel p = olc::WHITE);
|
||||||
|
void DrawTriangle(const olc::vf2d& pos1, const olc::vf2d& pos2, const olc::vf2d& pos3, olc::Pixel p = olc::WHITE);
|
||||||
|
// Flat fills a triangle between points (x1,y1), (x2,y2) and (x3,y3)
|
||||||
|
void FillTriangle(float x1, float y1, float x2, float y2, float x3, float y3, olc::Pixel p = olc::WHITE);
|
||||||
|
void FillTriangle(const olc::vf2d& pos1, const olc::vf2d& pos2, const olc::vf2d& pos3, olc::Pixel p = olc::WHITE);
|
||||||
|
// Draws an entire sprite at location (x,y)
|
||||||
|
void DrawSprite(float x, float y, olc::Sprite* sprite, float scalex = 1, float scaley = 1, uint8_t flip = olc::Sprite::NONE);
|
||||||
|
void DrawSprite(const olc::vf2d& pos, olc::Sprite* sprite, const olc::vf2d& scale = { 1.0f, 1.0f }, uint8_t flip = olc::Sprite::NONE);
|
||||||
|
// Draws an area of a sprite at location (x,y), where the
|
||||||
|
// selected area is (ox,oy) to (ox+w,oy+h)
|
||||||
|
void DrawPartialSprite(float x, float y, Sprite* sprite, int32_t ox, int32_t oy, int32_t w, int32_t h, float scalex = 1, float scaley = 1, uint8_t flip = olc::Sprite::NONE);
|
||||||
|
void DrawPartialSprite(const olc::vf2d& pos, Sprite* sprite, const olc::vi2d& sourcepos, const olc::vi2d& size, const olc::vf2d& scale = { 1.0f, 1.0f }, uint8_t flip = olc::Sprite::NONE);
|
||||||
|
void DrawString(float x, float y, const std::string& sText, Pixel col, const olc::vf2d& scale);
|
||||||
|
void DrawString(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale);
|
||||||
|
|
||||||
|
|
||||||
|
// Draws a whole decal, with optional scale and tinting
|
||||||
|
void DrawDecal(const olc::vf2d& pos, olc::Decal* decal, const olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
// Draws a region of a decal, with optional scale and tinting
|
||||||
|
void DrawPartialDecal(const olc::vf2d& pos, olc::Decal* decal, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
void DrawPartialDecal(const olc::vf2d& pos, const olc::vf2d& size, olc::Decal* decal, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
// Draws fully user controlled 4 vertices, pos(pixels), uv(pixels), colours
|
||||||
|
void DrawExplicitDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d* uv, const olc::Pixel* col, uint32_t elements = 4);
|
||||||
|
//// Draws a decal with 4 arbitrary points, warping the texture to look "correct"
|
||||||
|
void DrawWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::Pixel& tint = olc::WHITE);
|
||||||
|
void DrawWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
void DrawWarpedDecal(olc::Decal* decal, const std::array<olc::vf2d, 4>& pos, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
//// As above, but you can specify a region of a decal source sprite
|
||||||
|
void DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
void DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
void DrawPartialWarpedDecal(olc::Decal* decal, const std::array<olc::vf2d, 4>& pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
//// Draws a decal rotated to specified angle, wit point of rotation offset
|
||||||
|
void DrawRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
void DrawPartialRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f, 1.0f }, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
// Draws a multiline string as a decal, with tiniting and scaling
|
||||||
|
void DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||||
|
void DrawStringPropDecal(const olc::vf2d& pos, const std::string& sText, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||||
|
// Draws a single shaded filled rectangle as a decal
|
||||||
|
void FillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE);
|
||||||
|
void DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE);
|
||||||
|
|
||||||
|
// Draws a corner shaded rectangle as a decal
|
||||||
|
void GradientFillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel colTL, const olc::Pixel colBL, const olc::Pixel colBR, const olc::Pixel colTR);
|
||||||
|
// Draws an arbitrary convex textured polygon using GPU
|
||||||
|
void DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<olc::vf2d>& uv, const olc::Pixel tint = olc::WHITE);
|
||||||
|
void DrawLineDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p = olc::WHITE);
|
||||||
|
void DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>&pos, const std::vector<olc::vf2d>&uv, const std::vector<olc::Pixel> &tint);
|
||||||
|
void DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<olc::vf2d>& uv, const std::vector<olc::Pixel>& colours, const olc::Pixel tint);
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(OLC_PGEX_SHADER)
|
||||||
|
// Shader Specific
|
||||||
|
void DrawDecal(olc::Shade& shader, const olc::vf2d & pos, olc::Decal * decal, const olc::vf2d & scale = { 1.0f,1.0f }, const olc::Pixel & tint = olc::WHITE);
|
||||||
|
void DrawPartialDecal(olc::Shade& shader, const olc::vf2d& pos, olc::Decal* decal, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
void DrawPartialDecal(olc::Shade& shader, const olc::vf2d& pos, const olc::vf2d& size, olc::Decal* decal, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class TileTransformedView : public TransformedView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TileTransformedView() = default;
|
||||||
|
TileTransformedView(const olc::vi2d& vViewArea, const olc::vi2d& vTileSize);
|
||||||
|
|
||||||
|
public:
|
||||||
|
olc::vi2d GetTopLeftTile() const;
|
||||||
|
olc::vi2d GetBottomRightTile() const;
|
||||||
|
olc::vi2d GetVisibleTiles() const;
|
||||||
|
olc::vi2d GetTileUnderScreenPos(const olc::vi2d& vPos) const;
|
||||||
|
const olc::vi2d GetTileOffset() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OLC_PGEX_TRANSFORMEDVIEW
|
||||||
|
#undef OLC_PGEX_TRANSFORMEDVIEW
|
||||||
|
|
||||||
|
namespace olc
|
||||||
|
{
|
||||||
|
olc::PixelGameEngine* TransformedView::GetPGE()
|
||||||
|
{
|
||||||
|
return pge;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::Initialise(const olc::vi2d& vViewArea, const olc::vf2d& vPixelScale)
|
||||||
|
{
|
||||||
|
SetViewArea(vViewArea);
|
||||||
|
SetWorldScale(vPixelScale);
|
||||||
|
m_vPixelScale = vPixelScale;
|
||||||
|
m_vRecipPixel = 1.0f / m_vPixelScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::SetWorldOffset(const olc::vf2d& vOffset)
|
||||||
|
{
|
||||||
|
m_vWorldOffset = vOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::MoveWorldOffset(const olc::vf2d& vDeltaOffset)
|
||||||
|
{
|
||||||
|
m_vWorldOffset += vDeltaOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::SetWorldScale(const olc::vf2d& vScale)
|
||||||
|
{
|
||||||
|
m_vWorldScale = vScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::SetViewArea(const olc::vi2d& vViewArea)
|
||||||
|
{
|
||||||
|
m_vViewArea = vViewArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vf2d TransformedView::GetWorldTL() const
|
||||||
|
{
|
||||||
|
return TransformedView::ScreenToWorld({ 0,0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vf2d TransformedView::GetWorldBR() const
|
||||||
|
{
|
||||||
|
return TransformedView::ScreenToWorld(m_vViewArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vf2d TransformedView::GetWorldVisibleArea() const
|
||||||
|
{
|
||||||
|
return GetWorldBR() - GetWorldTL();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::ZoomAtScreenPos(const float fDeltaZoom, const olc::vi2d& vPos)
|
||||||
|
{
|
||||||
|
olc::vf2d vOffsetBeforeZoom = ScreenToWorld(vPos);
|
||||||
|
m_vWorldScale *= fDeltaZoom;
|
||||||
|
olc::vf2d vOffsetAfterZoom = ScreenToWorld(vPos);
|
||||||
|
m_vWorldOffset += vOffsetBeforeZoom - vOffsetAfterZoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::SetZoom(const float fZoom, const olc::vf2d& vPos)
|
||||||
|
{
|
||||||
|
olc::vf2d vOffsetBeforeZoom = ScreenToWorld(vPos);
|
||||||
|
m_vWorldScale = { fZoom, fZoom };
|
||||||
|
olc::vf2d vOffsetAfterZoom = ScreenToWorld(vPos);
|
||||||
|
m_vWorldOffset += vOffsetBeforeZoom - vOffsetAfterZoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::StartPan(const olc::vi2d& vPos)
|
||||||
|
{
|
||||||
|
m_bPanning = true;
|
||||||
|
m_vStartPan = olc::vf2d(vPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::UpdatePan(const olc::vi2d& vPos)
|
||||||
|
{
|
||||||
|
if (m_bPanning)
|
||||||
|
{
|
||||||
|
m_vWorldOffset -= (olc::vf2d(vPos) - m_vStartPan) / m_vWorldScale;
|
||||||
|
m_vStartPan = olc::vf2d(vPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::EndPan(const olc::vi2d& vPos)
|
||||||
|
{
|
||||||
|
UpdatePan(vPos);
|
||||||
|
m_bPanning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const olc::vf2d& TransformedView::GetWorldOffset() const
|
||||||
|
{
|
||||||
|
return m_vWorldOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
const olc::vf2d& TransformedView::GetWorldScale() const
|
||||||
|
{
|
||||||
|
return m_vWorldScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vf2d TransformedView::WorldToScreen(const olc::vf2d& vWorldPos) const
|
||||||
|
{
|
||||||
|
olc::vf2d vFloat = ((vWorldPos - m_vWorldOffset) * m_vWorldScale);
|
||||||
|
//vFloat = { std::floor(vFloat.x + 0.5f), std::floor(vFloat.y + 0.5f) };
|
||||||
|
return vFloat;
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vf2d TransformedView::ScreenToWorld(const olc::vf2d& vScreenPos) const
|
||||||
|
{
|
||||||
|
return (olc::vf2d(vScreenPos) / m_vWorldScale) + m_vWorldOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vf2d TransformedView::ScaleToWorld(const olc::vf2d& vScreenSize) const
|
||||||
|
{
|
||||||
|
return (olc::vf2d(vScreenSize) / m_vWorldScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vf2d TransformedView::ScaleToScreen(const olc::vf2d& vWorldSize) const
|
||||||
|
{
|
||||||
|
//olc::vf2d vFloat = (vWorldSize * m_vWorldScale) + olc::vf2d(0.5f, 0.5f);
|
||||||
|
//return vFloat.floor();
|
||||||
|
return (vWorldSize * m_vWorldScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TransformedView::IsPointVisible(const olc::vf2d & vPos) const
|
||||||
|
{
|
||||||
|
olc::vi2d vScreen = WorldToScreen(vPos);
|
||||||
|
return vScreen.x >= 0 && vScreen.x < m_vViewArea.x&& vScreen.y >= 0 && vScreen.y < m_vViewArea.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TransformedView::IsRectVisible(const olc::vf2d& vPos, const olc::vf2d& vSize) const
|
||||||
|
{
|
||||||
|
olc::vi2d vScreenPos = WorldToScreen(vPos);
|
||||||
|
olc::vi2d vScreenSize = vSize * m_vWorldScale;
|
||||||
|
return (vScreenPos.x < 0 + m_vViewArea.x && vScreenPos.x + vScreenSize.x > 0 && vScreenPos.y < m_vViewArea.y&& vScreenPos.y + vScreenSize.y > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::HandlePanAndZoom(const int nMouseButton, const float fZoomRate, const bool bPan, const bool bZoom)
|
||||||
|
{
|
||||||
|
const auto& vMousePos = pge->GetMousePos();
|
||||||
|
if (bPan)
|
||||||
|
{
|
||||||
|
if (pge->GetMouse(nMouseButton).bPressed) StartPan(vMousePos);
|
||||||
|
if (pge->GetMouse(nMouseButton).bHeld) UpdatePan(vMousePos);
|
||||||
|
if (pge->GetMouse(nMouseButton).bReleased) EndPan(vMousePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bZoom)
|
||||||
|
{
|
||||||
|
if (pge->GetMouseWheel() > 0) ZoomAtScreenPos(1.0f + fZoomRate, vMousePos);
|
||||||
|
if (pge->GetMouseWheel() < 0) ZoomAtScreenPos(1.0f - fZoomRate, vMousePos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TransformedView::Draw(float x, float y, olc::Pixel p)
|
||||||
|
{
|
||||||
|
return Draw({ x, y }, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TransformedView::Draw(const olc::vf2d & pos, olc::Pixel p)
|
||||||
|
{
|
||||||
|
return pge->Draw(WorldToScreen(pos), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawLine(float x1, float y1, float x2, float y2, olc::Pixel p, uint32_t pattern)
|
||||||
|
{
|
||||||
|
DrawLine({ x1, y1 }, { x2, y2 }, p, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawLine(const olc::vf2d & pos1, const olc::vf2d & pos2, olc::Pixel p, uint32_t pattern)
|
||||||
|
{
|
||||||
|
pge->DrawLine(WorldToScreen(pos1), WorldToScreen(pos2), p, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawCircle(float x, float y, float radius, olc::Pixel p, uint8_t mask)
|
||||||
|
{
|
||||||
|
DrawCircle({ x,y }, radius, p, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawCircle(const olc::vf2d & pos, float radius, olc::Pixel p, uint8_t mask)
|
||||||
|
{
|
||||||
|
pge->DrawCircle(WorldToScreen(pos), int32_t(radius * m_vWorldScale.x), p, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::FillCircle(float x, float y, float radius, olc::Pixel p)
|
||||||
|
{
|
||||||
|
FillCircle({ x,y }, radius, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::FillCircle(const olc::vf2d & pos, float radius, olc::Pixel p)
|
||||||
|
{
|
||||||
|
pge->FillCircle(WorldToScreen(pos), int32_t(radius * m_vWorldScale.x), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawRect(float x, float y, float w, float h, olc::Pixel p)
|
||||||
|
{
|
||||||
|
DrawRect({ x, y }, { w, h }, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawRect(const olc::vf2d & pos, const olc::vf2d & size, olc::Pixel p)
|
||||||
|
{
|
||||||
|
pge->DrawRect(WorldToScreen(pos), ((size * m_vWorldScale) + olc::vf2d(0.5f, 0.5f)).floor(), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::FillRect(float x, float y, float w, float h, olc::Pixel p)
|
||||||
|
{
|
||||||
|
FillRect({ x, y }, { w, h }, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::FillRect(const olc::vf2d & pos, const olc::vf2d & size, olc::Pixel p)
|
||||||
|
{
|
||||||
|
pge->FillRect(WorldToScreen(pos), size * m_vWorldScale, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawTriangle(float x1, float y1, float x2, float y2, float x3, float y3, olc::Pixel p)
|
||||||
|
{
|
||||||
|
DrawTriangle({ x1, y1 }, { x2, y2 }, { x3, y3 }, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawTriangle(const olc::vf2d & pos1, const olc::vf2d & pos2, const olc::vf2d & pos3, olc::Pixel p)
|
||||||
|
{
|
||||||
|
pge->DrawTriangle(WorldToScreen(pos1), WorldToScreen(pos2), WorldToScreen(pos3), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::FillTriangle(float x1, float y1, float x2, float y2, float x3, float y3, olc::Pixel p)
|
||||||
|
{
|
||||||
|
FillTriangle({ x1, y1 }, { x2, y2 }, { x3, y3 }, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::FillTriangle(const olc::vf2d & pos1, const olc::vf2d & pos2, const olc::vf2d & pos3, olc::Pixel p)
|
||||||
|
{
|
||||||
|
pge->FillTriangle(WorldToScreen(pos1), WorldToScreen(pos2), WorldToScreen(pos3), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawSprite(float x, float y, olc::Sprite* sprite, float scalex, float scaley, uint8_t flip)
|
||||||
|
{
|
||||||
|
DrawSprite({ x, y }, sprite, { scalex, scaley }, flip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawSprite(const olc::vf2d & pos, olc::Sprite * sprite, const olc::vf2d & scale, uint8_t flip)
|
||||||
|
{
|
||||||
|
olc::vf2d vSpriteSize = olc::vf2d(float(sprite->width), float(sprite->height));
|
||||||
|
if (IsRectVisible(pos, vSpriteSize * scale))
|
||||||
|
{
|
||||||
|
olc::vf2d vSpriteScaledSize = vSpriteSize * m_vRecipPixel * m_vWorldScale * scale;
|
||||||
|
olc::vi2d vPixel;
|
||||||
|
olc::vi2d vSpritePixelStart = WorldToScreen(pos);
|
||||||
|
olc::vi2d vSpritePixelEnd = WorldToScreen((vSpriteSize * scale) + pos);
|
||||||
|
|
||||||
|
olc::vi2d vScreenPixelStart = (vSpritePixelStart).max({0,0});
|
||||||
|
olc::vi2d vScreenPixelEnd = (vSpritePixelEnd).min({ pge->ScreenWidth(),pge->ScreenHeight() });
|
||||||
|
|
||||||
|
olc::vf2d vPixelStep = 1.0f / vSpriteScaledSize;
|
||||||
|
|
||||||
|
for (vPixel.y = vScreenPixelStart.y; vPixel.y < vScreenPixelEnd.y; vPixel.y++)
|
||||||
|
{
|
||||||
|
for (vPixel.x = vScreenPixelStart.x; vPixel.x < vScreenPixelEnd.x; vPixel.x++)
|
||||||
|
{
|
||||||
|
olc::vf2d vSample = olc::vf2d(vPixel - vSpritePixelStart) * vPixelStep;
|
||||||
|
pge->Draw(vPixel, sprite->Sample(vSample.x, vSample.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TransformedView::DrawPartialSprite(float x, float y, Sprite* sprite, int32_t ox, int32_t oy, int32_t w, int32_t h, float scalex, float scaley, uint8_t flip)
|
||||||
|
{
|
||||||
|
DrawPartialSprite({ x,y }, sprite, { ox,oy }, { w, h }, { scalex, scaley }, flip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPartialSprite(const olc::vf2d& pos, Sprite* sprite, const olc::vi2d& sourcepos, const olc::vi2d& size, const olc::vf2d& scale, uint8_t flip)
|
||||||
|
{
|
||||||
|
olc::vf2d vSpriteSize = size;
|
||||||
|
if (IsRectVisible(pos, size * scale))
|
||||||
|
{
|
||||||
|
olc::vf2d vSpriteScaledSize = olc::vf2d(size) * m_vRecipPixel * m_vWorldScale * scale;
|
||||||
|
olc::vf2d vSpritePixelStep = 1.0f / olc::vf2d(float(sprite->width), float(sprite->height));
|
||||||
|
olc::vi2d vPixel, vStart = WorldToScreen(pos), vEnd = vSpriteScaledSize + vStart;
|
||||||
|
olc::vf2d vScreenPixelStep = 1.0f / vSpriteScaledSize;
|
||||||
|
|
||||||
|
for (vPixel.y = vStart.y; vPixel.y < vEnd.y; vPixel.y++)
|
||||||
|
{
|
||||||
|
for (vPixel.x = vStart.x; vPixel.x < vEnd.x; vPixel.x++)
|
||||||
|
{
|
||||||
|
olc::vf2d vSample = ((olc::vf2d(vPixel - vStart) * vScreenPixelStep) * size * vSpritePixelStep) + olc::vf2d(sourcepos) * vSpritePixelStep;
|
||||||
|
pge->Draw(vPixel, sprite->Sample(vSample.x, vSample.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawString(float x, float y, const std::string& sText, Pixel col, const olc::vf2d& scale)
|
||||||
|
{
|
||||||
|
DrawString({ x, y }, sText, col, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawString(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale)
|
||||||
|
{
|
||||||
|
olc::vf2d vOffset = { 0.0f, 0.0f };
|
||||||
|
Pixel::Mode m = pge->GetPixelMode();
|
||||||
|
|
||||||
|
auto StringPlot = [&col](const int x, const int y, const olc::Pixel& pSource, const olc::Pixel& pDest)
|
||||||
|
{
|
||||||
|
return pSource.r > 1 ? col : pDest;
|
||||||
|
};
|
||||||
|
|
||||||
|
pge->SetPixelMode(StringPlot);
|
||||||
|
|
||||||
|
for (auto c : sText)
|
||||||
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
vOffset.x = 0.0f; vOffset.y += 8.0f * m_vRecipPixel.y * scale.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t ox = ((c - 32) % 16) * 8;
|
||||||
|
int32_t oy = ((c - 32) / 16) * 8;
|
||||||
|
DrawPartialSprite(pos + vOffset, pge->GetFontSprite(), { ox, oy }, { 8, 8 }, scale);
|
||||||
|
vOffset.x += 8.0f * m_vRecipPixel.x * scale.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pge->SetPixelMode(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TransformedView::DrawDecal(const olc::vf2d & pos, olc::Decal * decal, const olc::vf2d & scale, const olc::Pixel & tint)
|
||||||
|
{
|
||||||
|
pge->DrawDecal(WorldToScreen(pos), decal, scale * m_vWorldScale * m_vRecipPixel, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPartialDecal(const olc::vf2d & pos, olc::Decal * decal, const olc::vf2d & source_pos, const olc::vf2d & source_size, const olc::vf2d & scale, const olc::Pixel & tint)
|
||||||
|
{
|
||||||
|
pge->DrawPartialDecal(WorldToScreen(pos), decal, source_pos, source_size, scale * m_vWorldScale * m_vRecipPixel, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPartialDecal(const olc::vf2d & pos, const olc::vf2d & size, olc::Decal * decal, const olc::vf2d & source_pos, const olc::vf2d & source_size, const olc::Pixel & tint)
|
||||||
|
{
|
||||||
|
pge->DrawPartialDecal(WorldToScreen(pos), size * m_vWorldScale * m_vRecipPixel, decal, source_pos, source_size, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawExplicitDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d* uv, const olc::Pixel* col, uint32_t elements)
|
||||||
|
{
|
||||||
|
std::vector<olc::vf2d> vTransformed(elements);
|
||||||
|
for (uint32_t n = 0; n < elements; n++)
|
||||||
|
vTransformed[n] = WorldToScreen(pos[n]);
|
||||||
|
pge->DrawExplicitDecal(decal, vTransformed.data(), uv, col, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::Pixel& tint)
|
||||||
|
{
|
||||||
|
std::array<olc::vf2d, 4> vTransformed =
|
||||||
|
{ {
|
||||||
|
WorldToScreen(pos[0]), WorldToScreen(pos[1]),
|
||||||
|
WorldToScreen(pos[2]), WorldToScreen(pos[3]),
|
||||||
|
} };
|
||||||
|
|
||||||
|
pge->DrawWarpedDecal(decal, vTransformed, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::Pixel& tint)
|
||||||
|
{
|
||||||
|
DrawWarpedDecal(decal, &pos[0], tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawWarpedDecal(olc::Decal* decal, const std::array<olc::vf2d, 4>& pos, const olc::Pixel& tint)
|
||||||
|
{
|
||||||
|
DrawWarpedDecal(decal, pos.data(), tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint)
|
||||||
|
{
|
||||||
|
DrawPartialWarpedDecal(decal, &pos[0], source_pos, source_size, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint)
|
||||||
|
{
|
||||||
|
std::array<olc::vf2d, 4> vTransformed =
|
||||||
|
{ {
|
||||||
|
WorldToScreen(pos[0]), WorldToScreen(pos[1]),
|
||||||
|
WorldToScreen(pos[2]), WorldToScreen(pos[3]),
|
||||||
|
} };
|
||||||
|
|
||||||
|
pge->DrawPartialWarpedDecal(decal, vTransformed, source_pos, source_size, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPartialWarpedDecal(olc::Decal* decal, const std::array<olc::vf2d, 4>& pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint)
|
||||||
|
{
|
||||||
|
DrawPartialWarpedDecal(decal, pos.data(), source_pos, source_size, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawRotatedDecal(const olc::vf2d & pos, olc::Decal * decal, const float fAngle, const olc::vf2d & center, const olc::vf2d & scale, const olc::Pixel & tint)
|
||||||
|
{
|
||||||
|
pge->DrawRotatedDecal(WorldToScreen(pos), decal, fAngle, center, scale * m_vWorldScale * m_vRecipPixel, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPartialRotatedDecal(const olc::vf2d & pos, olc::Decal * decal, const float fAngle, const olc::vf2d & center, const olc::vf2d & source_pos, const olc::vf2d & source_size, const olc::vf2d & scale, const olc::Pixel & tint)
|
||||||
|
{
|
||||||
|
pge->DrawPartialRotatedDecal(WorldToScreen(pos), decal, fAngle, center, source_pos, source_size, scale * m_vWorldScale * m_vRecipPixel, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawStringDecal(const olc::vf2d & pos, const std::string & sText, const olc::Pixel col, const olc::vf2d & scale)
|
||||||
|
{
|
||||||
|
pge->DrawStringDecal(WorldToScreen(pos), sText, col, scale * m_vWorldScale * m_vRecipPixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawStringPropDecal(const olc::vf2d & pos, const std::string & sText, const olc::Pixel col, const olc::vf2d & scale )
|
||||||
|
{
|
||||||
|
pge->DrawStringPropDecal(WorldToScreen(pos), sText, col, scale * m_vWorldScale * m_vRecipPixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::FillRectDecal(const olc::vf2d & pos, const olc::vf2d & size, const olc::Pixel col)
|
||||||
|
{
|
||||||
|
pge->FillRectDecal(WorldToScreen(pos), (size * m_vWorldScale).ceil(), col);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col)
|
||||||
|
{
|
||||||
|
pge->DrawRectDecal(WorldToScreen(pos), (size * m_vWorldScale).ceil(), col);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawLineDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p)
|
||||||
|
{
|
||||||
|
pge->DrawLineDecal(WorldToScreen(pos1), WorldToScreen(pos2), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::GradientFillRectDecal(const olc::vf2d & pos, const olc::vf2d & size, const olc::Pixel colTL, const olc::Pixel colBL, const olc::Pixel colBR, const olc::Pixel colTR)
|
||||||
|
{
|
||||||
|
pge->GradientFillRectDecal(WorldToScreen(pos), size * m_vWorldScale, colTL, colBL, colBR, colTR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<olc::vf2d>& uv, const olc::Pixel tint)
|
||||||
|
{
|
||||||
|
std::vector<olc::vf2d> vTransformed(pos.size());
|
||||||
|
for (uint32_t n = 0; n < pos.size(); n++)
|
||||||
|
vTransformed[n] = WorldToScreen(pos[n]);
|
||||||
|
pge->DrawPolygonDecal(decal, vTransformed, uv, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<olc::vf2d>& uv, const std::vector<olc::Pixel> &tint)
|
||||||
|
{
|
||||||
|
std::vector<olc::vf2d> vTransformed(pos.size());
|
||||||
|
for (uint32_t n = 0; n < pos.size(); n++)
|
||||||
|
vTransformed[n] = WorldToScreen(pos[n]);
|
||||||
|
pge->DrawPolygonDecal(decal, vTransformed, uv, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<olc::vf2d>& uv, const std::vector<olc::Pixel>& colours, const olc::Pixel tint)
|
||||||
|
{
|
||||||
|
std::vector<olc::vf2d> vTransformed(pos.size());
|
||||||
|
for (uint32_t n = 0; n < pos.size(); n++)
|
||||||
|
vTransformed[n] = WorldToScreen(pos[n]);
|
||||||
|
pge->DrawPolygonDecal(decal, vTransformed, uv, colours, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (OLC_PGEX_SHADER)
|
||||||
|
|
||||||
|
void TransformedView::DrawDecal(olc::Shade &shade, const olc::vf2d& pos, olc::Decal* decal, const olc::vf2d& scale, const olc::Pixel& tint)
|
||||||
|
{
|
||||||
|
shade.DrawDecal(WorldToScreen(pos), decal, scale * m_vWorldScale * m_vRecipPixel, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPartialDecal(olc::Shade& shade, const olc::vf2d& pos, olc::Decal* decal, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale, const olc::Pixel& tint)
|
||||||
|
{
|
||||||
|
shade.DrawPartialDecal(WorldToScreen(pos), decal, source_pos, source_size, scale * m_vWorldScale * m_vRecipPixel, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawPartialDecal(olc::Shade& shade, const olc::vf2d& pos, const olc::vf2d& size, olc::Decal* decal, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint)
|
||||||
|
{
|
||||||
|
shade.DrawPartialDecal(WorldToScreen(pos), size * m_vWorldScale * m_vRecipPixel, decal, source_pos, source_size, tint);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
TileTransformedView::TileTransformedView(const olc::vi2d& vViewArea, const olc::vi2d& vTileSize)
|
||||||
|
{
|
||||||
|
Initialise(vViewArea, vTileSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
olc::vi2d TileTransformedView::GetTopLeftTile() const
|
||||||
|
{
|
||||||
|
return ScreenToWorld({ 0,0 }).floor();
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vi2d TileTransformedView::GetBottomRightTile() const
|
||||||
|
{
|
||||||
|
return ScreenToWorld(m_vViewArea).ceil();
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vi2d TileTransformedView::GetVisibleTiles() const
|
||||||
|
{
|
||||||
|
return GetBottomRightTile() - GetTopLeftTile();
|
||||||
|
}
|
||||||
|
|
||||||
|
olc::vi2d TileTransformedView::GetTileUnderScreenPos(const olc::vi2d& vPos) const
|
||||||
|
{
|
||||||
|
return ScreenToWorld(vPos).floor();
|
||||||
|
}
|
||||||
|
|
||||||
|
const olc::vi2d TileTransformedView::GetTileOffset() const
|
||||||
|
{
|
||||||
|
return { int32_t((m_vWorldOffset.x - std::floor(m_vWorldOffset.x)) * m_vWorldScale.x),
|
||||||
|
int32_t((m_vWorldOffset.y - std::floor(m_vWorldOffset.y)) * m_vWorldScale.y) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
6701
olcCodeJam2023Entry/olcPixelGameEngine.h
Normal file
6701
olcCodeJam2023Entry/olcPixelGameEngine.h
Normal file
File diff suppressed because it is too large
Load Diff
1962
olcCodeJam2023Entry/olcSoundWaveEngine.h
Normal file
1962
olcCodeJam2023Entry/olcSoundWaveEngine.h
Normal file
File diff suppressed because it is too large
Load Diff
258
olcCodeJam2023Entry/olcUTIL_Camera2D.h
Normal file
258
olcCodeJam2023Entry/olcUTIL_Camera2D.h
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
/*
|
||||||
|
OneLoneCoder - Camera2D v1.00
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
A 2D world camera with various modes
|
||||||
|
|
||||||
|
|
||||||
|
License (OLC-3)
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Copyright 2018 - 2022 OneLoneCoder.com
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions or derivations of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions or derivative works in binary form must reproduce
|
||||||
|
the above copyright notice. This list of conditions and the following
|
||||||
|
disclaimer must be reproduced in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
Links
|
||||||
|
~~~~~
|
||||||
|
YouTube: https://www.youtube.com/javidx9
|
||||||
|
Discord: https://discord.gg/WhwHUMV
|
||||||
|
Twitter: https://www.twitter.com/javidx9
|
||||||
|
Twitch: https://www.twitch.tv/javidx9
|
||||||
|
GitHub: https://www.github.com/onelonecoder
|
||||||
|
Homepage: https://www.onelonecoder.com
|
||||||
|
|
||||||
|
Author
|
||||||
|
~~~~~~
|
||||||
|
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020, 2021, 2022
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "olcPixelGameEngine.h"
|
||||||
|
|
||||||
|
namespace olc::utils
|
||||||
|
{
|
||||||
|
class Camera2D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class Mode : uint8_t
|
||||||
|
{
|
||||||
|
Simple, // No motion, just directly settable
|
||||||
|
EdgeMove, // Moves as target crosses boundary
|
||||||
|
LazyFollow, // Lazily follows the target
|
||||||
|
FixedScreens, // Moves statically between "screens"
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline Camera2D() : m_pTarget(&m_vLocalTarget) {}
|
||||||
|
|
||||||
|
// Construct a camera with a viewable area size, and an optional starting position
|
||||||
|
inline Camera2D(const olc::vf2d& vViewSize, const olc::vf2d& vViewPos = { 0.0f, 0.0f }) : m_pTarget(&m_vLocalTarget)
|
||||||
|
{
|
||||||
|
m_vViewSize = vViewSize;
|
||||||
|
m_vViewPos = vViewPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the operational mode of this camera
|
||||||
|
inline void SetMode(const Mode t)
|
||||||
|
{
|
||||||
|
m_nMode = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the operational mode of this camera
|
||||||
|
inline Mode GetMode() const
|
||||||
|
{
|
||||||
|
return m_nMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the position of the target being tracked by this camera
|
||||||
|
inline const olc::vf2d& GetTarget() const
|
||||||
|
{
|
||||||
|
return *m_pTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the position of the cameras focus point
|
||||||
|
inline const olc::vf2d& GetPosition() const
|
||||||
|
{
|
||||||
|
return m_vPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the top left of teh cameras visible area in world space
|
||||||
|
inline const olc::vf2d& GetViewPosition() const
|
||||||
|
{
|
||||||
|
return m_vViewPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the camera's visible area
|
||||||
|
inline const olc::vf2d& GetViewSize() const
|
||||||
|
{
|
||||||
|
return m_vViewSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set tracked point via pointer
|
||||||
|
inline void SetTarget(olc::vf2d& vTarget)
|
||||||
|
{
|
||||||
|
m_pTarget = &vTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set tracked point via const ref - {10, 35} for example
|
||||||
|
inline void SetTarget(const olc::vf2d&& vTarget)
|
||||||
|
{
|
||||||
|
m_vLocalTarget = vTarget;
|
||||||
|
m_pTarget = &m_vLocalTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set world boundary rectangle
|
||||||
|
inline void SetWorldBoundary(const olc::vf2d& vPos, const olc::vf2d& vSize)
|
||||||
|
{
|
||||||
|
m_vWorldBoundaryPos = vPos;
|
||||||
|
m_vWorldBoundarySize = vSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instruct camera to respect world boundaries
|
||||||
|
inline void EnableWorldBoundary(const bool bEnable)
|
||||||
|
{
|
||||||
|
m_bWorldBoundary = bEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Are we using a world boundary?
|
||||||
|
inline bool IsWorldBoundaryEnabled() const
|
||||||
|
{
|
||||||
|
return m_bWorldBoundary;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the world boundary rectangle position
|
||||||
|
inline const olc::vf2d& GetWorldBoundaryPosition() const
|
||||||
|
{
|
||||||
|
return m_vWorldBoundaryPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the world boundary rectangle size
|
||||||
|
inline const olc::vf2d& GetWorldBoundarySize() const
|
||||||
|
{
|
||||||
|
return m_vWorldBoundarySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the velocity at which the lazy follower reaches tracked point
|
||||||
|
inline void SetLazyFollowRate(const float fRate)
|
||||||
|
{
|
||||||
|
m_fLazyFollowRate = fRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the velocity at which the lazy follower reaches tracked point
|
||||||
|
inline float GetLazyFollowRate() const
|
||||||
|
{
|
||||||
|
return m_fLazyFollowRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set distance from tracked point to start nudging screen
|
||||||
|
inline void SetEdgeTriggerDistance(const olc::vf2d& vEdge)
|
||||||
|
{
|
||||||
|
m_vEdgeTriggerDistance = vEdge;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return disance from tracked point that screen will nudge
|
||||||
|
inline const olc::vf2d& GetEdgeTriggerDistance() const
|
||||||
|
{
|
||||||
|
return m_vEdgeTriggerDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update camera, animating if necessary, obeying world boundary rules
|
||||||
|
// returns true if target is visible
|
||||||
|
inline virtual bool Update(const float fElapsedTime)
|
||||||
|
{
|
||||||
|
switch (m_nMode)
|
||||||
|
{
|
||||||
|
case Mode::Simple:
|
||||||
|
{
|
||||||
|
m_vPosition = GetTarget();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mode::EdgeMove:
|
||||||
|
{
|
||||||
|
olc::vf2d vOverlap = GetTarget() - m_vPosition;
|
||||||
|
if (vOverlap.x > m_vEdgeTriggerDistance.x) m_vPosition.x += vOverlap.x - m_vEdgeTriggerDistance.x;
|
||||||
|
if (vOverlap.x < -m_vEdgeTriggerDistance.x) m_vPosition.x += vOverlap.x + m_vEdgeTriggerDistance.x;
|
||||||
|
if (vOverlap.y > m_vEdgeTriggerDistance.y) m_vPosition.y += vOverlap.y - m_vEdgeTriggerDistance.y;
|
||||||
|
if (vOverlap.y < -m_vEdgeTriggerDistance.y) m_vPosition.y += vOverlap.y + m_vEdgeTriggerDistance.y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mode::LazyFollow:
|
||||||
|
{
|
||||||
|
m_vPosition += (GetTarget() - m_vPosition) * m_fLazyFollowRate * fElapsedTime;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mode::FixedScreens:
|
||||||
|
{
|
||||||
|
m_vPosition = olc::vf2d(olc::vi2d(GetTarget() / m_vScreenSize) * olc::vi2d(m_vScreenSize)) + (m_vViewSize * 0.5f);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make camera target the middle of the view
|
||||||
|
m_vViewPos = m_vPosition - (m_vViewSize * 0.5f);
|
||||||
|
|
||||||
|
// Clamp to World Boundary (if in place)
|
||||||
|
if (m_bWorldBoundary)
|
||||||
|
{
|
||||||
|
m_vViewPos = m_vViewPos.max(m_vWorldBoundaryPos).min(m_vWorldBoundaryPos + m_vWorldBoundarySize - m_vViewSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetTarget().x >= m_vViewPos.x && GetTarget().x < (m_vViewPos.x + m_vViewSize.x) &&
|
||||||
|
GetTarget().y >= m_vViewPos.y && GetTarget().y < (m_vViewPos.y + m_vViewSize.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Position of camera focus point in the world
|
||||||
|
olc::vf2d m_vPosition;
|
||||||
|
// Rectangular size of camera viewing area
|
||||||
|
olc::vf2d m_vViewSize;
|
||||||
|
// Top left coordinate of camera viewing area
|
||||||
|
olc::vf2d m_vViewPos;
|
||||||
|
// Camera movement mode
|
||||||
|
Mode m_nMode = Mode::Simple;
|
||||||
|
|
||||||
|
// Target Vector2D object camera should follow (either ref or ptr)
|
||||||
|
olc::vf2d* m_pTarget = nullptr;
|
||||||
|
olc::vf2d m_vLocalTarget;
|
||||||
|
|
||||||
|
// World Boundary
|
||||||
|
bool m_bWorldBoundary = false;
|
||||||
|
olc::vf2d m_vWorldBoundaryPos = { 0.0f, 0.0f };
|
||||||
|
olc::vf2d m_vWorldBoundarySize = { 256.0f, 240.0f };
|
||||||
|
|
||||||
|
// Mode specific
|
||||||
|
olc::vf2d m_vEdgeTriggerDistance = { 1.0f, 1.0f };
|
||||||
|
float m_fLazyFollowRate = 4.0f;
|
||||||
|
olc::vi2d m_vScreenSize = { 16,15 };
|
||||||
|
};
|
||||||
|
}
|
||||||
1046
olcCodeJam2023Entry/olcUTIL_Geometry2D.h
Normal file
1046
olcCodeJam2023Entry/olcUTIL_Geometry2D.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
olcCodeJam2023Entry/pge.data
Normal file
BIN
olcCodeJam2023Entry/pge.data
Normal file
Binary file not shown.
1296
olcCodeJam2023Entry/pge.html
Normal file
1296
olcCodeJam2023Entry/pge.html
Normal file
File diff suppressed because one or more lines are too long
11121
olcCodeJam2023Entry/pge.js
Normal file
11121
olcCodeJam2023Entry/pge.js
Normal file
File diff suppressed because it is too large
Load Diff
BIN
olcCodeJam2023Entry/pge.wasm
Normal file
BIN
olcCodeJam2023Entry/pge.wasm
Normal file
Binary file not shown.
1
olcCodeJam2023Entry/pge.wasm.map
Normal file
1
olcCodeJam2023Entry/pge.wasm.map
Normal file
File diff suppressed because one or more lines are too long
16
olcCodeJam2023Entry/resource.h
Normal file
16
olcCodeJam2023Entry/resource.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by olcCodeJam2023Entry.rc
|
||||||
|
//
|
||||||
|
#define IDI_ICON1 104
|
||||||
|
|
||||||
|
// Next default values for new objects
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 105
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
16
olcCodeJam2023Entry/resource1.h
Normal file
16
olcCodeJam2023Entry/resource1.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by olcCodeJam2023Entry.rc
|
||||||
|
//
|
||||||
|
#define IDI_ICON1 103
|
||||||
|
|
||||||
|
// Next default values for new objects
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 104
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 102
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
Loading…
x
Reference in New Issue
Block a user