diff --git a/assets/hamster.png b/assets/hamster.png
index af6ff59..bc576da 100644
Binary files a/assets/hamster.png and b/assets/hamster.png differ
diff --git a/hamster.vcxproj b/hamster.vcxproj
index 6fa01d8..b0d8b16 100644
--- a/hamster.vcxproj
+++ b/hamster.vcxproj
@@ -324,6 +324,8 @@ if %errorlevel% neq 0 goto :VCEnd
+
+
@@ -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