Prepare sound effects, add leaderboard display for single races.

sigonasr2 6 months ago
parent c3fc8ec00a
commit 9b507e9471
  1. 2
      assets/PBData
  2. BIN
      assets/button3.png
  3. BIN
      assets/highlight_button3.png
  4. BIN
      assets/sounds/cannot_launch_jet.wav
  5. BIN
      assets/sounds/checkpoint_collection.wav
  6. BIN
      assets/sounds/collect_powerup.wav
  7. BIN
      assets/sounds/countdown.wav
  8. BIN
      assets/sounds/drown_burn.wav
  9. BIN
      assets/sounds/hit_hamster.wav
  10. BIN
      assets/sounds/hit_hamster_2.wav
  11. BIN
      assets/sounds/jet_land.wav
  12. BIN
      assets/sounds/menu_hover.wav
  13. BIN
      assets/sounds/menu_set_name.wav
  14. BIN
      assets/sounds/obtain_jet.wav
  15. BIN
      assets/sounds/select_track_confirm_name_menu.wav
  16. BIN
      assets/sounds/sfx_movement_footsteps1a.wav
  17. BIN
      assets/sounds/sfx_movement_footsteps1b.wav
  18. BIN
      assets/sounds/sfx_sounds_falling7.wav
  19. BIN
      assets/sounds/start_race_whistle.wav
  20. BIN
      assets/sounds/wheel_boost.wav
  21. 7
      src/Hamster.cpp
  22. 1
      src/HamsterAI.cpp
  23. 4
      src/HamsterGame.cpp
  24. 25
      src/HamsterGame.h
  25. 91
      src/Menu.cpp
  26. 3
      src/Menu.h
  27. 2
      src/TODO.txt

@ -1 +1 @@
2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 0.7 0.6 OneLoneHam Black 44669 64212 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 0.7 0.6 OneLoneHam Black

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 B

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 787 B

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -231,9 +231,9 @@ void Hamster::CreateHamsters(const HamsterGame::GameMode mode){
playerHamster.reset(); playerHamster.reset();
HAMSTER_LIST.reserve(MAX_HAMSTER_COUNT); HAMSTER_LIST.reserve(MAX_HAMSTER_COUNT);
if(NPC_HAMSTER_COUNT+1>MAX_HAMSTER_COUNT)throw std::runtime_error{std::format("WARNING! Max hamster count is too high! Please expand the MAX_HAMSTER_COUNT if you want more hamsters. Requested {} hamsters.",MAX_HAMSTER_COUNT)}; if(NPC_HAMSTER_COUNT+1>MAX_HAMSTER_COUNT)throw std::runtime_error{std::format("WARNING! Max hamster count is too high! Please expand the MAX_HAMSTER_COUNT if you want more hamsters. Requested {} hamsters.",MAX_HAMSTER_COUNT)};
playerHamster=&HAMSTER_LIST.emplace_back(vf2d{},HamsterGame::Game().GetPlayerHamsterImage(),PLAYER_CONTROLLED); playerHamster=&HAMSTER_LIST.emplace_back(vf2d{},HamsterGame::Game().ColorToHamsterImage(HamsterGame::Game().hamsterColor),PLAYER_CONTROLLED);
std::vector<std::string>hamsterColorChoices{NPC_HAMSTER_IMAGES}; std::vector<std::string>hamsterColorChoices{NPC_HAMSTER_IMAGES};
std::erase(hamsterColorChoices,HamsterGame::Game().GetPlayerHamsterImage()); std::erase(hamsterColorChoices,HamsterGame::Game().ColorToHamsterImage(HamsterGame::Game().hamsterColor));
for(int i:std::ranges::iota_view(0U,NPC_HAMSTER_COUNT)){ for(int i:std::ranges::iota_view(0U,NPC_HAMSTER_COUNT)){
std::string colorChoice{hamsterColorChoices.at(util::random()%hamsterColorChoices.size())}; std::string colorChoice{hamsterColorChoices.at(util::random()%hamsterColorChoices.size())};
std::erase(hamsterColorChoices,colorChoice); std::erase(hamsterColorChoices,colorChoice);
@ -848,8 +848,9 @@ void Hamster::HandleAIControls(){
vf2d aimingDir{}; vf2d aimingDir{};
const HamsterAI::ActionOptRef&currentAction{ai.GetCurrentAction()}; const HamsterAI::ActionOptRef&currentAction{ai.GetCurrentAction()};
HamsterAI::Action action;
if(!currentAction.has_value()){temporaryNode=ai.GetPreviousAction().value().get().pos;} if(!currentAction.has_value()){temporaryNode=ai.GetPreviousAction().value().get().pos;}
const HamsterAI::Action&action{currentAction.value().get()}; else action=currentAction.value().get();
if(aiNodeTime>GetAIAdjustNodeTime()){ if(aiNodeTime>GetAIAdjustNodeTime()){
geom2d::line<float>playerToHamster{GetPlayer().GetPos(),GetPos()}; geom2d::line<float>playerToHamster{GetPlayer().GetPos(),GetPos()};

@ -134,6 +134,7 @@ void HamsterAI::OnJetBeginLanding(const vi2d pos){
const HamsterAI::ActionOptRef HamsterAI::GetPreviousAction(){ const HamsterAI::ActionOptRef HamsterAI::GetPreviousAction(){
if(actionInd-1>0)return actionsToPerform[actionInd-1]; if(actionInd-1>0)return actionsToPerform[actionInd-1];
if(actionsToPerform.size()>0)return actionsToPerform[actionsToPerform.size()-1];
return {}; return {};
} }
const HamsterAI::ActionOptRef HamsterAI::RevertToPreviousAction(){ const HamsterAI::ActionOptRef HamsterAI::RevertToPreviousAction(){

@ -772,8 +772,8 @@ void HamsterGame::QuitGame(){
gameIsRunning=false; gameIsRunning=false;
} }
const std::string&HamsterGame::GetPlayerHamsterImage()const{ const std::string HamsterGame::ColorToHamsterImage(const std::string&color)const{
return std::format("hamster{}.png",std::distance(hamsterColorNames.begin(),std::find(hamsterColorNames.begin(),hamsterColorNames.end(),hamsterColor))+1); return std::format("hamster{}.png",std::distance(hamsterColorNames.begin(),std::find(hamsterColorNames.begin(),hamsterColorNames.end(),color))+1);
} }
int main() int main()

@ -78,6 +78,17 @@ public:
HamsterGame(const std::string&appName); HamsterGame(const std::string&appName);
static geom2d::rect<float>SCREEN_FRAME; static geom2d::rect<float>SCREEN_FRAME;
TransformedView tv{}; TransformedView tv{};
private:
std::vector<std::string>hamsterColorNames{
"Yellow",
"Pink",
"Cyan",
"Black",
"Green",
"Purple"
"Red",
"Blue",
};
public: public:
bool OnUserCreate()override final; bool OnUserCreate()override final;
bool OnUserUpdate(float fElapsedTime)override final; bool OnUserUpdate(float fElapsedTime)override final;
@ -114,7 +125,8 @@ public:
void QuitGame(); void QuitGame();
std::string playerName{"OneLoneHamster"}; std::string playerName{"OneLoneHamster"};
void SaveOptions(); void SaveOptions();
const std::string&GetPlayerHamsterImage()const; const std::string ColorToHamsterImage(const std::string&color)const;
std::string hamsterColor{hamsterColorNames[0]};
private: private:
void UpdateGame(const float fElapsedTime); void UpdateGame(const float fElapsedTime);
void DrawGame(); void DrawGame();
@ -160,16 +172,6 @@ private:
#endif #endif
#endif #endif
bool netInitialized{false}; bool netInitialized{false};
std::vector<std::string>hamsterColorNames{
"Yellow",
"Pink",
"Cyan",
"Black",
"Green",
"Purple"
"Red",
"Blue",
};
std::vector<std::string>mapNameList{ std::vector<std::string>mapNameList{
"StageI.tmx", "StageI.tmx",
"StageII.tmx", "StageII.tmx",
@ -205,5 +207,4 @@ private:
std::string hamsterColorLabel{"hamsterColor"}; std::string hamsterColorLabel{"hamsterColor"};
float bgmVol{0.7f}; float bgmVol{0.7f};
float sfxVol{0.7f}; float sfxVol{0.7f};
std::string hamsterColor{hamsterColorNames[0]};
}; };

@ -130,12 +130,62 @@ std::vector<Menu::Button>Menu::GetMenuButtons(const MenuType type){
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,64.f},"Quit","button.png","highlight_button.png",Pixel{165,208,96},Pixel{37,134,139},[this](Button&self){Transition(SHIFT_DOWN,QUIT,0.5f);}); buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,64.f},"Quit","button.png","highlight_button.png",Pixel{165,208,96},Pixel{37,134,139},[this](Button&self){Transition(SHIFT_DOWN,QUIT,0.5f);});
}break; }break;
case GRAND_PRIX:{ case GRAND_PRIX:{
//Add more buttons up here! buttons.emplace_back(HamsterGame::SCREEN_FRAME.pos+vf2d{60.f,HamsterGame::SCREEN_FRAME.size.y/2-36.f},"Grand Prix I - ","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageI.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(vf2d{54.f,HamsterGame::SCREEN_FRAME.size.y-24.f},"< Back","button3.png","highlight_button3.png",Pixel{145,199,255},Pixel{145,199,255},[this](Button&self){Transition(SHIFT_RIGHT,MAIN_MENU,0.5f);}); buttons.emplace_back(vf2d{54.f,HamsterGame::SCREEN_FRAME.size.y-24.f},"< Back","button3.png","highlight_button3.png",Pixel{145,199,255},Pixel{145,199,255},[this](Button&self){Transition(SHIFT_RIGHT,MAIN_MENU,0.5f);});
}break; }break;
case SINGLE_RACE:{ case SINGLE_RACE:{
//Add more buttons up here! buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f},"I - Welcome to Hamster Planet!","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
buttons.emplace_back(vf2d{54.f,HamsterGame::SCREEN_FRAME.size.y-24.f},"< Back","button4.png","highlight_button4.png",Pixel{220,185,155},Pixel{180,140,152},[this](Button&self){Transition(SHIFT_DOWN,MAIN_MENU,0.5f);}); selectedMap="StageI.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f+22.f*1},"II - Splitting Hairs","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageII.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f+22.f*2},"III - The Stranger Lands","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageIII.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f+22.f*3},"IV - Jet Jet Go!","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageIV.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f+22.f*4},"V - Run Run Run!","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageV.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f+22.f*5},"VI - A Twisty Maze","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageVI.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f+22.f*6},"VII - Dunescape","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageVII.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f+22.f*7},"VIII - Swamps of Travesty","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageVIII.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f+22.f*8},"IX - Wide Chasm","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageIX.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f+22.f*9},"X - Hamster Island","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageX.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f+22.f*10},"XI - Lava Panic!","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageXI.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-132.f+22.f*11},"XII - The Great Plunge","longbutton2.png","longhighlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
selectedMap="StageXII.tmx";
Transition(FADE_OUT,LOADING,0.5f);
});
buttons.emplace_back(vf2d{54.f,HamsterGame::SCREEN_FRAME.size.y-12.f},"< Back","button4.png","highlight_button4.png",Pixel{220,185,155},Pixel{180,140,152},[this](Button&self){Transition(SHIFT_DOWN,MAIN_MENU,0.5f);});
}break; }break;
case OPTIONS:{ case OPTIONS:{
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-32.f},std::format("BGM: {}",int(round(HamsterGame::Game().bgmVol*100))),"button2.png","highlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){ buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-32.f},std::format("BGM: {}",int(round(HamsterGame::Game().bgmVol*100))),"button2.png","highlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](Button&self){
@ -302,6 +352,41 @@ void Menu::Draw(HamsterGame&game,const MenuType menu,const vi2d pos){
game.DrawPartialDecal(vi2d{pos},game.SCREEN_FRAME.size,game.GetGFX("background4.png").Decal(),vf2d{}+int(game.GetRuntime()*4),game.SCREEN_FRAME.size); game.DrawPartialDecal(vi2d{pos},game.SCREEN_FRAME.size,game.GetGFX("background4.png").Decal(),vf2d{}+int(game.GetRuntime()*4),game.SCREEN_FRAME.size);
DrawButtons(pos); DrawButtons(pos);
game.border.Draw(); game.border.Draw();
if(selectedButton.value()<game.mapNameList.size()){
//Display PB.
std::string mapName{game.mapNameList[selectedButton.value()]};
std::string timerStr{"No Record!"};
game.DrawShadowStringPropDecal({4.f,4.f},"Personal Best",WHITE,BLACK,{1.f,2.f});
if(game.mapPBs[mapName]!=std::numeric_limits<int>::max())timerStr=util::timerStr(game.mapPBs[mapName]);
vf2d timerStrSize{game.GetTextSize(timerStr)*vf2d{1.f,2.f}};
game.DrawShadowRotatedStringDecal({48.f,44.f},timerStr,0.f,timerStrSize/2,WHITE,BLACK,{1.f,2.f});
if(lastHovered!=selectedButton.value()){
loadedLeaderboard.clear();
loadedLeaderboard=game.net.GetLeaderboard(mapName);
lastHovered=selectedButton.value();
}
if(loadedLeaderboard.size()>0){
game.DrawShadowStringPropDecal(vf2d{game.SCREEN_FRAME.pos.x+game.SCREEN_FRAME.size.x,0.f}+vf2d{4.f,4.f},"Leaderboard",YELLOW,BLACK,{1.f,1.f});
for(int i=0;i<std::min(size_t(10),loadedLeaderboard.size());i++){
const LeaderboardEntry&entry{loadedLeaderboard[i]};
std::string placementStr{std::format("{}.",i+1)};
vf2d placementStrSize{game.GetTextSizeProp(placementStr)};
vf2d entryStrSize{game.GetTextSizeProp(entry.name)};
int totalPixelSpaceForName{int(96-16-placementStrSize.x)};
game.DrawShadowStringPropDecal(vf2d{game.SCREEN_FRAME.pos.x+game.SCREEN_FRAME.size.x,0.f}+vf2d{4.f,4.f+(i+1)*20.f},placementStr,WHITE,BLACK,{1.f,1.f});
if(entryStrSize.x>totalPixelSpaceForName){
float nameScaleX{totalPixelSpaceForName/entryStrSize.x};
game.DrawShadowStringPropDecal(vf2d{game.SCREEN_FRAME.pos.x+game.SCREEN_FRAME.size.x,0.f}+vf2d{4.f+placementStrSize.x,4.f+(i+1)*20.f},std::format("{}",entry.name,util::timerStr(entry.time)),WHITE,BLACK,{nameScaleX,1.f});
}else game.DrawShadowStringPropDecal(vf2d{game.SCREEN_FRAME.pos.x+game.SCREEN_FRAME.size.x,0.f}+vf2d{4.f+placementStrSize.x,4.f+(i+1)*20.f},std::format("{}",entry.name,util::timerStr(entry.time)),WHITE,BLACK,{1.f,1.f});
game.DrawShadowStringPropDecal(vf2d{game.SCREEN_FRAME.pos.x+game.SCREEN_FRAME.size.x,0.f}+vf2d{4.f+placementStrSize.x+4.f,4.f+(i+1)*20.f+10.f},std::format("{}",util::timerStr(entry.time)),WHITE,BLACK,{1.f,1.f});
std::string hamsterDisplayImg{game.ColorToHamsterImage(entry.color)};
game.DrawPartialRotatedDecal(vf2d{game.SCREEN_FRAME.pos.x+game.SCREEN_FRAME.size.x,0.f}+vf2d{96.f-6.f,4.f+(i+1)*20.f+2.f},game.GetGFX(hamsterDisplayImg).Decal(),0.f,{8.f,6.f},{64.f,64.f},{16.f,12.f},{-1.f,1.f});
}
}
}
}break; }break;
case OPTIONS:{ case OPTIONS:{
game.DrawPartialDecal(vi2d{pos},game.SCREEN_FRAME.size,game.GetGFX("background2.png").Decal(),vf2d{}+int(game.GetRuntime()*4),game.SCREEN_FRAME.size); game.DrawPartialDecal(vi2d{pos},game.SCREEN_FRAME.size,game.GetGFX("background2.png").Decal(),vf2d{}+int(game.GetRuntime()*4),game.SCREEN_FRAME.size);

@ -39,6 +39,7 @@ All rights reserved.
#include "olcPixelGameEngine.h" #include "olcPixelGameEngine.h"
#include <functional> #include <functional>
#include "HamsterNet.h"
class HamsterGame; class HamsterGame;
class Menu{ class Menu{
@ -98,12 +99,14 @@ class Menu{
std::vector<Button>newMenuButtons; std::vector<Button>newMenuButtons;
std::string selectedMap{"StageI.tmx"}; std::string selectedMap{"StageI.tmx"};
std::optional<int>selectedButton; std::optional<int>selectedButton;
int lastHovered{};
void Transition(const TransitionType type,const MenuType gotoMenu,const float transitionTime); void Transition(const TransitionType type,const MenuType gotoMenu,const float transitionTime);
void Draw(HamsterGame&game,const MenuType menu,const vi2d pos); void Draw(HamsterGame&game,const MenuType menu,const vi2d pos);
void DrawTransition(HamsterGame&game); void DrawTransition(HamsterGame&game);
void OnMenuTransition(); void OnMenuTransition();
std::vector<Button>GetMenuButtons(const MenuType type); std::vector<Button>GetMenuButtons(const MenuType type);
bool ignoreInputs{false}; bool ignoreInputs{false};
std::vector<LeaderboardEntry>loadedLeaderboard;
public: public:
void UpdateAndDraw(HamsterGame&game,const float fElapsedTime); void UpdateAndDraw(HamsterGame&game,const float fElapsedTime);
void OnLevelLoaded(); void OnLevelLoaded();

@ -179,6 +179,8 @@ Menu Select/Back Sound
Loading Screen Loading Screen
Credits goes in Quit Page
========================== ==========================
Stages VI - XII: 7 Stages (1 hour each, 7 hours total) Stages VI - XII: 7 Stages (1 hour each, 7 hours total)
Menu Navigations (3 hours) Menu Navigations (3 hours)

Loading…
Cancel
Save