Add loading screen.

sigonasr2 6 months ago
parent 6c0490596a
commit d3bc589235
  1. 2
      assets/PBData
  2. 2
      src/Hamster.cpp
  3. 99
      src/HamsterGame.cpp
  4. 9
      src/HamsterGame.h
  5. 1
      src/HamsterLeaderboard.cpp
  6. 51
      src/Menu.cpp
  7. 8
      src/Menu.h

@ -1 +1 @@
2147483647 2147483647 2147483647 2147483647 109086 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647
48889 2147483647 2147483647 2147483647 109086 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647

@ -848,7 +848,7 @@ void Hamster::HandleAIControls(){
vf2d aimingDir{};
const HamsterAI::ActionOptRef&currentAction{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()){

@ -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::vector<Powerup>mapPowerups;
std::vector<vf2d>checkpoints;
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");

@ -110,6 +110,7 @@ public:
void SetMapSetList(const std::queue<std::string>&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::optional<TMXParser>currentMap;
std::optional<TSXParser>currentTileset;
double runTime{};
@ -186,4 +187,10 @@ private:
HamsterLeaderboard leaderboard;
std::queue<std::string>mapSetList{};
Menu menu;
std::vector<Powerup>mapPowerupsTemp{};
std::vector<vf2d>checkpointsTemp{};
size_t loadingMapLayerInd;
size_t loadingMapLayerTileY;
int totalOperationsCount{};
int operationsProgress{};
};

@ -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};

@ -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;
}

@ -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);
};
Loading…
Cancel
Save