diff --git a/assets/checkpoint_arrow.png b/assets/checkpoint_arrow.png new file mode 100644 index 0000000..ce55739 Binary files /dev/null and b/assets/checkpoint_arrow.png differ diff --git a/assets/checkpoint_arrow.xcf b/assets/checkpoint_arrow.xcf new file mode 100644 index 0000000..e163923 Binary files /dev/null and b/assets/checkpoint_arrow.xcf differ diff --git a/src/Checkpoint.cpp b/src/Checkpoint.cpp index c999055..aa0b240 100644 --- a/src/Checkpoint.cpp +++ b/src/Checkpoint.cpp @@ -38,6 +38,8 @@ All rights reserved. #include "Checkpoint.h" #include "HamsterGame.h" +#include "Hamster.h" +#include "util.h" std::vectorCheckpoint::checkpoints; Checkpoint::Checkpoint(const vf2d pos) :pos(pos){ @@ -71,6 +73,22 @@ void Checkpoint::DrawCheckpoints(TransformedView&tv){ HamsterGame::Game().SetDecalMode(DecalMode::NORMAL); } tv.DrawPartialRotatedDecal(checkpoint.pos,frame.GetSourceImage()->Decal(),0.f,frame.GetSourceRect().size/2,frame.GetSourceRect().pos,frame.GetSourceRect().size); + geom2d::lineplayerToCheckpointLine{geom2d::line(Hamster::GetPlayer().GetPos(),checkpoint.pos)}; + + if(!Hamster::GetPlayer().HasCollectedCheckpoint(checkpoint)){ + const float screenDistance{playerToCheckpointLine.length()*(1.325f/(HamsterGame::Game().GetCameraZ()))}; + if(screenDistance>226){ + const vf2d dirVec{playerToCheckpointLine.vector().norm()}; + const float dir{dirVec.polar().y}; + std::optionalprojCircle{geom2d::project(geom2d::circle({},16),HamsterGame::SCREEN_FRAME,geom2d::ray(HamsterGame::SCREEN_FRAME.middle(),dirVec))}; + if(projCircle.has_value()){ + Pixel arrowCol{PixelLerp(GREEN,BLACK,std::clamp((screenDistance-226)/1000.f,0.f,1.f))}; + uint8_t iconAlpha{uint8_t(util::lerp(255.f,0.f,std::clamp((screenDistance-226)/1000.f,0.f,1.f)))}; + HamsterGame::Game().DrawPartialRotatedDecal(projCircle.value(),HamsterGame::GetGFX("checkpoint.png").Decal(),0.f,{64,64},{},{128,128},{0.125f,0.125f},{255,255,255,iconAlpha}); + HamsterGame::Game().DrawRotatedDecal(projCircle.value(),HamsterGame::GetGFX("checkpoint_arrow.png").Decal(),dir,HamsterGame::GetGFX("checkpoint_arrow.png").Sprite()->Size()/2,{1.f,1.f},arrowCol); + } + } + } } } std::vector&Checkpoint::GetCheckpoints(){ diff --git a/src/Hamster.cpp b/src/Hamster.cpp index 471e183..3e9a569 100644 --- a/src/Hamster.cpp +++ b/src/Hamster.cpp @@ -574,4 +574,8 @@ void Hamster::SetState(const HamsterState state){ const bool Hamster::CollectedAllCheckpoints()const{ return checkpointsCollected.size()==Checkpoint::GetCheckpoints().size(); +} + +const bool Hamster::HasCollectedCheckpoint(const Checkpoint&cp)const{ + return checkpointsCollected.contains(cp); } \ No newline at end of file diff --git a/src/Hamster.h b/src/Hamster.h index 825a02b..6705cf5 100644 --- a/src/Hamster.h +++ b/src/Hamster.h @@ -158,4 +158,5 @@ public: const Terrain::TerrainType GetTerrainHoveringOver()const; void SetState(const HamsterState state); const bool CollectedAllCheckpoints()const; + const bool HasCollectedCheckpoint(const Checkpoint&cp)const; }; \ No newline at end of file diff --git a/src/HamsterGame.cpp b/src/HamsterGame.cpp index 78c7655..1266921 100644 --- a/src/HamsterGame.cpp +++ b/src/HamsterGame.cpp @@ -65,6 +65,7 @@ void HamsterGame::LoadGraphics(){ _LoadImage("speedometer.png"); _LoadImage("speedometer_overlay.png"); _LoadImage("radar.png"); + _LoadImage("checkpoint_arrow.png"); UpdateMatrixTexture(); } @@ -487,6 +488,10 @@ const bool HamsterGame::IsInBounds(const vf2d pos)const{ return !(pos.x<=-160.f||pos.y<=-160.f||pos.x>=currentMap.value().GetData().GetMapData().width*16+160.f||pos.y>=currentMap.value().GetData().GetMapData().height*16+160.f); } +const float HamsterGame::GetCameraZ()const{ + return vEye.z; +} + int main() { HamsterGame game("Project Hamster"); diff --git a/src/HamsterGame.h b/src/HamsterGame.h index f1f49f1..599b8fa 100644 --- a/src/HamsterGame.h +++ b/src/HamsterGame.h @@ -80,6 +80,7 @@ public: void SetZoom(const float zoom); const float GetZoom()const; const bool IsInBounds(const vf2d pos)const; + const float GetCameraZ()const; private: void UpdateGame(const float fElapsedTime); void DrawGame(); diff --git a/src/util.cpp b/src/util.cpp index 8457b08..c993c82 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,5 +1,4 @@ #include "util.h" -#include "olcUTIL_Geometry2D.h" std::random_device rd; std::mt19937 rng(rd()); @@ -53,4 +52,7 @@ float olc::util::lerp(float n1,float n2,double t){ } float olc::util::degToRad(float deg){ return deg*(geom2d::pi/180); +} +vf2d olc::util::pointTo(vf2d posFrom,vf2d posTo){ + return geom2d::line(posFrom,posTo).vector().norm(); } \ No newline at end of file diff --git a/src/util.h b/src/util.h index c24bc8c..44ed90f 100644 --- a/src/util.h +++ b/src/util.h @@ -37,6 +37,7 @@ All rights reserved. #pragma endregion #pragma once #include +#include "olcUTIL_Geometry2D.h" namespace olc::util{ //Returns 0-range (as a float). @@ -49,4 +50,6 @@ namespace olc::util{ void turn_towards_direction(float&angle,float target,float rate); float lerp(float n1,float n2,double t); float degToRad(float deg); + //Returns a normalized vector pointing from posFrom towards posTo. + vf2d pointTo(vf2d posFrom,vf2d posTo); }; \ No newline at end of file