From 1a6980b3d4218e03164c27c569de1311646829c8 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Fri, 16 Aug 2024 19:30:34 -0500 Subject: [PATCH] Add in Hamsters and player flags. Fix up animation loading systems. Setup main game loop and load level function. --- assets/hamster.png | Bin 1195 -> 1659 bytes hamster.vcxproj | 10 +- hamster.vcxproj.filters | 17 ++- hamster.vcxproj.user | 5 +- src/Hamster.cpp | 80 +++++++++++++ src/Hamster.h | 71 +++++++++++ src/HamsterGame.cpp | 43 +++++-- src/HamsterGame.h | 9 +- src/olcPGEX_ViewPort.h | 8 +- src/olcUTIL_Camera2D.h | 258 ++++++++++++++++++++++++++++++++++++++++ src/util.cpp | 18 +++ Hamster.h => src/util.h | 14 ++- 12 files changed, 504 insertions(+), 29 deletions(-) create mode 100644 src/Hamster.cpp create mode 100644 src/Hamster.h create mode 100644 src/olcUTIL_Camera2D.h create mode 100644 src/util.cpp rename Hamster.h => src/util.h (86%) diff --git a/assets/hamster.png b/assets/hamster.png index af6ff59073f67c741a614418a548f9eb27202e2a..bc576dae4bfd474579130e107d937cdb49e8534c 100644 GIT binary patch delta 1134 zcmV-!1d;oz3HuDN(E$h%039$lqZGuG*#Rei1Z7D?K~#9!?c6bM+eR41@rNm!0P^Ue zMG+)(7iaMohyg7@!9jq>?peANodUOmTVyh_bn)J?K!6g47XsE7@DhK67)B8T^(X>S z6tIJQ#F0AEqIx7<>Hh-=OBBtMdGEbE9*>p)000000001MF7ULUtfO+^*#loYIypLj z*2&Rv<$K&up|2gCz2C|!e(%|-q*EQl`*&psGSIqYfN~&6(r?k9N|Q)w66xgVShLwI zUwk72wHE-{GCO+n`}cXJOVVH%YcP!S&*xb|3d6ARzLyQWv-ev%IXYIFMB00HY6oLh zu@C@vReqX8bqCNafnE7751+r4B+X`jvvLruMFv{us{j)O#g#j|dbIs2uguByp@NI^ z+R8WEmVzMgk%1)X#~=PEWFSehzx%`IZxx1N)ABdE6PTISG98bKk#ljbsYbFt&vth6 z&s-cWFIXk`Tmg7rGSE6@fXtOD?LaUG)&4Bo*;R0Hp8s@h*QE7V1z`C*e7t#o-Bt!7 z09IiKgB<{-B5zZ)w*aimK;;0mf*~LSv=jj4Ah0b_`74#*LIxrL{wvdBO@&yOhTa3f za|R*+(j;=G&s8%(gUY`T0l3lQ0D12_3`0%FBTdI6{r%yKg~fSkar-;woNNyWH97EA z9lxdlX!-?Ie#6Va!7$FRqvr>IFVN*x@v^)s2wdm>1_}XaUjOs$Uke+4^Yv$E0H#S) z2tey{lFDBq0D{3V&Rnhc$>SiCv=9iA^yG0+7$>j~{wn9(9s>}|v{F@%t@{{vui8hp z%#tQimL^gDT8#ZS?gakdgL6~slKO=(+rj4**vS>~acr-{o)QDL|SJ0e`%C?L6S71(u%K_xewu zdMuv|U_9D>wUBb{gWtBk%irh>U|ON1yd{<^rZi0JEd!Wg-et;P^+_Z$Kn?p@y(;Fj zwnpNr?gQB6GYZ%^QpdY|=WjNf6&AVg5PB_NHIILl*E0^#LICt!0e3xrShXEI^a1RC zKv3=%RIKmf{M%(&SfW(|lW_zilYj&e7{HqQ7g!JkKiwBZ6951J07*qoM6N<$f>(tm A)&Kwi delta 664 zcmV;J0%!gE466yS(E$h$7YPn|xeTh4*#Rei0+mTbK~#9!?btDE)L<9~@FyB7w4;ki z>F&}l{Q@m?&2Zr8M{sczClRN^#ihHWQ1B>S4%#o!so$U?qM)M(mXkQN3At;oy_`9% z*WV99uT3s@&GUbspFxEv?v{5JO~jHud??s=w~tLXR+Vijp1-uZf(<6sRQJ7t+E<~;-XgfyB$O`X>c&{5$;o{(4>=NC0MkQ4K>i z07W4$T6Ajxys86@2e1-`L%I^Ow7qw%V!1#e0f-a&-@%r1N50?&n_~2J<00;eSB!HFa zq~cEzfMj{6m)DKnwbdk#h)Y3;h*(=qM%D?c7k`#}?mrA5(~Q!XytdxPy8EPaiq_ + + @@ -344,16 +346,16 @@ if %errorlevel% neq 0 goto :VCEnd - - - - + + + + diff --git a/hamster.vcxproj.filters b/hamster.vcxproj.filters index 8f2c85d..f5759d1 100644 --- a/hamster.vcxproj.filters +++ b/hamster.vcxproj.filters @@ -10,6 +10,12 @@ Source Files + + Source Files + + + Source Files + @@ -52,7 +58,16 @@ Header Files - + + Header Files + + + Header Files + + + Header Files + + Header Files diff --git a/hamster.vcxproj.user b/hamster.vcxproj.user index 88a5509..211be52 100644 --- a/hamster.vcxproj.user +++ b/hamster.vcxproj.user @@ -1,4 +1,7 @@  - + + C:/Users/sigon/source/repos/hamster + WindowsLocalDebugger + \ No newline at end of file diff --git a/src/Hamster.cpp b/src/Hamster.cpp new file mode 100644 index 0000000..26300c2 --- /dev/null +++ b/src/Hamster.cpp @@ -0,0 +1,80 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +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. + +Portions of this software are copyright © 2024 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion + +#include "HamsterGame.h" +#include "Hamster.h" +#include "util.h" +#include + +std::vectorHamster::HAMSTER_LIST; +const uint8_t Hamster::NPC_HAMSTER_COUNT{5U}; +const std::vectorHamster::NPC_HAMSTER_IMAGES{ + "hamster.png", +}; +const std::string Hamster::PLAYER_HAMSTER_IMAGE{"hamster.png"}; + +Hamster::Hamster(const vf2d spawnPos,const std::string_view img,const PlayerControlled playerControlled) +:pos(spawnPos),playerControlled(playerControlled){ + animations=HamsterGame::GetAnimations(img); + animations.ChangeState(internalAnimState,HamsterGame::DEFAULT); +} + +void Hamster::UpdateHamsters(const float fElapsedTime){ + for(Hamster&h:HAMSTER_LIST){ + h.animations.UpdateState(h.internalAnimState,fElapsedTime); + } +} + +void Hamster::LoadHamsters(const vf2d startingLoc){ + HAMSTER_LIST.clear(); + HAMSTER_LIST.emplace_back(startingLoc,PLAYER_HAMSTER_IMAGE,PLAYER_CONTROLLED); + for(int i:std::ranges::iota_view(0U,NPC_HAMSTER_COUNT)){ + HAMSTER_LIST.emplace_back(startingLoc,NPC_HAMSTER_IMAGES.at(util::random()%NPC_HAMSTER_IMAGES.size()),NPC); + } +} + +void Hamster::DrawHamsters(const ViewPort&view){ + for(Hamster&h:HAMSTER_LIST){ + const Animate2D::Frame&img{h.GetCurrentAnimation()}; + view.DrawPartialRotatedDecal(h.pos,img.GetSourceImage()->Decal(),h.rot,img.GetSourceRect().size/2,img.GetSourceRect().pos,img.GetSourceRect().size); + } +} + +const Animate2D::Frame&Hamster::GetCurrentAnimation()const{ + return animations.GetFrame(internalAnimState); +} \ No newline at end of file diff --git a/src/Hamster.h b/src/Hamster.h new file mode 100644 index 0000000..4be0a0f --- /dev/null +++ b/src/Hamster.h @@ -0,0 +1,71 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +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. + +Portions of this software are copyright © 2024 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion +#pragma once + +#include +#include "olcUTIL_Geometry2D.h" +#include "olcUTIL_Animate2D.h" +#include "olcPGEX_ViewPort.h" + +class Hamster{ + enum PlayerControlled{ + PLAYER_CONTROLLED, + NPC, + }; + + static std::vectorHAMSTER_LIST; + + static const uint8_t NPC_HAMSTER_COUNT; + + static const std::vectorNPC_HAMSTER_IMAGES; + static const std::string PLAYER_HAMSTER_IMAGE; + + vf2d pos; + vf2d vel; + float rot{}; + std::string img; + Animate2D::Animationanimations; + Animate2D::AnimationState internalAnimState; + PlayerControlled playerControlled; +public: + Hamster(const vf2d spawnPos,const std::string_view img,const PlayerControlled playerControlled=NPC); + static void UpdateHamsters(const float fElapsedTime); + static void LoadHamsters(const vf2d startingLoc); + static void DrawHamsters(const ViewPort&view); + const Animate2D::Frame&GetCurrentAnimation()const; +}; \ No newline at end of file diff --git a/src/HamsterGame.cpp b/src/HamsterGame.cpp index 47a05a5..8bc05e0 100644 --- a/src/HamsterGame.cpp +++ b/src/HamsterGame.cpp @@ -1,8 +1,9 @@ #include "HamsterGame.h" +#include "Hamster.h" #include geom2d::rectHamsterGame::SCREEN_FRAME{{96,0},{320,288}}; -std::unordered_map>HamsterGame::ANIMATIONS; +std::unordered_map>HamsterGame::ANIMATIONS; std::unordered_mapHamsterGame::GFX; const std::string HamsterGame::ASSETS_DIR{"assets/"}; @@ -14,6 +15,7 @@ HamsterGame::HamsterGame() bool HamsterGame::OnUserCreate(){ LoadGraphics(); LoadAnimations(); + LoadLevel(); //THIS IS TEMPORARY. return true; } @@ -28,26 +30,43 @@ void HamsterGame::LoadGraphics(){ } void HamsterGame::LoadAnimations(){ - auto LoadStillAnimation=[this](const AnimationState state,const std::string_view img){ + auto LoadImageIfRequired=[this](const std::string_view img){if(!GFX.count(ASSETS_DIR+std::string(img)))_LoadImage(img);}; + auto LoadStillAnimation=[this,&LoadImageIfRequired](const AnimationState state,const std::string_view img){ Animate2D::FrameSequence stillAnimation{0.f,Animate2D::Style::OneShot}; - if(!GFX.count(ASSETS_DIR+std::string(img)))_LoadImage(img); + LoadImageIfRequired(img); stillAnimation.AddFrame(Animate2D::Frame{&GetGFX(img),{{},GetGFX(img).Sprite()->Size()}}); ANIMATIONS[ASSETS_DIR+std::string(img)].AddState(state,stillAnimation); }; - auto LoadAnimation=[this](const AnimationState state,const std::string_view img,const std::vectorframes,const float frameDuration=0.1f,const Animate2D::Style style=Animate2D::Style::Repeat,vf2d frameSize={32,32}){ - Animate2D::FrameSequence stillAnimation{0.f,Animate2D::Style::OneShot}; - if(!GFX.count(ASSETS_DIR+std::string(img)))_LoadImage(img); - stillAnimation.AddFrame(Animate2D::Frame{&GetGFX(img),{{},GetGFX(img).Sprite()->Size()}}); - ANIMATIONS[ASSETS_DIR+std::string(img)].AddState(state,stillAnimation); + auto LoadAnimation=[this,&LoadImageIfRequired](const AnimationState state,const std::string_view img,const std::vectorframes,const float frameDuration=0.1f,const Animate2D::Style style=Animate2D::Style::Repeat,vf2d frameSize={32,32}){ + Animate2D::FrameSequence newAnimation{frameDuration,style}; + LoadImageIfRequired(img); + for(const vf2d&framePos:frames){ + newAnimation.AddFrame(Animate2D::Frame{&GetGFX(img),{framePos,frameSize}}); + } + ANIMATIONS[ASSETS_DIR+std::string(img)].AddState(state,newAnimation); }; - LoadAnimation(DEFAULT,"hamster.png",{{},{0,32}},0.3f); + LoadAnimation(DEFAULT,"hamster.png",{{0,32},{32,32}},0.3f); } -bool HamsterGame::OnUserUpdate(float fElapsedTime){ +void HamsterGame::LoadLevel(){ + const vf2d levelSpawnLoc{50,50}; //TEMPORARY + Hamster::LoadHamsters(levelSpawnLoc); +} + +void HamsterGame::UpdateGame(const float fElapsedTime){ + Hamster::UpdateHamsters(fElapsedTime); +} + +void HamsterGame::DrawGame(){ DrawDecal({},GetGFX("border.png").Decal()); gameWindow.FillRectDecal({},{500.f,150.f},WHITE); + Hamster::DrawHamsters(gameWindow); +} +bool HamsterGame::OnUserUpdate(float fElapsedTime){ + UpdateGame(fElapsedTime); + DrawGame(); return true; } @@ -55,7 +74,7 @@ const Renderable&HamsterGame::GetGFX(const std::string_view img){ if(!GFX.count(ASSETS_DIR+std::string(img)))throw std::runtime_error{std::format("Image {} does not exist!",img)}; return GFX[ASSETS_DIR+std::string(img)]; } -const Animate2D::Animation&HamsterGame::GetAnimations(const std::string_view img){ +const Animate2D::Animation&HamsterGame::GetAnimations(const std::string_view img){ if(!ANIMATIONS.count(ASSETS_DIR+std::string(img)))throw std::runtime_error{std::format("Animations for {} does not exist!",img)}; return ANIMATIONS[ASSETS_DIR+std::string(img)]; } @@ -69,7 +88,7 @@ bool HamsterGame::OnUserDestroy(){ int main() { HamsterGame game; - if(game.Construct(512, 288, 2, 2)) + if(game.Construct(512, 288, 3, 3)) game.Start(); return 0; diff --git a/src/HamsterGame.h b/src/HamsterGame.h index ffe76f5..354d8aa 100644 --- a/src/HamsterGame.h +++ b/src/HamsterGame.h @@ -40,6 +40,7 @@ All rights reserved. #include "olcUTIL_Geometry2D.h" #include "olcUTIL_Animate2D.h" #include "olcPGEX_ViewPort.h" +#include "olcUTIL_Camera2D.h" class HamsterGame : public olc::PixelGameEngine { @@ -58,11 +59,15 @@ public: bool OnUserDestroy()override final; static const Renderable&GetGFX(const std::string_view img); - static const Animate2D::Animation&GetAnimations(const std::string_view img); + static const Animate2D::Animation&GetAnimations(const std::string_view img); private: + void UpdateGame(const float fElapsedTime); + void DrawGame(); + Camera2D camera; void LoadGraphics(); void LoadAnimations(); + void LoadLevel(); void _LoadImage(const std::string_view img); static std::unordered_mapGFX; - static std::unordered_map>ANIMATIONS; + static std::unordered_map>ANIMATIONS; }; \ No newline at end of file diff --git a/src/olcPGEX_ViewPort.h b/src/olcPGEX_ViewPort.h index b93a534..307b25e 100644 --- a/src/olcPGEX_ViewPort.h +++ b/src/olcPGEX_ViewPort.h @@ -505,8 +505,8 @@ void olc::ViewPort::DrawPolygonDecal(Decal *decal, void olc::ViewPort::DrawLineDecal(const vf2d &pos1, const vf2d &pos2, Pixel p) const { - vf2d posA = pos1 + offset; - vf2d posB = pos2 + offset; + vf2d posA = pos1; + vf2d posB = pos2; for (auto i = 0u; i < clipVertices.size(); i++) { auto clipA = clipVertices[i] - offset; @@ -640,8 +640,8 @@ void olc::ViewPort::drawClippedPolygonDecal(Decal *decal, std::vector outputDepths{depth, depth + elements}; for (auto i = 0u; i < clipVertices.size(); i++) { - auto clipA = clipVertices[i] + offset; - auto clipB = clipVertices[(i + 1) % clipVertices.size()] + offset; + auto clipA = clipVertices[i] - offset; + auto clipB = clipVertices[(i + 1) % clipVertices.size()] - offset; auto inputList{outputList}; auto inputUvs{outputUvs}; diff --git a/src/olcUTIL_Camera2D.h b/src/olcUTIL_Camera2D.h new file mode 100644 index 0000000..a482b78 --- /dev/null +++ b/src/olcUTIL_Camera2D.h @@ -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 }; + }; +} \ No newline at end of file diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..2a5607c --- /dev/null +++ b/src/util.cpp @@ -0,0 +1,18 @@ +#include "util.h" + +std::random_device rd; +std::mt19937 rng(rd()); + +float olc::util::random(float range){ + static std::uniform_real_distributiondistrib(0,1); + return distrib(rng)*range; +} + +int olc::util::random(){ + static std::uniform_int_distributiondistrib(0,32767); + return distrib(rng); +} + +const float olc::util::random_range(const float min,const float max){ + return random(max-min)+min; +} \ No newline at end of file diff --git a/Hamster.h b/src/util.h similarity index 86% rename from Hamster.h rename to src/util.h index fb4e9ce..ec3f6da 100644 --- a/Hamster.h +++ b/src/util.h @@ -36,9 +36,13 @@ All rights reserved. */ #pragma endregion #pragma once - -#include - -class Hamster{ - //static std::vectorHAMSTER_LIST; +#include + +namespace olc::util{ + //Returns 0-range (as a float). + float random(float range); + //Returns a random float value min(inclusive) to max(exclusive). + const float random_range(const float min,const float max); + //Returns 0-32767 (as an int). + int random(); }; \ No newline at end of file