Switched menu button system to component inheritance system.

pull/28/head
sigonasr2 1 year ago
parent 2914aa1972
commit 3723835cc7
  1. 3
      Crawler/Crawler.cpp
  2. 5
      Crawler/Crawler.vcxproj
  3. 7
      Crawler/Crawler.vcxproj.filters
  4. 32
      Crawler/Menu.cpp
  5. 8
      Crawler/Menu.h
  6. 22
      Crawler/MenuButton.cpp
  7. 24
      Crawler/MenuButton.h
  8. 22
      Crawler/MenuComponent.cpp
  9. 34
      Crawler/MenuComponent.h
  10. 15
      Crawler/MenuIconButton.cpp
  11. 4
      Crawler/Player.cpp
  12. 1
      Crawler/Player.h
  13. 8
      Crawler/TestMenu.cpp
  14. 19
      Crawler/TestSubMenu.cpp
  15. 2
      Crawler/Version.h

@ -77,7 +77,6 @@ Crawler::Crawler()
bool Crawler::OnUserCreate(){ bool Crawler::OnUserCreate(){
InitializeDefaultKeybinds(); InitializeDefaultKeybinds();
InitializeLevels(); InitializeLevels();
Menu::InitializeMenus();
circleCooldownPoints.push_back({0,0}); circleCooldownPoints.push_back({0,0});
for(int i=0;i<=360;i+=4){ for(int i=0;i<=360;i+=4){
@ -107,6 +106,8 @@ bool Crawler::OnUserCreate(){
GFX.SetInitialized(); GFX.SetInitialized();
std::cout<<GFX.size()<<" images have been loaded."<<std::endl; std::cout<<GFX.size()<<" images have been loaded."<<std::endl;
Menu::InitializeMenus();
Monster::InitializeStrategies(); Monster::InitializeStrategies();
//Animations //Animations
sig::Animation::InitializeAnimations(); sig::Animation::InitializeAnimations();

@ -274,7 +274,7 @@
<ClInclude Include="Key.h" /> <ClInclude Include="Key.h" />
<ClInclude Include="Map.h" /> <ClInclude Include="Map.h" />
<ClInclude Include="Menu.h" /> <ClInclude Include="Menu.h" />
<ClInclude Include="MenuButton.h" /> <ClInclude Include="MenuComponent.h" />
<ClInclude Include="Monster.h" /> <ClInclude Include="Monster.h" />
<ClInclude Include="MonsterAttribute.h" /> <ClInclude Include="MonsterAttribute.h" />
<ClInclude Include="MonsterStrategyHelpers.h" /> <ClInclude Include="MonsterStrategyHelpers.h" />
@ -313,7 +313,8 @@
<ClCompile Include="LightningBoltEmitter.cpp" /> <ClCompile Include="LightningBoltEmitter.cpp" />
<ClCompile Include="Map.cpp" /> <ClCompile Include="Map.cpp" />
<ClCompile Include="Menu.cpp" /> <ClCompile Include="Menu.cpp" />
<ClCompile Include="MenuButton.cpp" /> <ClCompile Include="MenuComponent.cpp" />
<ClCompile Include="MenuIconButton.cpp" />
<ClCompile Include="Meteor.cpp" /> <ClCompile Include="Meteor.cpp" />
<ClCompile Include="RunAway.cpp" /> <ClCompile Include="RunAway.cpp" />
<ClCompile Include="RunTowards.cpp" /> <ClCompile Include="RunTowards.cpp" />

@ -147,7 +147,7 @@
<ClInclude Include="Menu.h"> <ClInclude Include="Menu.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="MenuButton.h"> <ClInclude Include="MenuComponent.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="MenuType.h"> <ClInclude Include="MenuType.h">
@ -266,7 +266,7 @@
<ClCompile Include="Menu.cpp"> <ClCompile Include="Menu.cpp">
<Filter>Source Files\Interface</Filter> <Filter>Source Files\Interface</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="MenuButton.cpp"> <ClCompile Include="MenuComponent.cpp">
<Filter>Source Files\Interface</Filter> <Filter>Source Files\Interface</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="TestMenu.cpp"> <ClCompile Include="TestMenu.cpp">
@ -275,6 +275,9 @@
<ClCompile Include="TestSubMenu.cpp"> <ClCompile Include="TestSubMenu.cpp">
<Filter>Source Files\Interface</Filter> <Filter>Source Files\Interface</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="MenuIconButton.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="cpp.hint" /> <None Include="cpp.hint" />

@ -23,16 +23,16 @@ void Menu::InitializeMenus(){
} }
} }
void Menu::AddButton(const MenuButton&button){ void Menu::AddComponent(MenuComponent*button){
buttons[button.rect.pos.y].push_back(button); buttons[button->rect.pos.y].push_back(button);
} }
void Menu::MenuSelect(Crawler*game){ void Menu::MenuSelect(Crawler*game){
if(selection==vi2d{-1,-1})return; if(selection==vi2d{-1,-1})return;
buttons[selection.y][selection.x].onClick(*this,game); buttons[selection.y][selection.x]->onClick(*this,game);
if(buttons[selection.y][selection.x].menuDest!=MenuType::ENUM_END){ if(buttons[selection.y][selection.x]->menuDest!=MenuType::ENUM_END){
if(stack.size()<32){ if(stack.size()<32){
stack.push_back(&menus[buttons[selection.y][selection.x].menuDest]);//Navigate to the next menu. stack.push_back(&menus[buttons[selection.y][selection.x]->menuDest]);//Navigate to the next menu.
}else{ }else{
std::cout<<"WARNING! Exceeded menu stack size limit!"<<std::endl; std::cout<<"WARNING! Exceeded menu stack size limit!"<<std::endl;
throw; throw;
@ -45,16 +45,16 @@ void Menu::Update(Crawler*game){
for(auto&key:buttons){ for(auto&key:buttons){
for(auto&button:key.second){ for(auto&button:key.second){
button.hovered=false; button->hovered=false;
} }
} }
if(!MOUSE_NAVIGATION){ if(!MOUSE_NAVIGATION){
if(selection!=vi2d{-1,-1})buttons[selection.y][selection.x].hovered=true; if(selection!=vi2d{-1,-1})buttons[selection.y][selection.x]->hovered=true;
}else{ }else{
for(auto&key:buttons){ for(auto&key:buttons){
for(auto&button:key.second){ for(auto&button:key.second){
if(geom2d::overlaps(geom2d::rect<float>{button.rect.pos+upperLeftPos,button.rect.size},game->GetMousePos())){ if(geom2d::overlaps(geom2d::rect<float>{button->rect.pos+upperLeftPos,button->rect.size},game->GetMousePos())){
button.hovered=true; button->hovered=true;
} }
} }
} }
@ -84,7 +84,7 @@ void Menu::Update(Crawler*game){
for(auto&key:buttons){ for(auto&key:buttons){
int index=0; int index=0;
for(auto&button:key.second){ for(auto&button:key.second){
if(geom2d::overlaps(geom2d::rect<float>{button.rect.pos+upperLeftPos,button.rect.size},game->GetMousePos())){ if(geom2d::overlaps(geom2d::rect<float>{button->rect.pos+upperLeftPos,button->rect.size},game->GetMousePos())){
selection={index,key.first}; selection={index,key.first};
break; break;
} }
@ -96,7 +96,7 @@ void Menu::Update(Crawler*game){
} }
for(auto&key:buttons){ for(auto&key:buttons){
for(auto&button:key.second){ for(auto&button:key.second){
button.Update(game); button->Update(game);
} }
} }
}; };
@ -106,7 +106,7 @@ void Menu::Draw(Crawler*game){
game->FillRectDecal(upperLeftPos,size,VERY_DARK_BLUE); game->FillRectDecal(upperLeftPos,size,VERY_DARK_BLUE);
for(auto&key:buttons){ for(auto&key:buttons){
for(auto&button:key.second){ for(auto&button:key.second){
button.Draw(game,upperLeftPos); button->Draw(game,upperLeftPos);
} }
} }
}; };
@ -141,11 +141,11 @@ void Menu::KeyboardButtonNavigation(Crawler*game){
}else{ }else{
for(auto&key:buttons){ for(auto&key:buttons){
if(found){ //Once we discover the previous element, the next element becomes our next selection. if(found){ //Once we discover the previous element, the next element becomes our next selection.
int previousButtonX=buttons[selection.y][selection.x].rect.pos.x; int previousButtonX=buttons[selection.y][selection.x]->rect.pos.x;
selection.y=key.first; selection.y=key.first;
int index=0; int index=0;
for(auto&button:key.second){ //Try to match a button in the same column as this button first. for(auto&button:key.second){ //Try to match a button in the same column as this button first.
if(previousButtonX==button.rect.pos.x){ if(previousButtonX==button->rect.pos.x){
selection.x=index; selection.x=index;
break; break;
} }
@ -183,11 +183,11 @@ void Menu::KeyboardButtonNavigation(Crawler*game){
prevInd=key.first; prevInd=key.first;
} }
if(prevInd!=-1){ if(prevInd!=-1){
int previousButtonX=buttons[selection.y][selection.x].rect.pos.x; int previousButtonX=buttons[selection.y][selection.x]->rect.pos.x;
selection.y=prevInd; selection.y=prevInd;
int index=0; int index=0;
for(auto&button:buttons[prevInd]){ //Try to match a button in the same column as this button first. for(auto&button:buttons[prevInd]){ //Try to match a button in the same column as this button first.
if(previousButtonX==button.rect.pos.x){ if(previousButtonX==button->rect.pos.x){
selection.x=index; selection.x=index;
break; break;
} }

@ -1,8 +1,10 @@
#pragma once #pragma once
#include "MenuButton.h" #include "MenuComponent.h"
#include "olcPixelGameEngine.h" #include "olcPixelGameEngine.h"
#include <stack> #include <stack>
#define MENUFUNC [](Menu&menu,Crawler*game)
class Crawler; class Crawler;
class Menu{ class Menu{
@ -11,13 +13,13 @@ class Menu{
static bool MOUSE_NAVIGATION; static bool MOUSE_NAVIGATION;
static std::map<MenuType,Menu>menus; static std::map<MenuType,Menu>menus;
std::map<int/*Y*/,std::vector<MenuButton>>buttons; //Buttons are stored in rows followed by their column order. std::map<int/*Y*/,std::vector<MenuComponent*>>buttons; //Buttons are stored in rows followed by their column order.
vi2d selection={-1,-1}; vi2d selection={-1,-1};
vf2d size; //Size in tiles (24x24), every menu will be tile-based vf2d size; //Size in tiles (24x24), every menu will be tile-based
public: public:
Menu(); Menu();
Menu(vf2d size); Menu(vf2d size);
void AddButton(const MenuButton&button); void AddComponent(MenuComponent*button);
void Update(Crawler*game); void Update(Crawler*game);
void Draw(Crawler*game); void Draw(Crawler*game);
static void InitializeMenus(); static void InitializeMenus();

@ -1,22 +0,0 @@
#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,24 +0,0 @@
#pragma once
#include "olcUTIL_Geometry2D.h"
#include "MenuType.h"
#include <functional>
class Menu;
class Crawler;
class MenuButton{
friend class Menu;
MenuType menuDest;
geom2d::rect<float>rect;
std::string label;
Decal*icon;
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,22 @@
#include "Crawler.h"
#include "Menu.h"
MenuComponent::MenuComponent(geom2d::rect<float>rect,std::string label,MenuFunc onClick)
:rect(rect),label(label),menuDest(MenuType::ENUM_END),onClick(onClick),hoverEffect(0){}
MenuComponent::MenuComponent(geom2d::rect<float>rect,std::string label,MenuType menuDest,MenuFunc onClick)
:rect(rect),label(label),menuDest(menuDest),onClick(onClick),hoverEffect(0){}
void MenuComponent::Update(Crawler*game){
if(hovered){
hoverEffect=std::min(1.f,hoverEffect+game->GetElapsedTime());
}else{
hoverEffect=std::max(0.f,hoverEffect-game->GetElapsedTime());
}
}
void MenuComponent::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);
}

@ -0,0 +1,34 @@
#pragma once
#include "olcUTIL_Geometry2D.h"
#include "MenuType.h"
#include <functional>
class Menu;
class Crawler;
class MenuComponent{
friend class Menu;
MenuType menuDest;
std::string label;
MenuFunc onClick;
bool hovered=false;
private:
float hoverEffect=0;
protected:
geom2d::rect<float>rect;
public:
MenuComponent(geom2d::rect<float>rect,std::string label,MenuFunc onClick);
MenuComponent(geom2d::rect<float>rect,std::string label,MenuType menuDest,MenuFunc onClick);
virtual void Update(Crawler*game);
virtual void Draw(Crawler*game,vf2d parentPos);
};
class MenuIconButton:public MenuComponent{
private:
Decal*icon;
public:
MenuIconButton(geom2d::rect<float>rect,Decal*icon,MenuFunc onClick);
protected:
virtual void Update(Crawler*game)override;
virtual void Draw(Crawler*game,vf2d parentPos)override;
};

@ -0,0 +1,15 @@
#include "MenuComponent.h"
#include "Crawler.h"
MenuIconButton::MenuIconButton(geom2d::rect<float>rect,Decal*icon,MenuFunc onClick)
:MenuComponent(rect,"",onClick),icon(icon)
{}
void MenuIconButton::Update(Crawler*game){
MenuComponent::Update(game);
}
void MenuIconButton::Draw(Crawler*game,vf2d parentPos){
MenuComponent::Draw(game,parentPos);
game->DrawRotatedDecal(parentPos+rect.middle(),icon,0,icon->sprite->Size()/2);
}

@ -699,3 +699,7 @@ void Player::SetAnimationBasedOnTargetingDirection(float targetDirection){
void Player::SetIframes(float duration){ void Player::SetIframes(float duration){
iframe_time=duration; iframe_time=duration;
} }
void Player::SetMana(int mana){
this->mana=std::clamp(mana,0,maxmana);
}

@ -133,6 +133,7 @@ public:
bool CanAct(Ability&ability); bool CanAct(Ability&ability);
void Knockback(vf2d vel); void Knockback(vf2d vel);
void SetIframes(float duration); void SetIframes(float duration);
void SetMana(int mana);
void AddBuff(BuffType type,float duration,float intensity); void AddBuff(BuffType type,float duration,float intensity);
std::vector<Buff>GetBuffs(BuffType buff); std::vector<Buff>GetBuffs(BuffType buff);

@ -8,19 +8,19 @@ const Menu Menu::InitializeTestMenu(){
menu.stack.clear(); menu.stack.clear();
}; };
testMenu.AddButton(MenuButton({{24*1,24*1},{24*2,24*1}},"Close",nullptr,quitWindow)); testMenu.AddComponent(new MenuComponent({{24*1,24*1},{24*2,24*1}},"Close",quitWindow));
MenuFunc doNothing=[](Menu&menu,Crawler*game){}; MenuFunc doNothing=[](Menu&menu,Crawler*game){};
testMenu.AddButton(MenuButton({{24*4,24*1},{24*3,24*1}},"Test",nullptr,doNothing)); testMenu.AddComponent(new MenuComponent({{24*4,24*1},{24*3,24*1}},"Test",doNothing));
MenuFunc HurtPlayer=[](Menu&menu,Crawler*game){ MenuFunc HurtPlayer=[](Menu&menu,Crawler*game){
game->GetPlayer()->Hurt(20,game->GetPlayer()->OnUpperLevel(),game->GetPlayer()->GetZ()); 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.AddComponent(new MenuComponent({{24*4,24*3},{24*3,24*1}},"Hurt Player",HurtPlayer));
testMenu.AddButton(MenuButton({{24*2,24*4.5},{24*4,24*1}},"Open Another\n Menu",TEST_2,nullptr,doNothing)); testMenu.AddComponent(new MenuComponent({{24*2,24*4.5},{24*4,24*1}},"Open Another\n Menu",TEST_2,doNothing));
return testMenu; return testMenu;
} }

@ -1,20 +1,31 @@
#include "Crawler.h" #include "Crawler.h"
#include "Menu.h" #include "Menu.h"
#include "DEFINES.h"
#include "olcPixelGameEngine.h"
#include "safemap.h"
INCLUDE_GFX
const Menu Menu::InitializeTestSubMenu(){ const Menu Menu::InitializeTestSubMenu(){
Menu testSubMenu({24*4,24*5}); Menu testSubMenu({24*4,24*5});
MenuFunc goBack=[](Menu&menu,Crawler*game){ MenuFunc goBack=MENUFUNC{
menu.stack.pop_back(); menu.stack.pop_back();
}; };
testSubMenu.AddButton(MenuButton({{24*1,24*1},{24*2,24*1}},"Go Back",nullptr,goBack)); testSubMenu.AddComponent(new MenuComponent({{24*1,24*1},{24*2,24*1}},"Go Back",goBack));
MenuFunc quitWindow=[](Menu&menu,Crawler*game){ MenuFunc quitWindow=MENUFUNC{
menu.stack.clear(); menu.stack.clear();
}; };
testSubMenu.AddButton(MenuButton({{24*1,24*3},{24*3,24*1}},"Close Window",nullptr,quitWindow)); testSubMenu.AddComponent(new MenuComponent({{24*1,24*3},{24*3,24*1}},"Close Window",quitWindow));
MenuFunc restoreMana=MENUFUNC{
game->GetPlayer()->SetMana(game->GetPlayer()->GetMaxMana());
};
testSubMenu.AddComponent(new MenuIconButton({{24*0,24*3},{24*1,24*2}},GFX["mana.png"].Decal(),restoreMana));
return testSubMenu; return testSubMenu;
} }

@ -2,7 +2,7 @@
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 0 #define VERSION_PATCH 0
#define VERSION_BUILD 1644 #define VERSION_BUILD 1651
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

Loading…
Cancel
Save