parent
3cbb0d1e17
commit
03f2738ead
@ -0,0 +1,104 @@ |
||||
#include "Crawler.h" |
||||
#include "Menu.h" |
||||
|
||||
bool Menu::MOUSE_NAVIGATION=true; |
||||
std::vector<Menu*>Menu::stack; |
||||
std::map<MenuType,Menu>Menu::menus; |
||||
|
||||
Menu::Menu(){} |
||||
|
||||
Menu::Menu(vf2d size) |
||||
:size(size){} |
||||
|
||||
void Menu::InitializeMenus(){ |
||||
stack.reserve(32); |
||||
menus[TEST]=InitializeTestMenu(); |
||||
menus[TEST_2]=InitializeTestSubMenu(); |
||||
|
||||
for(MenuType type=TEST;type<MenuType::ENUM_END;type=MenuType(int(type+1))){ |
||||
if(menus.count(type)==0){ |
||||
std::cout<<"WARNING! Menu Type "<<type<<" does not exist!"<<std::endl; |
||||
throw; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void Menu::AddButton(const MenuButton&button){ |
||||
buttons.push_back(button); |
||||
} |
||||
|
||||
void Menu::MenuSelect(Crawler*game){ |
||||
if(selection==-1)return; |
||||
buttons[selection].onClick(*this,game); |
||||
if(buttons[selection].menuDest!=MenuType::ENUM_END){ |
||||
if(stack.size()<32){ |
||||
stack.push_back(&menus[buttons[selection].menuDest]);//Navigate to the next menu.
|
||||
}else{ |
||||
std::cout<<"WARNING! Exceeded menu stack size limit!"<<std::endl; |
||||
throw; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void Menu::Update(Crawler*game){ |
||||
vf2d upperLeftPos=game->GetScreenSize()/2-size/2; |
||||
|
||||
for(MenuButton&button:buttons){ |
||||
button.hovered=false; |
||||
} |
||||
if(!MOUSE_NAVIGATION){ |
||||
if(selection!=-1)buttons[selection].hovered=true; |
||||
}else{ |
||||
for(MenuButton&button:buttons){ |
||||
if(geom2d::overlaps(geom2d::rect<float>{button.rect.pos+upperLeftPos,button.rect.size},game->GetMousePos())){ |
||||
button.hovered=true; |
||||
} |
||||
} |
||||
} |
||||
if(game->GetKey(RIGHT).bPressed||game->GetKey(DOWN).bPressed){ |
||||
MOUSE_NAVIGATION=false; |
||||
selection=(selection+1)%buttons.size(); |
||||
} |
||||
if(game->GetKey(LEFT).bPressed||game->GetKey(UP).bPressed){ |
||||
MOUSE_NAVIGATION=false; |
||||
selection--; |
||||
if(selection<0)selection+=buttons.size(); |
||||
} |
||||
if(game->GetMouse(0).bPressed||game->GetKey(ENTER).bPressed||game->GetKey(SPACE).bPressed){ |
||||
MOUSE_NAVIGATION=game->GetMouse(0).bPressed; //If a click occurs we use mouse controls.
|
||||
if(!MOUSE_NAVIGATION){ |
||||
MenuSelect(game); |
||||
//Key presses automatically highlight the first button if it's not highlighted.
|
||||
if(selection==-1&&buttons.size()>0){ |
||||
selection=0; |
||||
} |
||||
}else{//Mouse click.
|
||||
selection=-1; |
||||
int index=0; |
||||
for(MenuButton&button:buttons){ |
||||
if(geom2d::overlaps(geom2d::rect<float>{button.rect.pos+upperLeftPos,button.rect.size},game->GetMousePos())){ |
||||
selection=index; |
||||
break; |
||||
} |
||||
index++; |
||||
} |
||||
MenuSelect(game); |
||||
} |
||||
} |
||||
for(MenuButton&button:buttons){ |
||||
button.Update(game); |
||||
} |
||||
}; |
||||
|
||||
void Menu::Draw(Crawler*game){ |
||||
vf2d upperLeftPos=game->GetScreenSize()/2-size/2; |
||||
game->FillRectDecal(upperLeftPos,size,VERY_DARK_BLUE); |
||||
for(MenuButton&button:buttons){ |
||||
button.Draw(game,upperLeftPos); |
||||
} |
||||
}; |
||||
|
||||
void Menu::OpenMenu(MenuType menu){ |
||||
stack.clear(); |
||||
stack.push_back(&(menus[menu])); |
||||
} |
@ -0,0 +1,22 @@ |
||||
#include "Crawler.h" |
||||
#include "Menu.h" |
||||
|
||||
MenuButton::MenuButton(geom2d::rect<float>rect,std::string label,Decal*icon,MenuFunc onClick) |
||||
:rect(rect),label(label),menuDest(MenuType::ENUM_END),icon(icon),onClick(onClick),hoverEffect(0){} |
||||
|
||||
MenuButton::MenuButton(geom2d::rect<float>rect,std::string label,MenuType menuDest,Decal*icon,MenuFunc onClick) |
||||
:rect(rect),label(label),menuDest(menuDest),icon(icon),onClick(onClick),hoverEffect(0){} |
||||
|
||||
void MenuButton::Update(Crawler*game){ |
||||
if(hovered){ |
||||
hoverEffect=std::min(1.f,hoverEffect+game->GetElapsedTime()); |
||||
}else{ |
||||
hoverEffect=std::max(0.f,hoverEffect-game->GetElapsedTime()); |
||||
} |
||||
} |
||||
|
||||
void MenuButton::Draw(Crawler*game,vf2d parentPos){ |
||||
game->FillRectDecal(rect.pos+parentPos,rect.size,PixelLerp(VERY_DARK_BLUE,CYAN,hoverEffect)); |
||||
game->DrawRectDecal(rect.pos+parentPos,rect.size,GREY); |
||||
game->DrawStringPropDecal(rect.pos+parentPos+rect.size/2-game->GetTextSizeProp(label)/2,label); |
||||
} |
@ -1,17 +1,24 @@ |
||||
#pragma once |
||||
#include "olcPixelGameEngine.h" |
||||
#include "olcUTIL_Geometry2D.h" |
||||
#include "MenuType.h" |
||||
#include <functional> |
||||
|
||||
class Menu; |
||||
class Crawler; |
||||
|
||||
class MenuButton{ |
||||
Menu*menuDest; |
||||
vf2d size; |
||||
friend class Menu; |
||||
MenuType menuDest; |
||||
geom2d::rect<float>rect; |
||||
std::string label; |
||||
Decal*icon; |
||||
std::function<void()>onClick; |
||||
|
||||
void Update(float fElapsedTime); |
||||
void Draw(Crawler*game); |
||||
MenuFunc onClick; |
||||
bool hovered=false; |
||||
private: |
||||
float hoverEffect=0; |
||||
public: |
||||
MenuButton(geom2d::rect<float>rect,std::string label,Decal*icon,MenuFunc onClick); |
||||
MenuButton(geom2d::rect<float>rect,std::string label,MenuType menuDest,Decal* icon,MenuFunc onClick); |
||||
void Update(Crawler*game); |
||||
void Draw(Crawler*game,vf2d parentPos); |
||||
}; |
@ -0,0 +1,14 @@ |
||||
#pragma once |
||||
|
||||
class Menu; |
||||
class Crawler; |
||||
|
||||
typedef std::function<void(Menu&,Crawler*)> MenuFunc; |
||||
|
||||
enum MenuType{ |
||||
TEST, |
||||
TEST_2, |
||||
///////////////////////////////////////////////////////////
|
||||
/*DO NOT REMOVE!!*/ENUM_END////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
}; |
@ -0,0 +1,26 @@ |
||||
#include "Crawler.h" |
||||
#include "Menu.h" |
||||
|
||||
const Menu Menu::InitializeTestMenu(){ |
||||
Menu testMenu({24*8,24*6}); |
||||
|
||||
MenuFunc quitWindow=[](Menu&menu,Crawler*game){ |
||||
menu.stack.clear(); |
||||
}; |
||||
|
||||
testMenu.AddButton(MenuButton({{24*1,24*1},{24*2,24*1}},"Close",nullptr,quitWindow)); |
||||
|
||||
MenuFunc doNothing=[](Menu&menu,Crawler*game){}; |
||||
|
||||
testMenu.AddButton(MenuButton({{24*4,24*1},{24*3,24*1}},"Test",nullptr,doNothing)); |
||||
|
||||
MenuFunc HurtPlayer=[](Menu&menu,Crawler*game){ |
||||
game->GetPlayer()->Hurt(20,game->GetPlayer()->OnUpperLevel(),game->GetPlayer()->GetZ()); |
||||
}; |
||||
|
||||
testMenu.AddButton(MenuButton({{24*4,24*3},{24*3,24*1}},"Hurt Player",nullptr,HurtPlayer)); |
||||
|
||||
testMenu.AddButton(MenuButton({{24*2,24*4.5},{24*4,24*1}},"Open Another\n Menu",TEST_2,nullptr,doNothing)); |
||||
|
||||
return testMenu; |
||||
} |
@ -0,0 +1,20 @@ |
||||
#include "Crawler.h" |
||||
#include "Menu.h" |
||||
|
||||
const Menu Menu::InitializeTestSubMenu(){ |
||||
Menu testSubMenu({24*4,24*5}); |
||||
|
||||
MenuFunc goBack=[](Menu&menu,Crawler*game){ |
||||
menu.stack.pop_back(); |
||||
}; |
||||
|
||||
testSubMenu.AddButton(MenuButton({{24*1,24*1},{24*2,24*1}},"Go Back",nullptr,goBack)); |
||||
|
||||
MenuFunc quitWindow=[](Menu&menu,Crawler*game){ |
||||
menu.stack.clear(); |
||||
}; |
||||
|
||||
testSubMenu.AddButton(MenuButton({{24*1,24*3},{24*3,24*1}},"Close Window",nullptr,quitWindow)); |
||||
|
||||
return testSubMenu; |
||||
} |
Loading…
Reference in new issue