diff --git a/src/frontend/gui/GUI.cpp b/src/frontend/gui/GUI.cpp index 546b47c2..2ccf4895 100644 --- a/src/frontend/gui/GUI.cpp +++ b/src/frontend/gui/GUI.cpp @@ -45,11 +45,11 @@ void GUI::act(float delta) { } this->hover = hover; - if (Events::clicked(0)) { + if (Events::jclicked(0)) { if (pressed == nullptr && this->hover) { pressed = hover; pressed->click(this, mx, my); - if (focus) { + if (focus && focus != pressed) { focus->defocus(); } focus = pressed; @@ -75,6 +75,9 @@ void GUI::act(float delta) { for (auto key : Events::pressedKeys) { focus->keyPressed(key); } + if (Events::clicked(mousecode::BUTTON_1)) { + focus->mouseMove(this, mx, my); + } } } } diff --git a/src/frontend/gui/UINode.h b/src/frontend/gui/UINode.h index 63bb03d0..e9699118 100644 --- a/src/frontend/gui/UINode.h +++ b/src/frontend/gui/UINode.h @@ -57,6 +57,7 @@ namespace gui { glm::vec4 margin() const; virtual void click(GUI*, int x, int y); + virtual void mouseMove(GUI*, int x, int y) {}; virtual void mouseRelease(GUI*, int x, int y); bool ispressed() const; diff --git a/src/frontend/gui/controls.cpp b/src/frontend/gui/controls.cpp index 3c4ddf64..1cfd676f 100644 --- a/src/frontend/gui/controls.cpp +++ b/src/frontend/gui/controls.cpp @@ -148,4 +148,46 @@ wstring TextBox::text() const { if (input.empty()) return placeholder; return input; +} + +TrackBar::TrackBar(double min, double max, double value, double step) + : UINode(vec2(), vec2(32)), min(min), max(max), value(value), step(step) { + color(vec4(0.f, 0.f, 0.f, 0.4f)); +} + +void TrackBar::draw(Batch2D* batch, Assets* assets) { + if (supplier_) { + value = supplier_(); + } + vec2 coord = calcCoord(); + batch->texture(nullptr); + batch->color = (hover_ ? hoverColor : color_); + batch->rect(coord.x, coord.y, size_.x, size_.y); + + float width = size_.x; + float t = (value - min) / (max-min+trackWidth); + + batch->color = trackColor; + batch->rect(coord.x + width * t, coord.y, size_.x * (trackWidth / (max-min)), size_.y); +} + +void TrackBar::supplier(doublesupplier supplier) { + this->supplier_ = supplier; +} + +void TrackBar::consumer(doubleconsumer consumer) { + this->consumer_ = consumer; +} + +void TrackBar::mouseMove(GUI*, int x, int y) { + vec2 coord = calcCoord(); + x -= coord.x; + x = x/size_.x * (max-min+trackWidth); + x = (x > max) ? max : x; + x = (x < min) ? min : x; + x = (int)(x / step) * step; + value = x; + if (consumer_) { + consumer_(value); + } } \ No newline at end of file diff --git a/src/frontend/gui/controls.h b/src/frontend/gui/controls.h index 51303134..e5d520a0 100644 --- a/src/frontend/gui/controls.h +++ b/src/frontend/gui/controls.h @@ -16,6 +16,9 @@ namespace gui { typedef std::function wstringsupplier; typedef std::function wstringconsumer; + typedef std::function doublesupplier; + typedef std::function doubleconsumer; + class Label : public UINode { protected: std::wstring text_; @@ -27,10 +30,11 @@ namespace gui { virtual Label& text(std::wstring text); std::wstring text() const; - virtual void draw(Batch2D* batch, Assets* assets); + virtual void draw(Batch2D* batch, Assets* assets) override; virtual void textSupplier(wstringsupplier supplier); }; + class Button : public Panel { protected: glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f}; @@ -70,6 +74,28 @@ namespace gui { virtual bool isfocuskeeper() const override {return true;} virtual std::wstring text() const; }; + + class TrackBar : public UINode { + protected: + glm::vec4 hoverColor {0.01f, 0.02f, 0.03f, 0.5f}; + glm::vec4 trackColor {1.0f, 1.0f, 1.0f, 0.4f}; + Label* label; + doublesupplier supplier_ = nullptr; + doubleconsumer consumer_ = nullptr; + double min; + double max; + double value; + double step; + int trackWidth = 3; + public: + TrackBar(double min, double max, double value, double step=1.0); + virtual void draw(Batch2D* batch, Assets* assets) override; + + virtual void supplier(doublesupplier supplier); + virtual void consumer(doubleconsumer consumer); + + virtual void mouseMove(GUI*, int x, int y) override; + }; } #endif // FRONTEND_GUI_CONTROLS_H_ \ No newline at end of file diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 5d041f30..e95bedf2 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -51,6 +51,7 @@ HudRenderer::HudRenderer(Engine* engine, Level* level) : level(level), assets(en uicamera->flipped = true; Panel* panel = new Panel(vec2(250, 200), vec4(5.0f), 1.0f); + debugPanel = shared_ptr(panel); panel->listenInterval(1.0f, [this]() { fpsString = std::to_wstring(fpsMax)+L" / "+std::to_wstring(fpsMin); fpsMin = fps; @@ -112,26 +113,32 @@ HudRenderer::HudRenderer(Engine* engine, Level* level) : level(level), assets(en panel->add(shared_ptr(sub)); } panel->refresh(); - debugPanel = shared_ptr(panel); - Panel* pauseMenu = new Panel(vec2(350, 200)); - pauseMenu->color(vec4(0.0f)); + panel = new Panel(vec2(350, 200)); + pauseMenu = shared_ptr(panel); + panel->color(vec4(0.0f)); { Button* button = new Button(L"Continue", vec4(10.0f)); button->listenAction([this](GUI*){ this->pause = false; + pauseMenu->visible(false); }); - pauseMenu->add(shared_ptr(button)); + panel->add(shared_ptr(button)); } + panel->add((new Button(L"Settings", vec4(10.f)))->listenAction([=](GUI* gui) { + pauseMenu->visible(false); + gui->store("back", pauseMenu); + gui->get("settings")->visible(true); + })); { Button* button = new Button(L"Save and Quit to Menu", vec4(10.f)); button->listenAction([this, engine](GUI*){ this->pauseMenu->visible(false); engine->setScreen(shared_ptr(new MenuScreen(engine))); }); - pauseMenu->add(shared_ptr(button)); + panel->add(shared_ptr(button)); } - this->pauseMenu = std::shared_ptr(pauseMenu); + panel->visible(false); guiController->add(this->debugPanel); guiController->add(this->pauseMenu); } @@ -229,9 +236,11 @@ void HudRenderer::drawInventory(Player* player) { void HudRenderer::draw(){ debugPanel->visible(level->player->debug); - pauseMenu->visible(pause); pauseMenu->setCoord((Window::size() - pauseMenu->size()) / 2.0f); + auto settingsPanel = guiController->get("settings"); + settingsPanel->setCoord((Window::size() - settingsPanel->size()) / 2.0f); + glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); @@ -288,10 +297,13 @@ void HudRenderer::draw(){ if (Events::jpressed(keycode::ESCAPE) && !guiController->isFocusCaught()) { if (pause) { pause = false; + pauseMenu->visible(false); + settingsPanel->visible(false); } else if (inventoryOpen) { inventoryOpen = false; } else { pause = true; + pauseMenu->visible(true); } } if (Events::jpressed(keycode::TAB)) { diff --git a/src/frontend/screens.cpp b/src/frontend/screens.cpp index 9dbb2d1d..725bd283 100644 --- a/src/frontend/screens.cpp +++ b/src/frontend/screens.cpp @@ -37,8 +37,9 @@ using std::filesystem::u8path; using std::filesystem::directory_iterator; using namespace gui; -Panel* create_main_menu_panel(Engine* engine) { +shared_ptr create_main_menu_panel(Engine* engine) { Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 1.0f); + shared_ptr panelptr(panel); panel->color(vec4(0.0f)); panel->setCoord(vec2(10, 10)); @@ -65,15 +66,22 @@ Panel* create_main_menu_panel(Engine* engine) { worldsPanel->add(button); } panel->add(worldsPanel); + + panel->add((new Button(L"Settings", vec4(10.f)))->listenAction([=](GUI* gui) { + panel->visible(false); + gui->store("back", panelptr); + gui->get("settings")->visible(true); + })); panel->add((new Button(L"Quit", vec4(10.f)))->listenAction([](GUI*) { Window::setShouldClose(true); })); - return panel; + return panelptr; } -Panel* create_new_world_panel(Engine* engine) { +shared_ptr create_new_world_panel(Engine* engine) { Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 1.0f); + shared_ptr panelptr(panel); panel->color(vec4(0.0f)); panel->setCoord(vec2(10, 10)); @@ -157,19 +165,56 @@ Panel* create_new_world_panel(Engine* engine) { gui->get("main-menu")->visible(true); })); + return panelptr; +} + +Panel* create_settings_panel(Engine* engine) { + Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 1.0f); + panel->color(vec4(0.0f)); + panel->setCoord(vec2(10, 10)); + + { + Label* label = new Label(L""); + label->textSupplier([=]() { + return L"Load Distance: " + + std::to_wstring(engine->getSettings().chunks.loadDistance); + }); + panel->add(label); + + TrackBar* trackbar = new TrackBar(0, 64, 10); + trackbar->supplier([=]() { + return engine->getSettings().chunks.loadDistance; + }); + trackbar->consumer([=](double value) { + engine->getSettings().chunks.loadDistance = value; + }); + panel->add(trackbar); + } + + panel->add((new Button(L"Back", vec4(10.f)))->listenAction([=](GUI* gui) { + panel->visible(false); + gui->get("back")->visible(true); + })); return panel; } MenuScreen::MenuScreen(Engine* engine_) : Screen(engine_) { GUI* gui = engine->getGUI(); - panel = shared_ptr(create_main_menu_panel(engine)); - newWorldPanel = shared_ptr(create_new_world_panel(engine)); + panel = create_main_menu_panel(engine); + newWorldPanel = create_new_world_panel(engine); newWorldPanel->visible(false); + auto settingsPanel = shared_ptr(create_settings_panel(engine)); + settingsPanel->visible(false); + gui->store("main-menu", panel); gui->store("new-world", newWorldPanel); + if (gui->get("settings") == nullptr) { + gui->store("settings", settingsPanel); + } gui->add(panel); gui->add(newWorldPanel); + gui->add(settingsPanel); batch = new Batch2D(1024); uicamera = new Camera(vec3(), Window::height); @@ -196,6 +241,9 @@ void MenuScreen::draw(float delta) { panel->setCoord((Window::size() - panel->size()) / 2.0f); newWorldPanel->setCoord((Window::size() - newWorldPanel->size()) / 2.0f); + auto settingsPanel = engine->getGUI()->get("settings"); + settingsPanel->setCoord((Window::size() - settingsPanel->size()) / 2.0f); + Window::clear(); Window::setBgColor(vec3(0.2f, 0.2f, 0.2f)); @@ -261,6 +309,7 @@ void LevelScreen::update(float delta) { } level->updatePlayer(delta, !inputLocked, hud->isPause(), !inputLocked); level->update(); + level->chunksController->update(settings.chunks.loadSpeed); } diff --git a/src/frontend/screens.h b/src/frontend/screens.h index 2558c613..37c72b7f 100644 --- a/src/frontend/screens.h +++ b/src/frontend/screens.h @@ -16,7 +16,6 @@ namespace gui { class UINode; } - /* Screen is a mainloop state */ class Screen { protected: diff --git a/src/world/Level.cpp b/src/world/Level.cpp index d49ac6ea..293eda3f 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -11,11 +11,12 @@ #include "../objects/Player.h" #include "../objects/player_control.h" -Level::Level(World* world, Player* player, EngineSettings& settings) +Level::Level(World* world, Player* player, EngineSettings& settings) : world(world), player(player), chunksStorage(new ChunksStorage(this)), - events(new LevelEvents()) { + events(new LevelEvents()) , + settings(settings) { physics = new PhysicsSolver(vec3(0, -19.6f, 0)); uint matrixSize = (settings.chunks.loadDistance+ @@ -70,4 +71,10 @@ void Level::updatePlayer(float delta, void Level::update() { vec3 position = player->hitbox->position; chunks->setCenter(position.x, position.z); + + int matrixSize = (settings.chunks.loadDistance+ + settings.chunks.padding) * 2; + if (chunks->w != matrixSize) { + chunks->resize(matrixSize, matrixSize); + } } diff --git a/src/world/Level.h b/src/world/Level.h index 34ea8d31..1ba0b9d1 100644 --- a/src/world/Level.h +++ b/src/world/Level.h @@ -25,6 +25,7 @@ public: ChunksController* chunksController; PlayerController* playerController; LevelEvents* events; + const EngineSettings& settings; Level(World* world, Player* player,