Add checkpoint arrow indicators for offscreen checkpoints.

sigonasr2 3 months ago
parent 6ee7e293d5
commit 7eda510317
  1. BIN
      assets/checkpoint_arrow.png
  2. BIN
      assets/checkpoint_arrow.xcf
  3. 18
      src/Checkpoint.cpp
  4. 4
      src/Hamster.cpp
  5. 1
      src/Hamster.h
  6. 5
      src/HamsterGame.cpp
  7. 1
      src/HamsterGame.h
  8. 4
      src/util.cpp
  9. 3
      src/util.h

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

@ -38,6 +38,8 @@ All rights reserved.
#include "Checkpoint.h" #include "Checkpoint.h"
#include "HamsterGame.h" #include "HamsterGame.h"
#include "Hamster.h"
#include "util.h"
std::vector<Checkpoint>Checkpoint::checkpoints; std::vector<Checkpoint>Checkpoint::checkpoints;
Checkpoint::Checkpoint(const vf2d pos) Checkpoint::Checkpoint(const vf2d pos)
:pos(pos){ :pos(pos){
@ -71,6 +73,22 @@ void Checkpoint::DrawCheckpoints(TransformedView&tv){
HamsterGame::Game().SetDecalMode(DecalMode::NORMAL); HamsterGame::Game().SetDecalMode(DecalMode::NORMAL);
} }
tv.DrawPartialRotatedDecal(checkpoint.pos,frame.GetSourceImage()->Decal(),0.f,frame.GetSourceRect().size/2,frame.GetSourceRect().pos,frame.GetSourceRect().size); tv.DrawPartialRotatedDecal(checkpoint.pos,frame.GetSourceImage()->Decal(),0.f,frame.GetSourceRect().size/2,frame.GetSourceRect().pos,frame.GetSourceRect().size);
geom2d::line<float>playerToCheckpointLine{geom2d::line<float>(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::optional<vf2d>projCircle{geom2d::project(geom2d::circle<float>({},16),HamsterGame::SCREEN_FRAME,geom2d::ray<float>(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>&Checkpoint::GetCheckpoints(){ std::vector<Checkpoint>&Checkpoint::GetCheckpoints(){

@ -575,3 +575,7 @@ void Hamster::SetState(const HamsterState state){
const bool Hamster::CollectedAllCheckpoints()const{ const bool Hamster::CollectedAllCheckpoints()const{
return checkpointsCollected.size()==Checkpoint::GetCheckpoints().size(); return checkpointsCollected.size()==Checkpoint::GetCheckpoints().size();
} }
const bool Hamster::HasCollectedCheckpoint(const Checkpoint&cp)const{
return checkpointsCollected.contains(cp);
}

@ -158,4 +158,5 @@ public:
const Terrain::TerrainType GetTerrainHoveringOver()const; const Terrain::TerrainType GetTerrainHoveringOver()const;
void SetState(const HamsterState state); void SetState(const HamsterState state);
const bool CollectedAllCheckpoints()const; const bool CollectedAllCheckpoints()const;
const bool HasCollectedCheckpoint(const Checkpoint&cp)const;
}; };

@ -65,6 +65,7 @@ void HamsterGame::LoadGraphics(){
_LoadImage("speedometer.png"); _LoadImage("speedometer.png");
_LoadImage("speedometer_overlay.png"); _LoadImage("speedometer_overlay.png");
_LoadImage("radar.png"); _LoadImage("radar.png");
_LoadImage("checkpoint_arrow.png");
UpdateMatrixTexture(); 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); 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() int main()
{ {
HamsterGame game("Project Hamster"); HamsterGame game("Project Hamster");

@ -80,6 +80,7 @@ public:
void SetZoom(const float zoom); void SetZoom(const float zoom);
const float GetZoom()const; const float GetZoom()const;
const bool IsInBounds(const vf2d pos)const; const bool IsInBounds(const vf2d pos)const;
const float GetCameraZ()const;
private: private:
void UpdateGame(const float fElapsedTime); void UpdateGame(const float fElapsedTime);
void DrawGame(); void DrawGame();

@ -1,5 +1,4 @@
#include "util.h" #include "util.h"
#include "olcUTIL_Geometry2D.h"
std::random_device rd; std::random_device rd;
std::mt19937 rng(rd()); std::mt19937 rng(rd());
@ -54,3 +53,6 @@ float olc::util::lerp(float n1,float n2,double t){
float olc::util::degToRad(float deg){ float olc::util::degToRad(float deg){
return deg*(geom2d::pi/180); return deg*(geom2d::pi/180);
} }
vf2d olc::util::pointTo(vf2d posFrom,vf2d posTo){
return geom2d::line(posFrom,posTo).vector().norm();
}

@ -37,6 +37,7 @@ All rights reserved.
#pragma endregion #pragma endregion
#pragma once #pragma once
#include <random> #include <random>
#include "olcUTIL_Geometry2D.h"
namespace olc::util{ namespace olc::util{
//Returns 0-range (as a float). //Returns 0-range (as a float).
@ -49,4 +50,6 @@ namespace olc::util{
void turn_towards_direction(float&angle,float target,float rate); void turn_towards_direction(float&angle,float target,float rate);
float lerp(float n1,float n2,double t); float lerp(float n1,float n2,double t);
float degToRad(float deg); float degToRad(float deg);
//Returns a normalized vector pointing from posFrom towards posTo.
vf2d pointTo(vf2d posFrom,vf2d posTo);
}; };
Loading…
Cancel
Save