1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-03 09:09:47 +02:00

Improve Menu system implementation

This commit is contained in:
Daniel Evans 2016-10-18 22:00:53 +01:00
parent 6a7802de87
commit 613d386488
9 changed files with 225 additions and 307 deletions

View File

@ -19,6 +19,9 @@ set(RWGAME_SOURCES
StateManager.cpp
State.cpp
MenuSystem.hpp
MenuSystem.cpp
states/LoadingState.hpp
states/LoadingState.cpp
states/IngameState.hpp

0
rwgame/MenuSystem.cpp Normal file
View File

View File

@ -21,27 +21,35 @@ constexpr const char* kOptionsId = "FET_OPT";
constexpr const char* kQuitGameId = "FET_QG";
}
/**
* @brief Implements user navigable menus
*
* This is a temporary implementation
*/
class Menu {
int font;
public:
Menu(int font = MenuDefaults::kFont) : font(font), activeEntry(-1) {
}
struct MenuEntry {
/**
* @brief Handles rendering and dispatch of menu items
*/
class MenuEntry {
GameString text;
float _size;
float size;
std::function<void(void)> callback;
MenuEntry(const GameString& n, float size = 30.f)
: text(n), _size(size) {
public:
MenuEntry(const std::string& n, std::function<void(void)> cb)
: text(GameStringUtil::fromString(n)), size(30.f), callback(cb) {
}
MenuEntry(const GameString& n, std::function<void(void)> cb,
float size = 30.f)
: text(n), size(size), callback(cb) {
}
float getHeight() {
return _size;
float getHeight() const {
return size;
}
virtual void draw(int font, bool active, GameRenderer* r,
glm::vec2& basis) {
void draw(int font, bool active, GameRenderer* r, glm::vec2& basis) {
TextRenderer::TextInfo ti;
ti.font = font;
ti.screenPosition = basis;
@ -56,16 +64,6 @@ public:
basis.y += getHeight();
}
virtual void activate(float clickX, float clickY) = 0;
};
struct Entry : public MenuEntry {
std::function<void(void)> callback;
Entry(const GameString& title, std::function<void(void)> cb, float size)
: MenuEntry(title, size), callback(cb) {
}
void activate(float clickX, float clickY) {
RW_UNUSED(clickX);
RW_UNUSED(clickY);
@ -73,19 +71,28 @@ public:
}
};
static std::shared_ptr<MenuEntry> lambda(const GameString& n,
std::function<void(void)> callback,
float size = 30.f) {
return std::shared_ptr<MenuEntry>(new Entry(n, callback, size));
Menu(std::vector<MenuEntry> initial, int font = MenuDefaults::kFont)
: activeEntry(-1), font(font), entries(std::move(initial)) {
}
static std::shared_ptr<MenuEntry> lambda(const std::string& n,
std::function<void(void)> callback,
float size = 30.f) {
return lambda(GameStringUtil::fromString(n), callback, size);
/**
* @brief creates a menu from the given menu items
* @return a shared pointer to the menu with the items
*/
static std::shared_ptr<Menu> create(std::vector<MenuEntry> items,
int font = MenuDefaults::kFont) {
return std::make_shared<Menu>(std::move(items), font);
}
std::vector<std::shared_ptr<MenuEntry>> entries;
Menu& lambda(const GameString& n, std::function<void()> callback) {
entries.emplace_back(n, callback, 30.f);
return *this;
}
Menu& lambda(const std::string& n, std::function<void(void)> callback) {
entries.emplace_back(GameStringUtil::fromString(n), callback, 30.f);
return *this;
}
/**
* Active Entry index
@ -94,10 +101,6 @@ public:
glm::vec2 offset;
void addEntry(std::shared_ptr<MenuEntry> entry) {
entries.push_back(entry);
}
void draw(GameRenderer* r) {
glm::vec2 basis(offset);
for (size_t i = 0; i < entries.size(); ++i) {
@ -105,18 +108,18 @@ public:
if (activeEntry >= 0 && i == (unsigned)activeEntry) {
active = true;
}
entries[i]->draw(font, active, r, basis);
entries[i].draw(font, active, r, basis);
}
}
void hover(const float x, const float y) {
glm::vec2 c(x - offset.x, y - offset.y);
for (size_t i = 0; i < entries.size(); ++i) {
if (c.y > 0.f && c.y < entries[i]->getHeight()) {
if (c.y > 0.f && c.y < entries[i].getHeight()) {
activeEntry = i;
return;
} else {
c.y -= entries[i]->getHeight();
c.y -= entries[i].getHeight();
}
}
}
@ -124,11 +127,11 @@ public:
void click(const float x, const float y) {
glm::vec2 c(x - offset.x, y - offset.y);
for (auto it = entries.begin(); it != entries.end(); ++it) {
if (c.y > 0.f && c.y < (*it)->getHeight()) {
(*it)->activate(c.x, c.y);
if (c.y > 0.f && c.y < (*it).getHeight()) {
(*it).activate(c.x, c.y);
return;
} else {
c.y -= (*it)->getHeight();
c.y -= (*it).getHeight();
}
}
}
@ -136,7 +139,7 @@ public:
// Activates the menu entry at the current active index.
void activate() {
if (activeEntry >= 0 && (unsigned)activeEntry < entries.size()) {
entries[activeEntry]->activate(0.f, 0.f);
entries[activeEntry].activate(0.f, 0.f);
}
}
@ -148,6 +151,14 @@ public:
activeEntry = entries.size() - 1;
}
}
const std::vector<MenuEntry>& getEntries() const {
return entries;
}
private:
int font;
std::vector<MenuEntry> entries;
};
#endif

View File

@ -12,13 +12,12 @@ class StateManager;
class State {
public:
// Helper for global menu behaviour
Menu* currentMenu;
Menu* nextMenu;
std::shared_ptr<Menu> menu;
std::shared_ptr<Menu> nextMenu;
RWGame* game;
State(RWGame* game) : currentMenu(nullptr), nextMenu(nullptr), game(game) {
State(RWGame* game) : game(game) {
}
virtual void enter() = 0;
@ -33,24 +32,18 @@ public:
}
virtual ~State() {
if (getCurrentMenu()) {
delete getCurrentMenu();
}
}
void enterMenu(Menu* menu) {
void enterMenu(const std::shared_ptr<Menu>& menu) {
nextMenu = menu;
}
Menu* getCurrentMenu() {
if (nextMenu) {
if (currentMenu) {
delete currentMenu;
}
currentMenu = nextMenu;
menu = nextMenu;
nextMenu = nullptr;
}
return currentMenu;
return menu.get();
}
virtual void handleEvent(const SDL_Event& e);
@ -72,8 +65,11 @@ public:
private:
bool hasexited_ = false;
protected:
void done() { hasexited_ = true; }
void done() {
hasexited_ = true;
}
};
#endif

View File

@ -11,6 +11,7 @@
#include "RWGame.hpp"
constexpr float kDebugEntryHeight = 14.f;
constexpr int kDebugFont = 2;
const glm::vec2 kDebugMenuOffset = glm::vec2(10.f, 50.f);
static void jumpCharacter(RWGame* game, CharacterObject* player,
@ -29,195 +30,119 @@ static void jumpCharacter(RWGame* game, CharacterObject* player,
}
}
Menu* DebugState::createDebugMenu() {
std::shared_ptr<Menu> DebugState::createDebugMenu() {
CharacterObject* player = nullptr;
if (game->getPlayer()) {
player = game->getPlayer()->getCharacter();
}
Menu* m = new Menu(2);
m->offset = kDebugMenuOffset;
#if 0
m->addEntry(Menu::lambda("Random Vehicle", [this] {
auto it = getWorld()->vehicleTypes.begin();
std::uniform_int_distribution<int> uniform(0, 3);
for(size_t i = 0, n = uniform(getWorld()->randomEngine); i != n; i++) {
it++;
}
spawnVehicle(it->first);
}, entryHeight));
m->addEntry(Menu::lambda("Open All Doors/Flaps", [=] {
auto pc = getWorld()->state->player->getCharacter();
auto pv = pc->getCurrentVehicle();
if( pv ) {
for(auto& it : pv->_hingedObjects) {
pv->setHingeLocked(it.first, false);
}
}
}, entryHeight));
auto menu = Menu::create(
{{"Jump to Debug Camera",
[=] {
jumpCharacter(game, player,
_debugCam.position +
_debugCam.rotation * glm::vec3(3.f, 0.f, 0.f),
false);
}},
{"-Map", [=] { this->enterMenu(createMapMenu()); }},
{"-Vehicles", [=] { this->enterMenu(createVehicleMenu()); }},
{"-AI", [=] { this->enterMenu(createAIMenu()); }},
{"-Weapons", [=] { this->enterMenu(createWeaponMenu()); }},
{"Set Super Jump", [=] { player->setJumpSpeed(20.f); }},
{"Set Normal Jump",
[=] { player->setJumpSpeed(CharacterObject::DefaultJumpSpeed); }},
{"Full Health", [=] { player->getCurrentState().health = 100.f; }},
{"Full Armour", [=] { player->getCurrentState().armour = 100.f; }},
{"Cull Here",
[=] { game->getRenderer().setCullOverride(true, _debugCam); }}},
kDebugFont);
m->addEntry(Menu::lambda("Spawn Pedestrians", [=] {
glm::vec3 hit, normal;
if(game->hitWorldRay(hit, normal)) {
glm::vec3 spawnPos = hit + glm::vec3(-5, 0.f, 0.0) + normal;
size_t k = 1;
// Spawn every pedestrian.
for(auto it = getWorld()->pedestrianTypes.begin();
it != getWorld()->pedestrianTypes.end(); ++it) {
getWorld()->createPedestrian(it->first, spawnPos);
spawnPos += glm::vec3(2.5, 0, 0);
if((k++ % 6) == 0) { spawnPos += glm::vec3(-15, -2.5, 0); }
}
}
}, entryHeight));
int vehiclesMax = 16, i = 0;
for( auto& v : getWorld()->vehicleTypes ) {
if( (i++) > vehiclesMax ) break;
m->addEntry(Menu::lambda(v.second->handlingID, [=] {
spawnVehicle(v.first);
}, entryHeight));
}
#endif
m->addEntry(Menu::lambda("Jump to Debug Camera",
[=] {
jumpCharacter(game, player,
_debugCam.position +
_debugCam.rotation *
glm::vec3(3.f, 0.f, 0.f),
false);
},
kDebugEntryHeight));
m->addEntry(Menu::lambda("-Map", [=] { this->enterMenu(createMapMenu()); },
kDebugEntryHeight));
m->addEntry(Menu::lambda("-Vehicles",
[=] { this->enterMenu(createVehicleMenu()); },
kDebugEntryHeight));
m->addEntry(Menu::lambda("-AI", [=] { this->enterMenu(createAIMenu()); },
kDebugEntryHeight));
m->addEntry(Menu::lambda("-Weapons",
[=] { this->enterMenu(createWeaponMenu()); },
kDebugEntryHeight));
m->addEntry(Menu::lambda("Set Super Jump",
[=] { player->setJumpSpeed(20.f); },
kDebugEntryHeight));
m->addEntry(Menu::lambda(
"Set Normal Jump",
[=] { player->setJumpSpeed(CharacterObject::DefaultJumpSpeed); },
kDebugEntryHeight));
m->addEntry(Menu::lambda("Full Health",
[=] { player->getCurrentState().health = 100.f; },
kDebugEntryHeight));
m->addEntry(Menu::lambda("Full Armour",
[=] { player->getCurrentState().armour = 100.f; },
kDebugEntryHeight));
m->addEntry(Menu::lambda(
"Cull Here",
[=] { game->getRenderer().setCullOverride(true, _debugCam); },
kDebugEntryHeight));
menu->offset = kDebugMenuOffset;
// Optional block if the player is in a vehicle
auto cv = player->getCurrentVehicle();
if (cv) {
m->addEntry(Menu::lambda(
"Flip vehicle",
[=] {
cv->setRotation(
cv->getRotation() *
glm::quat(glm::vec3(0.f, glm::pi<float>(), 0.f)));
},
kDebugEntryHeight));
menu->lambda("Flip vehicle", [=] {
cv->setRotation(cv->getRotation() *
glm::quat(glm::vec3(0.f, glm::pi<float>(), 0.f)));
});
}
return m;
return menu;
}
Menu* DebugState::createMapMenu() {
std::shared_ptr<Menu> DebugState::createMapMenu() {
CharacterObject* player = nullptr;
if (game->getPlayer()) {
player = game->getPlayer()->getCharacter();
}
Menu* m = new Menu(2);
m->offset = kDebugMenuOffset;
auto menu = Menu::create(
{{"Back", [=] { enterMenu(createDebugMenu()); }},
{"Jump to Docks",
[=] {
jumpCharacter(game, player, glm::vec3(1390.f, -837.f, 100.f));
}},
{"Jump to Garage",
[=] { jumpCharacter(game, player, glm::vec3(270.f, -605.f, 40.f)); }},
{"Jump to Airport",
[=] {
jumpCharacter(game, player, glm::vec3(-950.f, -980.f, 12.f));
}},
{"Jump to Hideout",
[=] {
jumpCharacter(game, player, glm::vec3(875.0, -309.0, 100.0));
}},
{"Jump to Luigi's",
[=] {
jumpCharacter(game, player, glm::vec3(902.75, -425.56, 100.0));
}},
{"Jump to Hospital",
[=] {
jumpCharacter(game, player, glm::vec3(1123.77, -569.15, 100.0));
}},
{"Unsolid garage doors",
[=] {
m->addEntry(Menu::lambda("Back",
[=] { this->enterMenu(createDebugMenu()); },
kDebugEntryHeight));
std::vector<std::string> garageDoorModels{
"8ballsuburbandoor", "amcogaragedoor",
"bankjobdoor", "bombdoor",
"crushercrush", "crushertop",
"door2_garage", "door3_garage",
"door4_garage", "door_bombshop",
"door_col_compnd_01", "door_col_compnd_02",
"door_col_compnd_03", "door_col_compnd_04",
"door_col_compnd_05", "door_jmsgrage",
"door_sfehousegrge", "double_garage_dr",
"impex_door", "impexpsubgrgdoor",
"ind_plyrwoor", "ind_slidedoor",
"jamesgrge_kb", "leveldoor2",
"oddjgaragdoor", "plysve_gragedoor",
"SalvGarage", "shedgaragedoor",
"Sub_sprayshopdoor", "towergaragedoor1",
"towergaragedoor2", "towergaragedoor3",
"vheistlocdoor"};
m->addEntry(Menu::lambda(
"Jump to Docks",
[=] { jumpCharacter(game, player, glm::vec3(1390.f, -837.f, 100.f)); },
kDebugEntryHeight));
m->addEntry(Menu::lambda(
"Jump to Garage",
[=] { jumpCharacter(game, player, glm::vec3(270.f, -605.f, 40.f)); },
kDebugEntryHeight));
m->addEntry(Menu::lambda(
"Jump to Airport",
[=] { jumpCharacter(game, player, glm::vec3(-950.f, -980.f, 12.f)); },
kDebugEntryHeight));
m->addEntry(Menu::lambda(
"Jump to Hideout",
[=] { jumpCharacter(game, player, glm::vec3(875.0, -309.0, 100.0)); },
kDebugEntryHeight));
m->addEntry(Menu::lambda(
"Jump to Luigi's",
[=] { jumpCharacter(game, player, glm::vec3(902.75, -425.56, 100.0)); },
kDebugEntryHeight));
m->addEntry(Menu::lambda(
"Jump to Hospital",
[=] {
jumpCharacter(game, player, glm::vec3(1123.77, -569.15, 100.0));
},
kDebugEntryHeight));
m->addEntry(Menu::lambda(
"Unsolid garage doors",
[=] {
auto gw = game->getWorld();
for (auto& i : gw->instancePool.objects) {
auto obj = static_cast<InstanceObject*>(i.second);
if (std::find(garageDoorModels.begin(),
garageDoorModels.end(),
obj->getModelInfo<BaseModelInfo>()->name) !=
garageDoorModels.end()) {
obj->setSolid(false);
}
}
}}},
kDebugFont);
std::vector<std::string> garageDoorModels{
"8ballsuburbandoor", "amcogaragedoor",
"bankjobdoor", "bombdoor",
"crushercrush", "crushertop",
"door2_garage", "door3_garage",
"door4_garage", "door_bombshop",
"door_col_compnd_01", "door_col_compnd_02",
"door_col_compnd_03", "door_col_compnd_04",
"door_col_compnd_05", "door_jmsgrage",
"door_sfehousegrge", "double_garage_dr",
"impex_door", "impexpsubgrgdoor",
"ind_plyrwoor", "ind_slidedoor",
"jamesgrge_kb", "leveldoor2",
"oddjgaragdoor", "plysve_gragedoor",
"SalvGarage", "shedgaragedoor",
"Sub_sprayshopdoor", "towergaragedoor1",
"towergaragedoor2", "towergaragedoor3",
"vheistlocdoor"};
auto gw = game->getWorld();
for (auto& i : gw->instancePool.objects) {
auto obj = static_cast<InstanceObject*>(i.second);
if (std::find(garageDoorModels.begin(), garageDoorModels.end(),
obj->getModelInfo<BaseModelInfo>()->name) !=
garageDoorModels.end()) {
obj->setSolid(false);
}
}
},
kDebugEntryHeight));
return m;
menu->offset = kDebugMenuOffset;
return menu;
}
Menu* DebugState::createVehicleMenu() {
Menu* m = new Menu(2);
m->offset = kDebugMenuOffset;
m->addEntry(Menu::lambda("Back",
[=] { this->enterMenu(createDebugMenu()); },
kDebugEntryHeight));
std::shared_ptr<Menu> DebugState::createVehicleMenu() {
auto menu = Menu::create({{"Back", [=] { enterMenu(createDebugMenu()); }}},
kDebugFont);
const std::map<std::string, int> kVehicleTypes = {
{"Landstalker", 90}, {"Taxi", 110}, {"Firetruck", 97},
@ -228,20 +153,16 @@ Menu* DebugState::createVehicleMenu() {
};
for (auto& e : kVehicleTypes) {
m->addEntry(Menu::lambda(e.first, [=] { spawnVehicle(e.second); },
kDebugEntryHeight));
menu->lambda(e.first, [=] { spawnVehicle(e.second); });
}
return m;
menu->offset = kDebugMenuOffset;
return menu;
}
Menu* DebugState::createAIMenu() {
Menu* m = new Menu(2);
m->offset = kDebugMenuOffset;
m->addEntry(Menu::lambda("Back",
[=] { this->enterMenu(createDebugMenu()); },
kDebugEntryHeight));
std::shared_ptr<Menu> DebugState::createAIMenu() {
auto menu = Menu::create(
{{"Back", [=] { this->enterMenu(createDebugMenu()); }}}, kDebugFont);
const std::map<std::string, int> kPedTypes = {
{"Triad", 12}, {"Cop", 1}, {"SWAT", 2},
@ -249,42 +170,35 @@ Menu* DebugState::createAIMenu() {
};
for (auto& e : kPedTypes) {
m->addEntry(Menu::lambda(e.first + " Follower",
[=] { spawnFollower(e.second); },
kDebugEntryHeight));
menu->lambda(e.first + " Follower", [=] { spawnFollower(e.second); });
}
m->addEntry(Menu::lambda(
"Kill All Peds",
[=] {
for (auto& p : game->getWorld()->pedestrianPool.objects) {
if (p.second->getLifetime() == GameObject::PlayerLifetime) {
continue;
}
p.second->takeDamage({p.second->getPosition(),
p.second->getPosition(), 100.f,
GameObject::DamageInfo::Explosion, 0.f});
menu->lambda("Kill All Peds", [=] {
for (auto& p : game->getWorld()->pedestrianPool.objects) {
if (p.second->getLifetime() == GameObject::PlayerLifetime) {
continue;
}
},
kDebugEntryHeight));
return m;
p.second->takeDamage({p.second->getPosition(),
p.second->getPosition(), 100.f,
GameObject::DamageInfo::Explosion, 0.f});
}
});
menu->offset = kDebugMenuOffset;
return menu;
}
Menu* DebugState::createWeaponMenu() {
Menu* m = new Menu(2);
m->offset = kDebugMenuOffset;
m->addEntry(Menu::lambda("Back",
[=] { this->enterMenu(createDebugMenu()); },
kDebugEntryHeight));
std::shared_ptr<Menu> DebugState::createWeaponMenu() {
auto menu = Menu::create(
{{"Back", [=] { this->enterMenu(createDebugMenu()); }}}, kDebugFont);
for (int i = 1; i < kMaxInventorySlots; ++i) {
auto& name = getWorld()->data->weaponData[i]->name;
m->addEntry(
Menu::lambda(name, [=] { giveItem(i); }, kDebugEntryHeight));
menu->lambda(name, [=] { giveItem(i); });
}
return m;
menu->offset = kDebugMenuOffset;
return menu;
}
DebugState::DebugState(RWGame* game, const glm::vec3& vp, const glm::quat& vd)

View File

@ -11,11 +11,11 @@ class DebugState : public State {
bool _sonicMode = false;
bool _invertedY;
Menu* createDebugMenu();
Menu* createMapMenu();
Menu* createVehicleMenu();
Menu* createAIMenu();
Menu* createWeaponMenu();
std::shared_ptr<Menu> createDebugMenu();
std::shared_ptr<Menu> createMapMenu();
std::shared_ptr<Menu> createVehicleMenu();
std::shared_ptr<Menu> createAIMenu();
std::shared_ptr<Menu> createWeaponMenu();
public:
DebugState(RWGame* game, const glm::vec3& vp = {},

View File

@ -13,27 +13,24 @@ MenuState::MenuState(RWGame* game) : State(game) {
void MenuState::enterMainMenu() {
auto& t = game->getGameData().texts;
Menu* m = new Menu;
m->offset = glm::vec2(200.f, 200.f);
m->addEntry(Menu::lambda(t.text(MenuDefaults::kStartGameId), [=] {
StateManager::get().enter<IngameState>(game);
}));
m->addEntry(Menu::lambda(t.text(MenuDefaults::kLoadGameId),
[=] { enterLoadMenu(); }));
m->addEntry(Menu::lambda(t.text(MenuDefaults::kDebugId), [=] {
StateManager::get().enter<IngameState>(game, true, "test");
}));
m->addEntry(Menu::lambda(t.text(MenuDefaults::kOptionsId),
[] { RW_UNIMPLEMENTED("Options Menu"); }));
m->addEntry(Menu::lambda(t.text(MenuDefaults::kQuitGameId),
[] { StateManager::get().clear(); }));
this->enterMenu(m);
auto menu = Menu::create(
{{t.text(MenuDefaults::kStartGameId),
[=] { StateManager::get().enter<IngameState>(game); }},
{t.text(MenuDefaults::kLoadGameId), [=] { enterLoadMenu(); }},
{t.text(MenuDefaults::kDebugId),
[=] { StateManager::get().enter<IngameState>(game, true, "test"); }},
{t.text(MenuDefaults::kOptionsId),
[] { RW_UNIMPLEMENTED("Options Menu"); }},
{t.text(MenuDefaults::kQuitGameId),
[] { StateManager::get().clear(); }}});
menu->offset = glm::vec2(200.f, 200.f);
enterMenu(menu);
}
void MenuState::enterLoadMenu() {
Menu* m = new Menu;
m->offset = glm::vec2(20.f, 30.f);
m->addEntry(Menu::lambda("BACK", [=] { enterMainMenu(); }));
auto menu = Menu::create({{"BACK", [=] { enterMainMenu(); }}});
auto saves = SaveGame::getAllSaveGameInfo();
for (SaveGameInfo& save : saves) {
if (save.valid) {
@ -49,12 +46,14 @@ void MenuState::enterLoadMenu() {
StateManager::get().enter<IngameState>(game, false);
game->loadGame(save.savePath);
};
m->addEntry(Menu::lambda(name, loadsave, 20.f));
menu->lambda(name, loadsave);
} else {
m->addEntry(Menu::lambda("CORRUPT", [=] {}));
menu->lambda("CORRUPT", [=] {});
}
}
this->enterMenu(m);
menu->offset = glm::vec2(20.f, 30.f);
enterMenu(menu);
}
void MenuState::enter() {

View File

@ -4,15 +4,14 @@
PauseState::PauseState(RWGame* game) : State(game) {
auto& t = game->getGameData().texts;
Menu* m = new Menu;
m->offset = glm::vec2(200.f, 200.f);
m->addEntry(Menu::lambda(t.text(MenuDefaults::kResumeGameId),
[&] { done(); }));
m->addEntry(Menu::lambda(t.text(MenuDefaults::kOptionsId),
[] { std::cout << "Options" << std::endl; }));
m->addEntry(Menu::lambda(t.text(MenuDefaults::kQuitGameId),
[] { StateManager::get().clear(); }));
this->enterMenu(m);
auto menu = Menu::create(
{{t.text(MenuDefaults::kResumeGameId), [&] { done(); }},
{t.text(MenuDefaults::kOptionsId),
[] { std::cout << "Options" << std::endl; }},
{t.text(MenuDefaults::kQuitGameId),
[] { StateManager::get().clear(); }}});
menu->offset = glm::vec2(200.f, 200.f);
enterMenu(menu);
}
void PauseState::enter() {

View File

@ -6,8 +6,7 @@ BOOST_AUTO_TEST_SUITE(MenuUnitTests)
BOOST_AUTO_TEST_CASE(menu_test_click) {
bool clickered = false;
Menu test(0);
test.addEntry(Menu::lambda("Test", [&] { clickered = true; }));
Menu test({{"Test", [&] { clickered = true; }}});
BOOST_CHECK(!clickered);
@ -16,7 +15,7 @@ BOOST_AUTO_TEST_CASE(menu_test_click) {
BOOST_CHECK(!clickered);
float h = test.entries.at(0)->getHeight();
float h = test.getEntries().at(0).getHeight();
test.click(0.f, h + 1.f);
@ -29,9 +28,8 @@ BOOST_AUTO_TEST_CASE(menu_test_click) {
BOOST_AUTO_TEST_CASE(menu_test_click_offset) {
bool clickered = false;
Menu test(0);
Menu test({{"Test", [&] { clickered = true; }}});
test.offset = glm::vec2(200.f, 200.f);
test.addEntry(Menu::lambda("Test", [&] { clickered = true; }));
BOOST_CHECK(!clickered);
@ -40,7 +38,7 @@ BOOST_AUTO_TEST_CASE(menu_test_click_offset) {
BOOST_CHECK(!clickered);
float h = test.entries.at(0)->getHeight();
float h = test.getEntries().at(0).getHeight();
test.click(201.f, 200.f + h + 1.f);
@ -53,9 +51,8 @@ BOOST_AUTO_TEST_CASE(menu_test_click_offset) {
BOOST_AUTO_TEST_CASE(menu_test_active_index) {
int clickindex = -1;
Menu test(0);
test.addEntry(Menu::lambda("Test1", [&] { clickindex = 0; }));
test.addEntry(Menu::lambda("Test2", [&] { clickindex = 1; }));
Menu test({{"Test1", [&] { clickindex = 0; }},
{"Test2", [&] { clickindex = 1; }}});
test.activate();
@ -79,14 +76,13 @@ BOOST_AUTO_TEST_CASE(menu_test_active_index) {
BOOST_AUTO_TEST_CASE(menu_test_hover_index) {
int clickindex = -1;
Menu test(0);
test.addEntry(Menu::lambda("Test1", [&] { clickindex = 0; }));
test.addEntry(Menu::lambda("Test2", [&] { clickindex = 1; }));
Menu test({{"Test1", [&] { clickindex = 0; }},
{"Test2", [&] { clickindex = 1; }}});
test.hover(0.f, test.entries[0]->getHeight() - 0.1f);
test.hover(0.f, test.getEntries()[0].getHeight() - 0.1f);
BOOST_CHECK(test.activeEntry == 0);
test.hover(0.f, test.entries[0]->getHeight() + 0.1f);
test.hover(0.f, test.getEntries()[0].getHeight() + 0.1f);
BOOST_CHECK(test.activeEntry == 1);
}