mirror of
https://github.com/sigonasr2/hamster.git
synced 2025-04-18 22:49:41 -05:00
Add menu button system.
This commit is contained in:
parent
b114907cae
commit
c358f7e3c8
BIN
assets/button2.png
Normal file
BIN
assets/button2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 805 B |
BIN
assets/button3.png
Normal file
BIN
assets/button3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 796 B |
BIN
assets/button4.png
Normal file
BIN
assets/button4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 792 B |
BIN
assets/highlight_button2.png
Normal file
BIN
assets/highlight_button2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 807 B |
BIN
assets/highlight_button3.png
Normal file
BIN
assets/highlight_button3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 787 B |
BIN
assets/highlight_button4.png
Normal file
BIN
assets/highlight_button4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 792 B |
@ -108,6 +108,13 @@ void HamsterGame::LoadGraphics(){
|
|||||||
_LoadImage("hamsterplanet2.png");
|
_LoadImage("hamsterplanet2.png");
|
||||||
_LoadImage("hamsterplanet3.png");
|
_LoadImage("hamsterplanet3.png");
|
||||||
_LoadImage("button.png");
|
_LoadImage("button.png");
|
||||||
|
_LoadImage("highlight_button.png");
|
||||||
|
_LoadImage("button2.png");
|
||||||
|
_LoadImage("highlight_button2.png");
|
||||||
|
_LoadImage("button3.png");
|
||||||
|
_LoadImage("highlight_button3.png");
|
||||||
|
_LoadImage("button4.png");
|
||||||
|
_LoadImage("highlight_button4.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
void HamsterGame::LoadAnimations(){
|
void HamsterGame::LoadAnimations(){
|
||||||
@ -359,7 +366,7 @@ bool HamsterGame::OnUserUpdate(float fElapsedTime){
|
|||||||
|
|
||||||
runTime+=fElapsedTime;
|
runTime+=fElapsedTime;
|
||||||
menu.UpdateAndDraw(*this,fElapsedTime);
|
menu.UpdateAndDraw(*this,fElapsedTime);
|
||||||
return true;
|
return gameIsRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Renderable&HamsterGame::GetGFX(const std::string&img){
|
const Renderable&HamsterGame::GetGFX(const std::string&img){
|
||||||
@ -682,6 +689,10 @@ void HamsterGame::ProcessMap(){
|
|||||||
SetDrawTarget(nullptr);
|
SetDrawTarget(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HamsterGame::QuitGame(){
|
||||||
|
gameIsRunning=false;
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
HamsterGame game("Project Hamster");
|
HamsterGame game("Project Hamster");
|
||||||
|
@ -111,6 +111,7 @@ public:
|
|||||||
const bool HasMoreMapsToPlay()const;
|
const bool HasMoreMapsToPlay()const;
|
||||||
const std::string PopNextMap();
|
const std::string PopNextMap();
|
||||||
void ProcessMap();
|
void ProcessMap();
|
||||||
|
void QuitGame();
|
||||||
private:
|
private:
|
||||||
void UpdateGame(const float fElapsedTime);
|
void UpdateGame(const float fElapsedTime);
|
||||||
void DrawGame();
|
void DrawGame();
|
||||||
@ -193,4 +194,5 @@ private:
|
|||||||
size_t loadingMapLayerTileY;
|
size_t loadingMapLayerTileY;
|
||||||
int totalOperationsCount{};
|
int totalOperationsCount{};
|
||||||
int operationsProgress{};
|
int operationsProgress{};
|
||||||
|
bool gameIsRunning{true};
|
||||||
};
|
};
|
118
src/Menu.cpp
118
src/Menu.cpp
@ -43,10 +43,33 @@ All rights reserved.
|
|||||||
|
|
||||||
void Menu::UpdateAndDraw(HamsterGame&game,const float fElapsedTime){
|
void Menu::UpdateAndDraw(HamsterGame&game,const float fElapsedTime){
|
||||||
menuTransitionRefreshTimer-=fElapsedTime;
|
menuTransitionRefreshTimer-=fElapsedTime;
|
||||||
|
|
||||||
|
for(int i{0};const Button&b:menuButtons){
|
||||||
|
if(b.IsHovered(oldLayerPos+game.SCREEN_FRAME.pos))selectedButton=i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(menuButtons.size()>0&&menuTimer==0.f){
|
||||||
|
if(game.GetKey(W).bPressed||game.GetKey(UP).bPressed||game.GetKey(A).bPressed||game.GetKey(LEFT).bPressed){
|
||||||
|
if(selectedButton.value()-1<0)selectedButton=menuButtons.size()-1;
|
||||||
|
else selectedButton.value()--;
|
||||||
|
}
|
||||||
|
if(game.GetKey(S).bPressed||game.GetKey(DOWN).bPressed||game.GetKey(D).bPressed||game.GetKey(RIGHT).bPressed){
|
||||||
|
if(selectedButton.value()+1>=menuButtons.size())selectedButton=0;
|
||||||
|
else selectedButton.value()++;
|
||||||
|
}
|
||||||
|
if(game.GetKey(ENTER).bPressed||game.GetKey(SPACE).bPressed||menuButtons[selectedButton.value()].IsHovered(oldLayerPos+game.SCREEN_FRAME.pos)&&game.GetMouse(Mouse::LEFT).bPressed){
|
||||||
|
menuButtons[selectedButton.value()].OnClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(menuTimer>0.f){
|
if(menuTimer>0.f){
|
||||||
menuTimer-=fElapsedTime;
|
menuTimer-=fElapsedTime;
|
||||||
if(menuTimer<=0.f){
|
if(menuTimer<=0.f){
|
||||||
|
menuTimer=0.f;
|
||||||
currentMenu=nextMenu;
|
currentMenu=nextMenu;
|
||||||
|
oldLayerPos={};
|
||||||
|
newLayerPos=game.SCREEN_FRAME.pos;
|
||||||
OnMenuTransition();
|
OnMenuTransition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,15 +81,11 @@ void Menu::UpdateAndDraw(HamsterGame&game,const float fElapsedTime){
|
|||||||
Transition(FADE_OUT,TITLE_SCREEN,1.f);
|
Transition(FADE_OUT,TITLE_SCREEN,1.f);
|
||||||
}break;
|
}break;
|
||||||
case TITLE_SCREEN:{
|
case TITLE_SCREEN:{
|
||||||
if(game.GetKey(SPACE).bPressed||game.GetMouse(Mouse::LEFT).bPressed){
|
if(game.GetKey(SPACE).bPressed||game.GetKey(ENTER).bPressed||game.GetMouse(Mouse::LEFT).bPressed){
|
||||||
Transition(SHIFT_LEFT,MAIN_MENU,0.5f);
|
Transition(SHIFT_LEFT,MAIN_MENU,0.5f);
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
case MAIN_MENU:{
|
case MAIN_MENU:{
|
||||||
if(game.GetKey(SPACE).bPressed||game.GetMouse(Mouse::LEFT).bPressed){
|
|
||||||
Transition(FADE_OUT,LOADING,0.5f);
|
|
||||||
selectedMap="StageV.tmx";
|
|
||||||
}
|
|
||||||
}break;
|
}break;
|
||||||
case GAMEPLAY:{
|
case GAMEPLAY:{
|
||||||
game.UpdateGame(fElapsedTime);
|
game.UpdateGame(fElapsedTime);
|
||||||
@ -96,20 +115,49 @@ void Menu::Transition(const TransitionType type,const MenuType gotoMenu,const fl
|
|||||||
menuTimer=originalMenuTimer=transitionTime;
|
menuTimer=originalMenuTimer=transitionTime;
|
||||||
nextMenu=gotoMenu;
|
nextMenu=gotoMenu;
|
||||||
currentTransition=type;
|
currentTransition=type;
|
||||||
|
newMenuButtons=GetMenuButtons(gotoMenu);
|
||||||
|
}
|
||||||
|
std::vector<Menu::Button>Menu::GetMenuButtons(const MenuType type){
|
||||||
|
std::vector<Menu::Button>buttons;
|
||||||
|
switch(type){
|
||||||
|
case MAIN_MENU:{
|
||||||
|
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,-32.f},"Grand Prix","button.png","highlight_button.png",Pixel{165,208,96},Pixel{37,134,139},[this](){Transition(SHIFT_LEFT,GRAND_PRIX,0.5f);});
|
||||||
|
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,0.f},"Single Race","button.png","highlight_button.png",Pixel{165,208,96},Pixel{37,134,139},[this](){Transition(SHIFT_UP,SINGLE_RACE,0.5f);});
|
||||||
|
buttons.emplace_back(HamsterGame::SCREEN_FRAME.size/2+vf2d{0.f,32.f},"Options","button.png","highlight_button.png",Pixel{165,208,96},Pixel{37,134,139},[this](){Transition(SHIFT_RIGHT,OPTIONS,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](){Transition(SHIFT_DOWN,QUIT,0.5f);});
|
||||||
|
}break;
|
||||||
|
case GRAND_PRIX:{
|
||||||
|
//Add more buttons up here!
|
||||||
|
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](){Transition(SHIFT_RIGHT,MAIN_MENU,0.5f);});
|
||||||
|
}break;
|
||||||
|
case SINGLE_RACE:{
|
||||||
|
//Add more buttons up here!
|
||||||
|
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](){Transition(SHIFT_DOWN,MAIN_MENU,0.5f);});
|
||||||
|
}break;
|
||||||
|
case OPTIONS:{
|
||||||
|
//Add more buttons up here!
|
||||||
|
buttons.emplace_back(vf2d{54.f,HamsterGame::SCREEN_FRAME.size.y-24.f},"< Back","button2.png","highlight_button2.png",Pixel{114,109,163},Pixel{79,81,128},[this](){Transition(SHIFT_LEFT,MAIN_MENU,0.5f);});
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
return buttons;
|
||||||
}
|
}
|
||||||
void Menu::OnMenuTransition(){
|
void Menu::OnMenuTransition(){
|
||||||
selectedButton.reset();
|
selectedButton.reset();
|
||||||
|
menuButtons.clear();
|
||||||
|
newMenuButtons.clear();
|
||||||
|
menuButtons=GetMenuButtons(currentMenu);
|
||||||
switch(currentMenu){
|
switch(currentMenu){
|
||||||
case MAIN_MENU:{
|
|
||||||
//selectedButton
|
|
||||||
}break;
|
|
||||||
case LOADING:{
|
case LOADING:{
|
||||||
colorNumb=util::random()%8+1;
|
colorNumb=util::random()%8+1;
|
||||||
loading=true;
|
loading=true;
|
||||||
loadingPct=0.f;
|
loadingPct=0.f;
|
||||||
HamsterGame::Game().LoadRace(selectedMap);
|
HamsterGame::Game().LoadRace(selectedMap);
|
||||||
}break;
|
}break;
|
||||||
|
case QUIT:{
|
||||||
|
HamsterGame::Game().QuitGame();
|
||||||
|
}break;
|
||||||
}
|
}
|
||||||
|
if(menuButtons.size()>0)selectedButton=0;
|
||||||
}
|
}
|
||||||
void Menu::DrawTransition(HamsterGame&game){
|
void Menu::DrawTransition(HamsterGame&game){
|
||||||
if(currentTransition==FADE_OUT){
|
if(currentTransition==FADE_OUT){
|
||||||
@ -160,6 +208,19 @@ void Menu::DrawTransition(HamsterGame&game){
|
|||||||
|
|
||||||
void Menu::Draw(HamsterGame&game,const MenuType menu,const vi2d pos){
|
void Menu::Draw(HamsterGame&game,const MenuType menu,const vi2d pos){
|
||||||
game.Clear(BLANK);
|
game.Clear(BLANK);
|
||||||
|
const auto DrawButtons=[this,&game](const vf2d&offset){
|
||||||
|
for(int i{0};const Button&b:menuButtons){
|
||||||
|
if(selectedButton.has_value())b.Draw(game,oldLayerPos+game.SCREEN_FRAME.pos,menuButtons[selectedButton.value()]);
|
||||||
|
else b.Draw(game,oldLayerPos+game.SCREEN_FRAME.pos);
|
||||||
|
if(selectedButton.has_value())b.Draw(game,oldLayerPos+game.SCREEN_FRAME.pos,menuButtons[selectedButton.value()]);
|
||||||
|
else b.Draw(game,oldLayerPos+game.SCREEN_FRAME.pos);
|
||||||
|
}
|
||||||
|
for(int i{0};const Button&b:newMenuButtons){
|
||||||
|
if(selectedButton.has_value())b.Draw(game,newLayerPos+game.SCREEN_FRAME.pos,menuButtons[selectedButton.value()]);
|
||||||
|
else b.Draw(game,newLayerPos+game.SCREEN_FRAME.pos);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
switch(menu){
|
switch(menu){
|
||||||
case TITLE_SCREEN:{
|
case TITLE_SCREEN:{
|
||||||
game.FillRectDecal(pos,game.SCREEN_FRAME.size,{111,150,255});
|
game.FillRectDecal(pos,game.SCREEN_FRAME.size,{111,150,255});
|
||||||
@ -172,8 +233,27 @@ void Menu::Draw(HamsterGame&game,const MenuType menu,const vi2d pos){
|
|||||||
case MAIN_MENU:{
|
case MAIN_MENU:{
|
||||||
game.DrawPartialDecal(vi2d{pos},game.SCREEN_FRAME.size,game.GetGFX("background1.png").Decal(),vf2d{}+int(game.GetRuntime()*4),game.SCREEN_FRAME.size);
|
game.DrawPartialDecal(vi2d{pos},game.SCREEN_FRAME.size,game.GetGFX("background1.png").Decal(),vf2d{}+int(game.GetRuntime()*4),game.SCREEN_FRAME.size);
|
||||||
game.DrawRotatedDecal(pos,game.GetGFX("button.png").Decal(),0.f,game.GetGFX("button.png").Sprite()->Size()/2);
|
game.DrawRotatedDecal(pos,game.GetGFX("button.png").Decal(),0.f,game.GetGFX("button.png").Sprite()->Size()/2);
|
||||||
|
DrawButtons(pos);
|
||||||
game.border.Draw();
|
game.border.Draw();
|
||||||
}break;
|
}break;
|
||||||
|
case GRAND_PRIX:{
|
||||||
|
game.DrawPartialDecal(vi2d{pos},game.SCREEN_FRAME.size,game.GetGFX("background5.png").Decal(),vf2d{}+int(game.GetRuntime()*4),game.SCREEN_FRAME.size);
|
||||||
|
DrawButtons(pos);
|
||||||
|
game.border.Draw();
|
||||||
|
}break;
|
||||||
|
case SINGLE_RACE:{
|
||||||
|
game.DrawPartialDecal(vi2d{pos},game.SCREEN_FRAME.size,game.GetGFX("background4.png").Decal(),vf2d{}+int(game.GetRuntime()*4),game.SCREEN_FRAME.size);
|
||||||
|
DrawButtons(pos);
|
||||||
|
game.border.Draw();
|
||||||
|
}break;
|
||||||
|
case OPTIONS:{
|
||||||
|
game.DrawPartialDecal(vi2d{pos},game.SCREEN_FRAME.size,game.GetGFX("background2.png").Decal(),vf2d{}+int(game.GetRuntime()*4),game.SCREEN_FRAME.size);
|
||||||
|
DrawButtons(pos);
|
||||||
|
game.border.Draw();
|
||||||
|
}break;
|
||||||
|
case QUIT:{
|
||||||
|
game.DrawPartialDecal(vi2d{pos},game.SCREEN_FRAME.size,game.GetGFX("background3.png").Decal(),vf2d{}+int(game.GetRuntime()*4),game.SCREEN_FRAME.size);
|
||||||
|
}break;
|
||||||
case GAMEPLAY:{
|
case GAMEPLAY:{
|
||||||
game.DrawGame();
|
game.DrawGame();
|
||||||
}break;
|
}break;
|
||||||
@ -214,12 +294,22 @@ void Menu::UpdateLoadingProgress(const float pctLoaded){
|
|||||||
loadingPct=pctLoaded;
|
loadingPct=pctLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu::Button::Button(const vf2d pos,std::string buttonText,Renderable&buttonImg,std::function<void()>onClick)
|
Menu::Button::Button(const vf2d pos,const std::string&buttonText,const std::string&buttonImg,const std::string&highlightButtonImg,const Pixel textCol,const Pixel highlightTextCol,const std::function<void()>onClick)
|
||||||
:pos(pos),buttonText(buttonText),buttonImg(buttonImg),onClick(onClick){}
|
:pos(pos),buttonText(buttonText),buttonImg(buttonImg),highlightButtonImg(highlightButtonImg),onClick(onClick),textCol(textCol),highlightTextCol(highlightTextCol){}
|
||||||
|
|
||||||
void Menu::Button::Update(const float fElapsedTime){
|
|
||||||
|
|
||||||
|
const bool Menu::Button::IsHovered(const vf2d&offset)const{
|
||||||
|
return geom2d::overlaps(HamsterGame::Game().GetMousePos(),geom2d::rect<float>(pos-HamsterGame::GetGFX(buttonImg).Sprite()->Size()/2+offset,HamsterGame::GetGFX(buttonImg).Sprite()->Size()));
|
||||||
}
|
}
|
||||||
void Menu::Button::Draw(HamsterGame&game){
|
void Menu::Button::Draw(HamsterGame&game,const vf2d&offset,std::optional<std::reference_wrapper<Button>>selectedButton)const{
|
||||||
|
if(selectedButton.has_value()&&&selectedButton.value().get()==this){
|
||||||
|
game.DrawRotatedDecal(pos+offset,game.GetGFX(highlightButtonImg).Decal(),0.f,game.GetGFX(highlightButtonImg).Sprite()->Size()/2);
|
||||||
|
game.DrawRotatedStringPropDecal(pos+offset,buttonText,0.f,game.GetTextSizeProp(buttonText)/2,highlightTextCol);
|
||||||
|
}else{
|
||||||
|
game.DrawRotatedDecal(pos+offset,game.GetGFX(buttonImg).Decal(),0.f,game.GetGFX(buttonImg).Sprite()->Size()/2);
|
||||||
|
game.DrawRotatedStringPropDecal(pos+offset,buttonText,0.f,game.GetTextSizeProp(buttonText)/2,textCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Menu::Button::OnClick(){
|
||||||
|
onClick();
|
||||||
}
|
}
|
17
src/Menu.h
17
src/Menu.h
@ -45,12 +45,16 @@ class Menu{
|
|||||||
class Button{
|
class Button{
|
||||||
std::string buttonText;
|
std::string buttonText;
|
||||||
vf2d pos;
|
vf2d pos;
|
||||||
Renderable&buttonImg;
|
std::string buttonImg;
|
||||||
|
std::string highlightButtonImg;
|
||||||
|
Pixel textCol;
|
||||||
|
Pixel highlightTextCol;
|
||||||
std::function<void()>onClick;
|
std::function<void()>onClick;
|
||||||
public:
|
public:
|
||||||
Button(const vf2d pos,std::string buttonText,Renderable&buttonImg,std::function<void()>onClick={});
|
Button(const vf2d pos,const std::string&buttonText,const std::string&buttonImg,const std::string&highlightButtonImg,const Pixel textCol,const Pixel highlightTextCol,const std::function<void()>onClick={});
|
||||||
void Update(const float fElapsedTime);
|
const bool IsHovered(const vf2d&offset)const;
|
||||||
void Draw(HamsterGame&game);
|
void OnClick();
|
||||||
|
void Draw(HamsterGame&game,const vf2d&pos,std::optional<std::reference_wrapper<Button>>selectedButton={})const;
|
||||||
};
|
};
|
||||||
enum MenuType{
|
enum MenuType{
|
||||||
INITIALIZE,
|
INITIALIZE,
|
||||||
@ -64,6 +68,7 @@ class Menu{
|
|||||||
AFTER_RACE_MENU,
|
AFTER_RACE_MENU,
|
||||||
PAUSE,
|
PAUSE,
|
||||||
LOADING,
|
LOADING,
|
||||||
|
QUIT,
|
||||||
};
|
};
|
||||||
enum TransitionType{
|
enum TransitionType{
|
||||||
SHIFT_LEFT,
|
SHIFT_LEFT,
|
||||||
@ -81,7 +86,7 @@ class Menu{
|
|||||||
MenuType currentMenu{INITIALIZE};
|
MenuType currentMenu{INITIALIZE};
|
||||||
MenuType nextMenu{TITLE_SCREEN};
|
MenuType nextMenu{TITLE_SCREEN};
|
||||||
float menuTimer{};
|
float menuTimer{};
|
||||||
const float MENU_TRANSITION_REFRESH_RATE{0.15f};
|
const float MENU_TRANSITION_REFRESH_RATE{0.1f};
|
||||||
float menuTransitionRefreshTimer{MENU_TRANSITION_REFRESH_RATE};
|
float menuTransitionRefreshTimer{MENU_TRANSITION_REFRESH_RATE};
|
||||||
float originalMenuTimer{};
|
float originalMenuTimer{};
|
||||||
vi2d oldLayerPos{};
|
vi2d oldLayerPos{};
|
||||||
@ -90,12 +95,14 @@ class Menu{
|
|||||||
bool loading{false};
|
bool loading{false};
|
||||||
float loadingPct{0.f};
|
float loadingPct{0.f};
|
||||||
std::vector<Button>menuButtons;
|
std::vector<Button>menuButtons;
|
||||||
|
std::vector<Button>newMenuButtons;
|
||||||
std::string selectedMap{"StageI.tmx"};
|
std::string selectedMap{"StageI.tmx"};
|
||||||
std::optional<int>selectedButton;
|
std::optional<int>selectedButton;
|
||||||
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);
|
||||||
public:
|
public:
|
||||||
void UpdateAndDraw(HamsterGame&game,const float fElapsedTime);
|
void UpdateAndDraw(HamsterGame&game,const float fElapsedTime);
|
||||||
void OnLevelLoaded();
|
void OnLevelLoaded();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user