diff --git a/assets/speedometer.png b/assets/speedometer.png new file mode 100644 index 0000000..72d2aac Binary files /dev/null and b/assets/speedometer.png differ diff --git a/assets/speedometer_overlay.png b/assets/speedometer_overlay.png new file mode 100644 index 0000000..ad5168b Binary files /dev/null and b/assets/speedometer_overlay.png differ diff --git a/src/Hamster.cpp b/src/Hamster.cpp index ad6d8a5..abec064 100644 --- a/src/Hamster.cpp +++ b/src/Hamster.cpp @@ -522,4 +522,8 @@ void Hamster::Knockout(){ state=KNOCKOUT; knockoutTimer=4.f; animations.ChangeState(internalAnimState,HamsterGame::KNOCKOUT); +} + +const float Hamster::GetSpeed()const{ + return vel.mag(); } \ No newline at end of file diff --git a/src/Hamster.h b/src/Hamster.h index de183ea..f9196ad 100644 --- a/src/Hamster.h +++ b/src/Hamster.h @@ -148,4 +148,5 @@ public: const vf2d GetNearestSafeLocation()const; void SetJetFuel(const float amt); void Knockout(); + const float GetSpeed()const; }; \ No newline at end of file diff --git a/src/HamsterGame.cpp b/src/HamsterGame.cpp index cb405a6..6bb2c17 100644 --- a/src/HamsterGame.cpp +++ b/src/HamsterGame.cpp @@ -53,6 +53,8 @@ void HamsterGame::LoadGraphics(){ _LoadImage("fuelmeter.png"); _LoadImage("fuelbar.png"); _LoadImage("fuelbar_outline.png"); + _LoadImage("speedometer.png"); + _LoadImage("speedometer_overlay.png"); UpdateMatrixTexture(); } @@ -137,6 +139,8 @@ void HamsterGame::LoadLevel(const std::string_view mapName){ } void HamsterGame::UpdateGame(const float fElapsedTime){ + vEye.z+=(Hamster::GetPlayer().GetZ()+zoom-vEye.z)*fLazyFollowRate*fElapsedTime; + speedometerDisplayAmt+=(Hamster::GetPlayer().GetSpeed()-speedometerDisplayAmt)*fLazyFollowRate*fElapsedTime; UpdateMatrixTexture(); UpdateWaterTexture(); cloudOffset+=cloudSpd*fElapsedTime; @@ -185,15 +189,34 @@ void HamsterGame::DrawGame(){ } #pragma endregion #pragma region Drown/Burn Bar. - if(Hamster::GetPlayer().IsDrowning()){ - DrawDecal({12.f,240.f},GetGFX("drownmeter.png").Decal()); - GradientFillRectDecal(vf2d{12.f,240.f}+vf2d{12.f,5.f},vf2d{Hamster::GetPlayer().GetDrownRatio()*57.f,4.f},{145,199,255},{226,228,255},{226,228,255},{145,199,255}); - } - else if(Hamster::GetPlayer().IsBurning()){ - DrawDecal({12.f,240.f},GetGFX("burnmeter.png").Decal()); - GradientFillRectDecal(vf2d{12.f,240.f}+vf2d{12.f,5.f},vf2d{Hamster::GetPlayer().GetBurnRatio()*57.f,4.f},{250,177,163},{226,228,255},{226,228,255},{250,177,163}); + { + if(Hamster::GetPlayer().IsDrowning()){ + DrawDecal({12.f,240.f},GetGFX("drownmeter.png").Decal()); + GradientFillRectDecal(vf2d{12.f,240.f}+vf2d{12.f,5.f},vf2d{Hamster::GetPlayer().GetDrownRatio()*57.f,4.f},{145,199,255},{226,228,255},{226,228,255},{145,199,255}); + } + else if(Hamster::GetPlayer().IsBurning()){ + DrawDecal({12.f,240.f},GetGFX("burnmeter.png").Decal()); + GradientFillRectDecal(vf2d{12.f,240.f}+vf2d{12.f,5.f},vf2d{Hamster::GetPlayer().GetBurnRatio()*57.f,4.f},{250,177,163},{226,228,255},{226,228,255},{250,177,163}); + } } #pragma endregion + float speedometerWidth{float(GetGFX("speedometer.png").Sprite()->width)}; + const float speedometerSpd{std::min(speedometerWidth,speedometerDisplayAmt/180.f*speedometerWidth)}; + DrawPartialRotatedDecal(SCREEN_FRAME.pos+SCREEN_FRAME.size+vf2d{48.f,-4.f-GetGFX("speedometer_overlay.png").Sprite()->height},GetGFX("speedometer_overlay.png").Decal(),0.f,GetGFX("speedometer_overlay.png").Sprite()->Size()/2,{},vf2d{speedometerSpd,float(GetGFX("speedometer_overlay.png").Sprite()->height)}); + DrawRotatedDecal(SCREEN_FRAME.pos+SCREEN_FRAME.size+vf2d{48.f,-4.f-GetGFX("speedometer.png").Sprite()->height},GetGFX("speedometer.png").Decal(),0.f,GetGFX("speedometer.png").Sprite()->Size()/2); + const std::string speedometerStr{std::format("{:.0f}km/h",speedometerDisplayAmt)}; + const vf2d speedometerStrSize{GetTextSize(speedometerStr)}; + Pixel speedometerCol{CYAN}; + if(speedometerDisplayAmt>=180)speedometerCol=RED; + else if(speedometerDisplayAmt>=120)speedometerCol=YELLOW; + else if(speedometerDisplayAmt>=80)speedometerCol=GREEN; + for(int y:std::ranges::iota_view(-1,2)){ + for(int x:std::ranges::iota_view(-1,2)){ + if(x==0&&y==0)continue; + DrawStringDecal(SCREEN_FRAME.pos+SCREEN_FRAME.size-speedometerStrSize-vf2d{4.f,4.f}+vi2d{x,y},speedometerStr,BLACK); + } + } + DrawStringDecal(SCREEN_FRAME.pos+SCREEN_FRAME.size-speedometerStrSize-vf2d{4.f,4.f},speedometerStr,speedometerCol); } const Terrain::TerrainType HamsterGame::GetTerrainTypeAtPos(const vf2d pos)const{ @@ -247,9 +270,6 @@ void HamsterGame::DrawLevelTiles(){ bool HamsterGame::OnUserUpdate(float fElapsedTime){ runTime+=fElapsedTime; - - vEye.z+=(Hamster::GetPlayer().GetZ()+zoom-vEye.z)*fLazyFollowRate*fElapsedTime; - UpdateGame(fElapsedTime); DrawGame(); return true; diff --git a/src/HamsterGame.h b/src/HamsterGame.h index 2fab5d7..d595d0a 100644 --- a/src/HamsterGame.h +++ b/src/HamsterGame.h @@ -118,4 +118,5 @@ private: const float fLazyFollowRate{4.0f}; vf2d cloudSpd{}; vf2d cloudOffset{}; + float speedometerDisplayAmt{0.f}; }; \ No newline at end of file