From d3bc58923519b2f6ad3ae41ae0bbd700755e5825 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sat, 24 Aug 2024 21:57:31 -0500 Subject: [PATCH] Add loading screen. --- assets/PBData | 2 +- src/Hamster.cpp | 2 +- src/HamsterGame.cpp | 99 +++++++++++++++++++++----------------- src/HamsterGame.h | 9 +++- src/HamsterLeaderboard.cpp | 1 + src/Menu.cpp | 51 +++++++++++++++++++- src/Menu.h | 8 +++ 7 files changed, 123 insertions(+), 49 deletions(-) diff --git a/assets/PBData b/assets/PBData index 5ecd86b..238c6d1 100644 --- a/assets/PBData +++ b/assets/PBData @@ -1 +1 @@ -2147483647 2147483647 2147483647 2147483647 109086 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 \ No newline at end of file +48889 2147483647 2147483647 2147483647 109086 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 \ No newline at end of file diff --git a/src/Hamster.cpp b/src/Hamster.cpp index 00a6c59..27cfc5a 100644 --- a/src/Hamster.cpp +++ b/src/Hamster.cpp @@ -848,7 +848,7 @@ void Hamster::HandleAIControls(){ vf2d aimingDir{}; const HamsterAI::ActionOptRef¤tAction{ai.GetCurrentAction()}; - if(!currentAction.has_value())return; + if(!currentAction.has_value()){temporaryNode=ai.GetPreviousAction().value().get().pos;} const HamsterAI::Action&action{currentAction.value().get()}; if(aiNodeTime>GetAIAdjustNodeTime()){ diff --git a/src/HamsterGame.cpp b/src/HamsterGame.cpp index 745442e..b3b1d99 100644 --- a/src/HamsterGame.cpp +++ b/src/HamsterGame.cpp @@ -164,49 +164,22 @@ void HamsterGame::LoadLevel(const std::string&mapName){ camera.SetMode(Camera2D::Mode::LazyFollow); mapImage.Create(currentMap.value().GetData().GetMapData().width*16,currentMap.value().GetData().GetMapData().height*16); - SetDrawTarget(mapImage.Sprite()); - Clear(BLANK); - SetPixelMode(Pixel::MASK); - #pragma region Detect special tiles - { - std::vectormapPowerups; - std::vectorcheckpoints; - for(const LayerTag&layer:currentMap.value().GetData().GetLayers()){ - for(size_t y:std::ranges::iota_view(0U,layer.tiles.size())){ - for(size_t x:std::ranges::iota_view(0U,layer.tiles[y].size())){ - unsigned int tileID{(unsigned int)(layer.tiles[y][x]-1)}; - if(Powerup::TileIDIsUpperLeftPowerupTile(tileID))mapPowerups.emplace_back(vf2d{float(x),float(y)}*16+vf2d{16,16},Powerup::TileIDPowerupType(tileID)); - - if(tileID==1484)checkpoints.emplace_back(vf2d{float(x),float(y)}*16+vf2d{64,64}); - - const int numTilesWide{GetGFX("gametiles.png").Sprite()->width/16}; - const int numTilesTall{GetGFX("gametiles.png").Sprite()->height/16}; - - Sprite::Flip flip{Sprite::Flip::NONE}; - if(tileID&0x80'00'00'00)flip=Sprite::Flip::HORIZ; - - tileID&=0x7FFFFFFF; - - int imgTileX{int(tileID%numTilesWide)}; - int imgTileY{int(tileID/numTilesWide)}; - if(tileID==-1||Powerup::TileIDIsPowerupTile(tileID))continue; - DrawPartialSprite(vf2d{float(x),float(y)}*16,GetGFX("gametiles.png").Sprite(),vf2d{float(imgTileX),float(imgTileY)}*16.f,vf2d{16.f,16.f},1U,flip); - } - } - } - Powerup::Initialize(mapPowerups); - Checkpoint::Initialize(checkpoints); + mapPowerupsTemp.clear(); + checkpointsTemp.clear(); + + totalOperationsCount=0; + for(const LayerTag&layer:currentMap.value().GetData().GetLayers()){ + totalOperationsCount+=layer.tiles.size(); } - #pragma endregion - mapImage.Decal()->Update(); - SetPixelMode(Pixel::NORMAL); - SetDrawTarget(nullptr); + loadingMapLayerInd=0U; + loadingMapLayerTileY=0U; + + SetDrawTarget(mapImage.Sprite()); + Clear(BLANK); - audio.Play(bgm.at(currentMap.value().GetData().GetBGM()),true); - Hamster::MoveHamstersToSpawn(currentMap.value().GetData().GetSpawnZone()); - countdownTimer=3.f; + ProcessMap(); } void HamsterGame::UpdateGame(const float fElapsedTime){ @@ -215,6 +188,7 @@ void HamsterGame::UpdateGame(const float fElapsedTime){ if(countdownTimer<=0.f){ countdownTimer=0.f; leaderboard.OnRaceStart(); + net.StartRace(currentMapName); } } vEye.z+=(Hamster::GetPlayer().GetZ()+zoom-vEye.z)*fLazyFollowRate*fElapsedTime; @@ -236,7 +210,6 @@ void HamsterGame::UpdateGame(const float fElapsedTime){ Checkpoint::UpdateCheckpoints(fElapsedTime); FloatingText::UpdateFloatingText(fElapsedTime); leaderboard.Update(); - border.Update(fElapsedTime); } void HamsterGame::DrawGame(){ @@ -640,10 +613,8 @@ const HamsterGame::GameMode HamsterGame::GetGameMode(){ return mode; } -void HamsterGame::SetupAndStartRace(){ - LoadLevel("StageV.tmx"); //THIS IS TEMPORARY. - camera.SetTarget(Hamster::GetPlayer().GetPos()); - net.StartRace(currentMapName); +void HamsterGame::LoadRace(const std::string&mapName){ + LoadLevel(mapName); } const int HamsterGame::GetRaceTime(){ @@ -671,6 +642,46 @@ const std::string HamsterGame::PopNextMap(){ return frontMap; } +void HamsterGame::ProcessMap(){ + SetDrawTarget(mapImage.Sprite()); + SetPixelMode(Pixel::MASK); + + const LayerTag&layer{currentMap.value().GetData().GetLayers()[loadingMapLayerInd]}; + const size_t y{loadingMapLayerTileY}; + for(size_t x:std::ranges::iota_view(0U,layer.tiles[y].size())){ + unsigned int tileID{(unsigned int)(layer.tiles[y][x]-1)}; + if(Powerup::TileIDIsUpperLeftPowerupTile(tileID))mapPowerupsTemp.emplace_back(vf2d{float(x),float(y)}*16+vf2d{16,16},Powerup::TileIDPowerupType(tileID)); + + if(tileID==1484)checkpointsTemp.emplace_back(vf2d{float(x),float(y)}*16+vf2d{64,64}); + + const int numTilesWide{GetGFX("gametiles.png").Sprite()->width/16}; + const int numTilesTall{GetGFX("gametiles.png").Sprite()->height/16}; + + Sprite::Flip flip{Sprite::Flip::NONE}; + if(tileID&0x80'00'00'00)flip=Sprite::Flip::HORIZ; + + tileID&=0x7FFFFFFF; + + int imgTileX{int(tileID%numTilesWide)}; + int imgTileY{int(tileID/numTilesWide)}; + if(tileID==-1||Powerup::TileIDIsPowerupTile(tileID))continue; + DrawPartialSprite(vf2d{float(x),float(y)}*16,GetGFX("gametiles.png").Sprite(),vf2d{float(imgTileX),float(imgTileY)}*16.f,vf2d{16.f,16.f},1U,flip); + } + loadingMapLayerTileY++; + if(loadingMapLayerTileY>=layer.tiles.size()){ + loadingMapLayerInd++; + loadingMapLayerTileY=0; + } + if(loadingMapLayerInd>=currentMap.value().GetData().GetLayers().size()){ + operationsProgress=totalOperationsCount; + menu.OnLevelLoaded(); + } + operationsProgress++; + menu.UpdateLoadingProgress(float(operationsProgress)/totalOperationsCount); + SetPixelMode(Pixel::NORMAL); + SetDrawTarget(nullptr); +} + int main() { HamsterGame game("Project Hamster"); diff --git a/src/HamsterGame.h b/src/HamsterGame.h index cf89e75..d9c161a 100644 --- a/src/HamsterGame.h +++ b/src/HamsterGame.h @@ -110,6 +110,7 @@ public: void SetMapSetList(const std::queue&mapSet); const bool HasMoreMapsToPlay()const; const std::string PopNextMap(); + void ProcessMap(); private: void UpdateGame(const float fElapsedTime); void DrawGame(); @@ -122,7 +123,7 @@ private: static HamsterGame*self; Border border; void DrawLevelTiles(); - void SetupAndStartRace(); + void LoadRace(const std::string&mapName); std::optionalcurrentMap; std::optionalcurrentTileset; double runTime{}; @@ -186,4 +187,10 @@ private: HamsterLeaderboard leaderboard; std::queuemapSetList{}; Menu menu; + std::vectormapPowerupsTemp{}; + std::vectorcheckpointsTemp{}; + size_t loadingMapLayerInd; + size_t loadingMapLayerTileY; + int totalOperationsCount{}; + int operationsProgress{}; }; \ No newline at end of file diff --git a/src/HamsterLeaderboard.cpp b/src/HamsterLeaderboard.cpp index 58bc19b..8bcc817 100644 --- a/src/HamsterLeaderboard.cpp +++ b/src/HamsterLeaderboard.cpp @@ -95,6 +95,7 @@ void HamsterLeaderboard::Draw(HamsterGame&game){ std::string addonStr{"th"}; if(playerPlacement==1)addonStr="st"; else if(playerPlacement==2)addonStr="nd"; + else if(playerPlacement==3)addonStr="rd"; std::string placementStr{std::format("{}{}",playerPlacement,addonStr)}; vi2d placementStrSize{game.GetTextSizeProp(placementStr)}; Pixel blinkCol{DARK_RED}; diff --git a/src/Menu.cpp b/src/Menu.cpp index 9b890b0..9d95344 100644 --- a/src/Menu.cpp +++ b/src/Menu.cpp @@ -39,6 +39,7 @@ All rights reserved. #include "Menu.h" #include "HamsterGame.h" #include "util.h" +#include "Hamster.h" void Menu::UpdateAndDraw(HamsterGame&game,const float fElapsedTime){ menuTransitionRefreshTimer-=fElapsedTime; @@ -46,6 +47,7 @@ void Menu::UpdateAndDraw(HamsterGame&game,const float fElapsedTime){ menuTimer-=fElapsedTime; if(menuTimer<=0.f){ currentMenu=nextMenu; + OnMenuTransition(); } } @@ -62,8 +64,8 @@ void Menu::UpdateAndDraw(HamsterGame&game,const float fElapsedTime){ }break; case MAIN_MENU:{ if(game.GetKey(SPACE).bPressed||game.GetMouse(Mouse::LEFT).bPressed){ - Transition(FADE_OUT,GAMEPLAY,0.5f); - game.SetupAndStartRace(); + Transition(FADE_OUT,LOADING,0.5f); + selectedMap="StageV.tmx"; } }break; case GAMEPLAY:{ @@ -73,6 +75,9 @@ void Menu::UpdateAndDraw(HamsterGame&game,const float fElapsedTime){ case GAMEPLAY_RESULTS:{ game.DrawGame(); }break; + case LOADING:{ + if(loading)game.ProcessMap(); + }break; } if(menuTimer>0.f){ @@ -84,6 +89,7 @@ void Menu::UpdateAndDraw(HamsterGame&game,const float fElapsedTime){ game.SetDrawTarget(nullptr); Draw(game,currentMenu,game.SCREEN_FRAME.pos); } + game.border.Update(fElapsedTime); } void Menu::Transition(const TransitionType type,const MenuType gotoMenu,const float transitionTime){ if(menuTimer>0.f)return; @@ -91,6 +97,16 @@ void Menu::Transition(const TransitionType type,const MenuType gotoMenu,const fl nextMenu=gotoMenu; currentTransition=type; } +void Menu::OnMenuTransition(){ + switch(currentMenu){ + case LOADING:{ + colorNumb=util::random()%8+1; + loading=true; + loadingPct=0.f; + HamsterGame::Game().LoadRace(selectedMap); + }break; + } +} void Menu::DrawTransition(HamsterGame&game){ if(currentTransition==FADE_OUT){ if(menuTimer>=originalMenuTimer/2){//Fading out from old scene. @@ -160,5 +176,36 @@ void Menu::Draw(HamsterGame&game,const MenuType menu,const vi2d pos){ case GAMEPLAY_RESULTS:{ game.DrawGame(); }break; + case LOADING:{ + game.DrawPartialDecal(vi2d{pos},game.SCREEN_FRAME.size,game.GetGFX("background3.png").Decal(),vf2d{}+int(game.GetRuntime()*4),game.SCREEN_FRAME.size); + game.FillRectDecal(pos+vf2d{32.f,game.SCREEN_FRAME.size.y-64.f}+vf2d{2.f,2.f},vf2d{loadingPct*(game.SCREEN_FRAME.size.x-64),32.f},BLACK); + game.GradientFillRectDecal(pos+vf2d{32.f,game.SCREEN_FRAME.size.y-64.f},vf2d{loadingPct*(game.SCREEN_FRAME.size.x-64),32.f},{250,177,163},{255,224,194},{255,224,194},{250,177,163}); + int animationFrame{3}; + if(fmod(game.GetRuntime(),2.f)<0.5f)animationFrame=0; + else if(fmod(game.GetRuntime(),2.f)<1.f)animationFrame=2; + else if(fmod(game.GetRuntime(),2.f)<1.5f)animationFrame=0; + game.DrawPartialRotatedDecal(pos+vf2d{32.f,game.SCREEN_FRAME.size.y-64.f}+vf2d{loadingPct*(game.SCREEN_FRAME.size.x-64)-10.f,8.f},game.GetGFX(std::format("hamster{}.png",colorNumb)).Decal(),0.f,{16.f,16.f},vf2d{float(animationFrame*32),0.f},{32.f,32.f}); + }break; } +} + +void Menu::OnLevelLoaded(){ + loading=false; + + HamsterGame::Game().mapImage.Decal()->Update(); + + Powerup::Initialize(HamsterGame::Game().mapPowerupsTemp); + Checkpoint::Initialize(HamsterGame::Game().checkpointsTemp); + + HamsterGame::Game().audio.Play(HamsterGame::Game().bgm.at(HamsterGame::Game().currentMap.value().GetData().GetBGM()),true); + Hamster::MoveHamstersToSpawn(HamsterGame::Game().currentMap.value().GetData().GetSpawnZone()); + HamsterGame::Game().countdownTimer=3.f; + + HamsterGame::Game().camera.SetTarget(Hamster::GetPlayer().GetPos()); + + Transition(FADE_OUT,GAMEPLAY,0.5f); +} + +void Menu::UpdateLoadingProgress(const float pctLoaded){ + loadingPct=pctLoaded; } \ No newline at end of file diff --git a/src/Menu.h b/src/Menu.h index 3d36735..efc1fce 100644 --- a/src/Menu.h +++ b/src/Menu.h @@ -55,6 +55,7 @@ class Menu{ GAMEPLAY_RESULTS, AFTER_RACE_MENU, PAUSE, + LOADING, }; enum TransitionType{ SHIFT_LEFT, @@ -77,9 +78,16 @@ class Menu{ float originalMenuTimer{}; vi2d oldLayerPos{}; vi2d newLayerPos{}; + int colorNumb{1}; + bool loading{false}; + float loadingPct{0.f}; + std::string selectedMap{"StageI.tmx"}; void Transition(const TransitionType type,const MenuType gotoMenu,const float transitionTime); void Draw(HamsterGame&game,const MenuType menu,const vi2d pos); void DrawTransition(HamsterGame&game); + void OnMenuTransition(); public: void UpdateAndDraw(HamsterGame&game,const float fElapsedTime); + void OnLevelLoaded(); + void UpdateLoadingProgress(const float pctLoaded); }; \ No newline at end of file