diff --git a/src/FloatingText.cpp b/src/FloatingText.cpp new file mode 100644 index 0000000..8ca06d9 --- /dev/null +++ b/src/FloatingText.cpp @@ -0,0 +1,87 @@ +#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 "FloatingText.h" +#include "HamsterGame.h" +#include "util.h" +#include + +std::vectorFloatingText::floatingText; + +FloatingText::FloatingText(const vf2d&pos,const std::string&text,const std::vector&colorCycle,const vf2d&scale) +:pos(pos),text(text),colorCycle(colorCycle),lifetime(4.f),scale(scale){} +void FloatingText::UpdateFloatingText(const float fElapsedTime){ + for(FloatingText&floatingText:FloatingText::floatingText){ + floatingText.Update(fElapsedTime); + } +} +void FloatingText::Update(const float fElapsedTime){ + lifetime-=fElapsedTime; + lastColorChange-=fElapsedTime; + if(lastColorChange<=0.f){ + lastColorChange=0.5f; + colorCycleInd++; + } + if(lifetime>1.f){ + pos.y-=16.f*fElapsedTime; + } +} +void FloatingText::DrawFloatingText(TransformedView&tv){ + for(FloatingText&floatingText:FloatingText::floatingText){ + floatingText.Draw(tv); + } + std::erase_if(floatingText,[](const FloatingText&floatingText){return floatingText.lifetime<=0.f;}); +} +void FloatingText::Draw(TransformedView&tv){ + const Pixel¤tCol{colorCycle[colorCycleInd%colorCycle.size()]}; + + const vf2d strSize{HamsterGame::Game().GetTextSize(text)}; + + uint8_t alpha{uint8_t(util::lerp(0U,255U,lifetime/4.f))}; + + for(int y:std::ranges::iota_view(-1,2)){ + for(int x:std::ranges::iota_view(-1,2)){ + tv.DrawRotatedStringDecal(pos+vi2d{x,y},text,0.f,strSize/2,{0,0,0,alpha},scale); + } + } + HamsterGame::Game().SetZ(0.01f); + tv.DrawRotatedStringDecal(pos,text,0.f,strSize/2,{currentCol.r,currentCol.g,currentCol.b,uint8_t(currentCol.a*(alpha/255.f))},scale); + HamsterGame::Game().SetZ(0.f); +} +void FloatingText::CreateFloatingText(const vf2d&pos,const std::string&text,const std::vector&colorCycle,const vf2d&scale){ + floatingText.emplace_back(pos,text,colorCycle,scale); +} \ No newline at end of file diff --git a/src/FloatingText.h b/src/FloatingText.h new file mode 100644 index 0000000..4d18ce6 --- /dev/null +++ b/src/FloatingText.h @@ -0,0 +1,56 @@ +#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 "olcPGEX_TransformedView.h" +class FloatingText{ + vf2d pos; + float lifetime; + std::string text; + vf2d scale; + float lastColorChange{0.5f}; + size_t colorCycleInd{}; + std::vectorcolorCycle; + static std::vectorfloatingText; +public: + FloatingText(const vf2d&pos,const std::string&text,const std::vector&colorCycle={WHITE},const vf2d&scale={1.f,1.f}); + static void UpdateFloatingText(const float fElapsedTime); + void Update(const float fElapsedTime); + static void DrawFloatingText(TransformedView&tv); + void Draw(TransformedView&tv); + static void CreateFloatingText(const vf2d&pos,const std::string&text,const std::vector&colorCycle={WHITE},const vf2d&scale={1.f,1.f}); +}; \ No newline at end of file diff --git a/src/Hamster.cpp b/src/Hamster.cpp index 1cb52a8..471e183 100644 --- a/src/Hamster.cpp +++ b/src/Hamster.cpp @@ -41,6 +41,7 @@ All rights reserved. #include "util.h" #include #include "AnimationState.h" +#include "FloatingText.h" std::vectorHamster::HAMSTER_LIST; const uint8_t Hamster::MAX_HAMSTER_COUNT{100U}; @@ -351,6 +352,7 @@ void Hamster::HandleCollision(){ for(Checkpoint&checkpoint:Checkpoint::GetCheckpoints()){ if(z<=0.1f&&geom2d::overlaps(geom2d::rect(checkpoint.GetPos()-vf2d{62,60},{122.f,113.f}),geom2d::circle(GetPos(),collisionRadius))&&!checkpointsCollected.count(checkpoint)){ checkpointsCollected.insert(checkpoint); + FloatingText::CreateFloatingText(pos,std::format("{} / {}",checkpointsCollected.size(),Checkpoint::GetCheckpoints().size()),{WHITE,GREEN},{1.5f,2.f}); checkpoint.OnCheckpointCollect(); } } diff --git a/src/Hamster.h b/src/Hamster.h index 8352419..825a02b 100644 --- a/src/Hamster.h +++ b/src/Hamster.h @@ -46,6 +46,8 @@ All rights reserved. #include "HamsterGame.h" #include "Checkpoint.h" +using Timer=float; + class Hamster{ friend class HamsterJet; enum PlayerControlled{ @@ -113,6 +115,7 @@ class Hamster{ float knockoutTimer{0.f}; std::unordered_setcheckpointsCollected; float raceFinishAnimTimer{0.f}; + std::paircollectedCheckpointInfo{INFINITY,{}}; public: Hamster(const vf2d spawnPos,const std::string&img,const PlayerControlled IsPlayerControlled=NPC); static const Hamster&GetPlayer(); diff --git a/src/HamsterGame.cpp b/src/HamsterGame.cpp index ec0ae59..df4f946 100644 --- a/src/HamsterGame.cpp +++ b/src/HamsterGame.cpp @@ -4,6 +4,7 @@ #include #include "util.h" #include "Checkpoint.h" +#include "FloatingText.h" geom2d::rectHamsterGame::SCREEN_FRAME{{96,0},{320,288}}; std::unordered_map>HamsterGame::ANIMATIONS; @@ -161,6 +162,7 @@ void HamsterGame::UpdateGame(const float fElapsedTime){ Hamster::UpdateHamsters(fElapsedTime); Powerup::UpdatePowerups(fElapsedTime); Checkpoint::UpdateCheckpoints(fElapsedTime); + FloatingText::UpdateFloatingText(fElapsedTime); border.Update(fElapsedTime); } @@ -181,6 +183,7 @@ void HamsterGame::DrawGame(){ SetZ(6.f); tv.DrawPartialDecal({-3200,-3200},currentMap.value().GetData().GetMapData().MapSize*16+vf2d{6400,6400},GetGFX("clouds.png").Decal(),cloudOffset*2,currentMap.value().GetData().GetMapData().MapSize*16/2.f,{255,255,255,72}); SetZ(0.f); + FloatingText::DrawFloatingText(tv); border.Draw(); Hamster::DrawOverlay(); #pragma region Powerup Display diff --git a/src/olcPGEX_TransformedView.h b/src/olcPGEX_TransformedView.h index d9bdd96..e97075d 100644 --- a/src/olcPGEX_TransformedView.h +++ b/src/olcPGEX_TransformedView.h @@ -192,6 +192,10 @@ namespace olc // Draws a multiline string as a decal, with tiniting and scaling void DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); void DrawStringPropDecal(const olc::vf2d& pos, const std::string& sText, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); + + void DrawRotatedStringDecal(const olc::vf2d& pos, const std::string& sText, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); + void DrawRotatedStringPropDecal(const olc::vf2d& pos, const std::string& sText, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); + // Draws a single shaded filled rectangle as a decal void FillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE); void DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE); @@ -702,6 +706,12 @@ namespace olc pge->DrawPolygonDecal(decal, vTransformed, uv, colours, tint,GFX3DTransform::TRANSFORM_REQUIRED); } + void TransformedView::DrawRotatedStringDecal(const olc::vf2d& pos, const std::string& sText, const float fAngle, const olc::vf2d& center, const olc::Pixel col, const olc::vf2d& scale){ + pge->DrawRotatedStringDecal(WorldToScreen(pos),sText,fAngle,center,col,scale*m_vWorldScale*m_vRecipPixel,GFX3DTransform::TRANSFORM_REQUIRED); + } + void TransformedView::DrawRotatedStringPropDecal(const olc::vf2d& pos, const std::string& sText, const float fAngle, const olc::vf2d& center, const olc::Pixel col, const olc::vf2d& scale){ + pge->DrawRotatedStringPropDecal(WorldToScreen(pos),sText,fAngle,center,col,scale*m_vWorldScale*m_vRecipPixel,GFX3DTransform::TRANSFORM_REQUIRED); + } #if defined (OLC_PGEX_SHADER) diff --git a/src/olcPixelGameEngine.h b/src/olcPixelGameEngine.h index a59a7cd..54155ac 100644 --- a/src/olcPixelGameEngine.h +++ b/src/olcPixelGameEngine.h @@ -374,6 +374,8 @@ int main() */ #pragma endregion +#include "olcUTIL_Geometry2D.h" + #ifndef OLC_PGE_DEF #define OLC_PGE_DEF