From e2b5b873ef94338fc2036e54706009008563879f Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sat, 24 Aug 2024 03:02:17 -0500 Subject: [PATCH] Add in Hamster Net. Add timer parsing util function. Move around level initialization code. --- src/Checkpoint.cpp | 1 + src/HamsterGame.cpp | 21 +++- src/HamsterGame.h | 8 ++ src/HamsterNet.cpp | 2 +- src/olcPGEX_SplashScreen.h | 220 +++++++++++++++++++++++++++++++++++++ src/olcPixelGameEngine.cpp | 4 +- src/util.cpp | 24 ++++ src/util.h | 1 + 8 files changed, 274 insertions(+), 7 deletions(-) create mode 100644 src/olcPGEX_SplashScreen.h diff --git a/src/Checkpoint.cpp b/src/Checkpoint.cpp index d3b0b4b..ef61dc5 100644 --- a/src/Checkpoint.cpp +++ b/src/Checkpoint.cpp @@ -106,4 +106,5 @@ const vf2d&Checkpoint::GetPos()const{ void Checkpoint::OnCheckpointCollect(){ collectedByPlayerTimer=2.f; animation.ChangeState(internal_animState,AnimationState::CHECKPOINT_CYCLING); + if(Hamster::GetPlayer().CollectedAllCheckpoints())HamsterGame::Game().OnPlayerFinishedRace(); } \ No newline at end of file diff --git a/src/HamsterGame.cpp b/src/HamsterGame.cpp index 303c247..cbbdb40 100644 --- a/src/HamsterGame.cpp +++ b/src/HamsterGame.cpp @@ -42,11 +42,6 @@ bool HamsterGame::OnUserCreate(){ LoadSound("shiru8bit - A Little Journey.ogg"); LoadSound("nene - Boss Battle #3 Alternate.ogg"); LoadSound("nene - Boss Battle #5 V2.ogg"); - - LoadLevel("StageV.tmx"); //THIS IS TEMPORARY. - Hamster::CreateHamsters(mode); - Hamster::MoveHamstersToSpawn(currentMap.value().GetData().GetSpawnZone()); - camera.SetTarget(Hamster::GetPlayer().GetPos()); border.ChangeBorder(Border::DEFAULT); @@ -366,6 +361,18 @@ void HamsterGame::DrawLevelTiles(){ } bool HamsterGame::OnUserUpdate(float fElapsedTime){ + if(!netInitialized){ + net.InitSession(); + netInitialized=true; + + net.SetName("Sig"); + net.SetColor("Yellow"); + LoadLevel("StageV.tmx"); //THIS IS TEMPORARY. + Hamster::CreateHamsters(mode); + Hamster::MoveHamstersToSpawn(currentMap.value().GetData().GetSpawnZone()); + camera.SetTarget(Hamster::GetPlayer().GetPos()); + net.StartRace(currentMapName); + } runTime+=fElapsedTime; UpdateGame(fElapsedTime); DrawGame(); @@ -584,6 +591,10 @@ const Difficulty&HamsterGame::GetMapDifficulty()const{ return currentMap.value().GetData().GetMapDifficulty(); } +void HamsterGame::OnPlayerFinishedRace(){ + net.FinishRace(); +} + int main() { HamsterGame game("Project Hamster"); diff --git a/src/HamsterGame.h b/src/HamsterGame.h index c8e6e38..7014a30 100644 --- a/src/HamsterGame.h +++ b/src/HamsterGame.h @@ -50,6 +50,8 @@ All rights reserved. #include "olcPGEX_Viewport.h" #include "Difficulty.h" #include "olcPGEX_MiniAudio.h" +#include "HamsterNet.h" +#include "olcPGEX_SplashScreen.h" struct Letter{ vf2d pos; @@ -93,6 +95,7 @@ public: const std::string&GetCurrentMapName()const; virtual void OnTextEntryComplete(const std::string& sText)override; const Difficulty&GetMapDifficulty()const; + void OnPlayerFinishedRace(); private: void UpdateGame(const float fElapsedTime); void DrawGame(); @@ -130,4 +133,9 @@ private: MiniAudio audio; std::unordered_mapbgm; GameMode mode{GameMode::SINGLE_RACE}; + HamsterNet net; + #ifndef __EMSCRIPTEN__ + SplashScreen splash; + #endif + bool netInitialized{false}; }; \ No newline at end of file diff --git a/src/HamsterNet.cpp b/src/HamsterNet.cpp index 0fb1df9..594b471 100644 --- a/src/HamsterNet.cpp +++ b/src/HamsterNet.cpp @@ -287,7 +287,7 @@ std::vector HamsterNet::GetLeaderboard(const std::string& map, std::cout << "get leaderboard successful\n"; #else - std::cout << "HamsterNet::GetLeaderboard is not implemented for this platform\n" + std::cout << "HamsterNet::GetLeaderboard is not implemented for this platform\n"; #endif } diff --git a/src/olcPGEX_SplashScreen.h b/src/olcPGEX_SplashScreen.h new file mode 100644 index 0000000..a422f69 --- /dev/null +++ b/src/olcPGEX_SplashScreen.h @@ -0,0 +1,220 @@ +/* + olcPGEX_SplashScreen.h + + +-------------------------------------------------------------+ + | OneLoneCoder Pixel Game Engine Extension | + | Splash Screen v1.0 | + +-------------------------------------------------------------+ + + NOTE: UNDER ACTIVE DEVELOPMENT - THERE ARE BUGS/GLITCHES + + What is this? + ~~~~~~~~~~~~~ + This extension produces an animated splashscreen and copyright notice + at the beginning of a PGE application, for the purposes of remaining + OLC-3 compliant should it be ambiguous in your deployment. + + License (OLC-3) + ~~~~~~~~~~~~~~~ + + Copyright 2018 - 2024 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, 2023, 2024 + + Revisions: + 1.00: Initial Release +*/ + +#pragma once + +#include "olcPixelGameEngine.h" + +namespace olc +{ + class SplashScreen : public olc::PGEX + { + public: + SplashScreen(); + + protected: + virtual void OnAfterUserCreate() override; + virtual bool OnBeforeUserUpdate(float& fElapsedTime) override; + + private: + olc::Renderable spr; + std::vector> vBoom; + olc::vf2d vScale; + olc::vf2d vPosition; + float fParticleTime = 0.0f; + float fAspect = 0.0f; + bool bComplete = false; + }; + + +} + +#ifdef OLC_PGEX_SPLASHSCREEN +#undef OLC_PGEX_SPLASHSCREEN + +namespace olc +{ + SplashScreen::SplashScreen() : olc::PGEX(true) + { + } + + void SplashScreen::OnAfterUserCreate() + { + const char logo[] = + "000000000000000000000000000000000000000000000000000000000000000000005" + "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED1EE" + "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED5EEE" + "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE@E@000" + "0000000000000000000000000000000000000000000000000000000000001E1D:ZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ1D5BZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ5@E:P0002Z0" + "02ZZX000000000000ZP0000000000000000000000000000ZX000Z002XE1DX?o`o:Poo" + "800SooaE5@E1ED5BX?ol5E@E0E1ED?oo5@E1ED5DE1D5E@ZQEEBPEE2QD5BSooclZ?olQ" + "AB?oo5DEEDEEDE:SooaEEAE5DEEDoolEADEEDEAE5AEEBZ5EE:5EE:5@E:?oo?bXoob55" + "8o3lEAEEAD5ADZ?oo5@E5EEAD5Cl01E5AD5AE5DE5@E:X01DXEEDXE1DXo3lo:Sl0800S" + "ooaE1ED5EE5BXo00EEDEEE5EE?oo5EE5EE5DEEDEEDZQEEBQD5BQD5BSl?cl0?`0ZZZ?o" + "o5D5E@EEDE03loaEEAEEDEEDoolEED5EDEAEEAEEBZ5EE:5@E:5@E:?oo?oloob008o00" + "EAEEAD01EE?co5EE5EEAD03l01DE@05AE5AE5@0:XE000EEDXE1DXooloocoo8DDSlZQE" + "5EE5EE5EDoolE1DE4E5EE?oo5AE5EE5DE5DEEDZQEEAAEEBQD5BPoo3oo3olQAB?bZ5DE" + "1D5EDEE@ooaD5AD1D5EDoolE1DEE@EAD5@EEBZ5EE51ED:5@E:P000000020080:X0000" + "00000000000000000000000000000000000:X0000002XE1DZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZQD5@ZZZZZZZZZZZZZZZZZZZZZZ" + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZX5@E@00000000000000000000000" + "00000000000000000000000000000000000000001E1EEEEEEEEEEEEEEEEEEEEEEEEEE" + "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED5EEEEEEEEEEEEEEEEEEEEEEEEEEE" + "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE@5EEEEEEEEEEEEEEEEEEEEEEEEEEEE" + "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED0000000000000000000000000000000" + "0000000000000000000000000000000000000"; + + spr.Create(203, 24); + int px = 0, py = 0; + for (size_t b = 0; b < 1624; b += 4) + { + uint32_t sym1 = (uint32_t)logo[b + 0] - 48; + uint32_t sym2 = (uint32_t)logo[b + 1] - 48; + uint32_t sym3 = (uint32_t)logo[b + 2] - 48; + uint32_t sym4 = (uint32_t)logo[b + 3] - 48; + uint32_t r = sym1 << 18 | sym2 << 12 | sym3 << 6 | sym4; + + for (int i = 0; i < 12; i++) + { + olc::Pixel p = olc::RED; + switch ((r & 0xC00000) >> 22) + { + case 0: p = olc::Pixel(0, 0, 0, 255); break; + case 1: p = olc::Pixel(255, 255, 255, 255); break; + case 2: p = olc::Pixel(255, 120, 26, 255); break; + case 3: p = olc::Pixel(79, 193, 255, 255); break; + } + spr.Sprite()->SetPixel(px, py, p); + if (++px == 203) { py++; px = 0; } + r <<= 2; + } + } + + spr.Decal()->Update(); + vBoom.resize(spr.Sprite()->width * spr.Sprite()->height); + vScale = { float(pge->ScreenWidth()) / 500.0f, float(pge->ScreenWidth()) / 500.0f }; + fAspect = float(pge->ScreenWidth()) / float(pge->ScreenHeight()); + vPosition = olc::vf2d( + (250 - spr.Sprite()->width) / 2.0f, + (250 - spr.Sprite()->height) / 2.0f / fAspect); + for (int y = 0; y < spr.Sprite()->height; y++) + for (int x = 0; x < spr.Sprite()->width; x++) + vBoom[y * spr.Sprite()->width + x] = std::make_pair( + vPosition + olc::vf2d(x, y), + olc::vf2d( + (float(rand()) / float(RAND_MAX)) * 10.0f - 5.0f, + (float(rand()) / float(RAND_MAX)) * 10.0f - 5.0f) + ); + } + + bool SplashScreen::OnBeforeUserUpdate(float& fElapsedTime) + { + if (bComplete) return false; + + fParticleTime += fElapsedTime; + + for (int y = 0; y < spr.Sprite()->height; y++) + for (int x = 0; x < spr.Sprite()->width; x++) + { + + + if (fParticleTime < 1.0f) + { + + } + else if (fParticleTime < 2.0f) + { + vBoom[y * spr.Sprite()->width + x].first = + olc::vf2d( + (250 - spr.Sprite()->width) / 2.0f + float(x), + (250 - spr.Sprite()->height) / 2.0f / fAspect + float(y) + ) + + olc::vf2d( + (float(rand()) / float(RAND_MAX)) * 0.5f - 0.25f, + (float(rand()) / float(RAND_MAX)) * 0.5f - 0.25f); + } + else if(fParticleTime < 5.0f) + { + vBoom[y * spr.Sprite()->width + x].first += vBoom[y * spr.Sprite()->width + x].second * fElapsedTime * 20.0f; + } + else + { + bComplete = true; + } + + pge->DrawPartialDecal(vScale * vBoom[y * spr.Sprite()->width + x].first * 2.0f, spr.Decal(), olc::vf2d(x, y), { 1, 1 }, vScale * 2.0f, olc::PixelF(1.0f, 1.0f, 1.0f, std::min(1.0f, std::max(4.0f - fParticleTime, 0.0f)))); + } + + olc::vi2d vSize = pge->GetTextSizeProp("Copyright OneLoneCoder.com 2024"); + pge->DrawStringPropDecal(olc::vf2d(float(pge->ScreenWidth()/2) - vSize.x/2, float(pge->ScreenHeight()) - vSize.y * 3.0f), "Copyright OneLoneCoder.com 2023", olc::PixelF(1.0f, 1.0f, 1.0f, 0.5f), olc::vf2d(1.0, 2.0f)); + return true; + } + +} + +#endif \ No newline at end of file diff --git a/src/olcPixelGameEngine.cpp b/src/olcPixelGameEngine.cpp index 074c5d1..eea994a 100644 --- a/src/olcPixelGameEngine.cpp +++ b/src/olcPixelGameEngine.cpp @@ -10,4 +10,6 @@ #define OLC_PGEX_GRAPHICS3D #include "olcPGEX_Graphics3D.h" #define OLC_PGEX_VIEWPORT -#include "olcPGEX_Viewport.h" \ No newline at end of file +#include "olcPGEX_Viewport.h" +#define OLC_PGEX_SPLASHSCREEN +#include "olcPGEX_SplashScreen.h" \ No newline at end of file diff --git a/src/util.cpp b/src/util.cpp index c993c82..ae2d0b4 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -55,4 +55,28 @@ float olc::util::degToRad(float deg){ } vf2d olc::util::pointTo(vf2d posFrom,vf2d posTo){ return geom2d::line(posFrom,posTo).vector().norm(); +} +std::string olc::util::timerStr(int ms){ + int millis=ms%1000; + int seconds=ms/1000; + int hours=seconds/3600; + int minutes=seconds/60; + + std::string timeStr=""; + if(hours>0){ + if(hours<10)timeStr+="0"; + timeStr+=std::to_string(hours)+":"; + } + + if(minutes%60<10)timeStr+="0"; + timeStr+=std::to_string(minutes%60)+":"; + + if(seconds%60<10)timeStr+="0"; + timeStr+=std::to_string(seconds%60)+"."; + + if(millis<100)timeStr+="0"; + if(millis<10)timeStr+="0"; + timeStr+=std::to_string(millis); + + return timeStr; } \ No newline at end of file diff --git a/src/util.h b/src/util.h index 44ed90f..b3f35fb 100644 --- a/src/util.h +++ b/src/util.h @@ -52,4 +52,5 @@ namespace olc::util{ float degToRad(float deg); //Returns a normalized vector pointing from posFrom towards posTo. vf2d pointTo(vf2d posFrom,vf2d posTo); + std::string timerStr(int ms); }; \ No newline at end of file