diff --git a/include/Cubed/scene/world_scene.hpp b/include/Cubed/scene/world_scene.hpp index 376f14c..e1cba13 100644 --- a/include/Cubed/scene/world_scene.hpp +++ b/include/Cubed/scene/world_scene.hpp @@ -5,6 +5,7 @@ #include "Cubed/gameplay/client_world.hpp" #include "Cubed/gameplay/network_server.hpp" #include "Cubed/scene/scene.hpp" +#include "Cubed/ui/pasue_menu_ui_manager.hpp" #include "Cubed/ui/world_ui_manager.hpp" namespace Cubed { class SceneManager; @@ -28,6 +29,8 @@ public: SceneManager& scene_manager(); ClientWorld& client_world(); ServerWorld& server_world(); + bool pause() const; + void set_pause(bool pause); private: SceneManager& m_scene_manager; @@ -36,6 +39,8 @@ private: NetworkServer m_server; std::shared_ptr m_client; ClientWorld m_client_world; + bool m_paused = false; + PauseMenuUIManager m_pasue_menu; WorldUIManager m_ui_manager; const Argument& m_argument; }; diff --git a/include/Cubed/ui/image.hpp b/include/Cubed/ui/image.hpp index 06495cb..dd42a54 100644 --- a/include/Cubed/ui/image.hpp +++ b/include/Cubed/ui/image.hpp @@ -8,6 +8,10 @@ namespace Cubed { class TextureManager; class Image : public Widget { public: + Image(const Image&) = delete; + Image(Image&&) = delete; + Image& operator=(const Image&) = delete; + Image& operator=(Image&&) = delete; Image(Widget* parent); Image& set_image(const std::string& path, TextureManager& texture_manager); diff --git a/include/Cubed/ui/pasue_menu_ui_manager.hpp b/include/Cubed/ui/pasue_menu_ui_manager.hpp new file mode 100644 index 0000000..5de08be --- /dev/null +++ b/include/Cubed/ui/pasue_menu_ui_manager.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "Cubed/ui/ui_manager.hpp" +namespace Cubed { +class WorldScene; +class PauseMenuUIManager : public UIManager { +public: + PauseMenuUIManager(const PauseMenuUIManager&) = delete; + PauseMenuUIManager(PauseMenuUIManager&&) = delete; + PauseMenuUIManager& operator=(const PauseMenuUIManager&) = delete; + PauseMenuUIManager& operator=(PauseMenuUIManager&&) = delete; + PauseMenuUIManager(WorldScene& scene); + void init() override; + +private: + WorldScene& m_scene; + + bool handle_key_event(const KeyEvent& e) override; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/window.hpp b/include/Cubed/window.hpp index ee21f84..6772f27 100644 --- a/include/Cubed/window.hpp +++ b/include/Cubed/window.hpp @@ -25,7 +25,9 @@ public: void hot_reload(); void toggle_fullscreen(); - void toggle_mouse_able(); + + void enable_mouse(); + void disable_mouse(); void set_camera(Camera* camera); Camera* camera(); @@ -34,6 +36,10 @@ public: void should_close_window(); + bool is_enable_imgui() const; + + void set_imgui_enabled(bool enable); + private: bool m_mouse_enable = false; bool m_imgui_init = false; @@ -43,6 +49,7 @@ private: int m_window_height; Config& m_config; Camera* m_camera = nullptr; + bool m_imgui_enable = false; bool handle_key_event(const KeyEvent& e); bool handle_window_resize_event(const WindowResizeEvent& e); bool handle_mouse_button_event(const MouseButtonEvent& e); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4afa922..a78121b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,4 +70,5 @@ target_sources(${PROJECT_NAME} ui/column_layout.cpp ui/rect.cpp ui/ui_manager.cpp + ui/pause_menu_ui_manager.cpp ) \ No newline at end of file diff --git a/src/app.cpp b/src/app.cpp index 26cb977..ac830f5 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -28,14 +28,13 @@ void App::cursor_position_callback(GLFWwindow* window, double xpos, App* app = static_cast(glfwGetWindowUserPointer(window)); ASSERT_MSG(app, "nullptr"); - if (io.WantCaptureMouse && app->m_window.is_mouse_enable()) { + if (io.WantCaptureMouse && app->m_window.is_enable_imgui()) { ImGui_ImplGlfw_CursorPosCallback(window, xpos, ypos); return; } - if (!app->m_window.is_mouse_enable()) { - app->m_scene_manager.handle_event( - MouseMoveEvent{static_cast(xpos), static_cast(ypos)}); - } + + app->m_scene_manager.handle_event( + MouseMoveEvent{static_cast(xpos), static_cast(ypos)}); } void App::init(int argc, char** argv) { handle_toml(); @@ -173,7 +172,7 @@ void App::key_callback(GLFWwindow* window, int key, int scancode, int action, ASSERT_MSG(app, "nullptr"); // ImGui_ImplGlfw_CursorEnterCallback(window, // !app->m_window.is_mouse_enable()); - if (io.WantCaptureKeyboard && app->m_window.is_mouse_enable()) { + if (io.WantCaptureKeyboard && app->m_window.is_enable_imgui()) { if ((key == GLFW_KEY_LEFT_ALT) && action == GLFW_PRESS) { app->dispatch_event(KeyEvent{Key::LEFT_ALT, KeyAction::PRESS}); return; @@ -532,7 +531,7 @@ void App::mouse_button_callback(GLFWwindow* window, int button, int action, ImGuiIO& io = ImGui::GetIO(); App* app = static_cast(glfwGetWindowUserPointer(window)); ASSERT_MSG(app, "nullptr"); - if (io.WantCaptureMouse && app->m_window.is_mouse_enable()) { + if (io.WantCaptureMouse && app->m_window.is_enable_imgui()) { ImGui_ImplGlfw_MouseButtonCallback(window, button, action, mods); return; } @@ -582,7 +581,7 @@ void App::window_focus_callback(GLFWwindow* window, int focused) { ImGuiIO& io = ImGui::GetIO(); App* app = static_cast(glfwGetWindowUserPointer(window)); ASSERT_MSG(app, "nullptr"); - if (io.WantCaptureMouse && app->m_window.is_mouse_enable()) { + if (io.WantCaptureMouse && app->m_window.is_enable_imgui()) { ImGui_ImplGlfw_WindowFocusCallback(window, focused); return; } @@ -616,7 +615,7 @@ void App::mouse_scroll_callback(GLFWwindow* window, double xoffset, App* app = static_cast(glfwGetWindowUserPointer(window)); ASSERT_MSG(app, "nullptr"); - if (io.WantCaptureMouse && app->m_window.is_mouse_enable()) { + if (io.WantCaptureMouse && app->m_window.is_enable_imgui()) { ImGui_ImplGlfw_ScrollCallback(window, xoffset, yoffset); return; } @@ -627,7 +626,7 @@ void App::cursor_enter_callback(GLFWwindow* window, int entered) { ImGuiIO& io = ImGui::GetIO(); App* app = static_cast(glfwGetWindowUserPointer(window)); ASSERT_MSG(app, "nullptr"); - if (io.WantCaptureMouse && app->m_window.is_mouse_enable()) { + if (io.WantCaptureMouse && app->m_window.is_enable_imgui()) { ImGui_ImplGlfw_CursorEnterCallback(window, entered); return; } @@ -637,8 +636,9 @@ void App::char_callback(GLFWwindow* window, unsigned int c) { ImGuiIO& io = ImGui::GetIO(); App* app = static_cast(glfwGetWindowUserPointer(window)); ASSERT_MSG(app, "nullptr"); - if (io.WantCaptureKeyboard && app->m_window.is_mouse_enable()) { + if (io.WantCaptureKeyboard && app->m_window.is_enable_imgui()) { ImGui_ImplGlfw_CharCallback(window, c); + return; } } diff --git a/src/gameplay/client_player.cpp b/src/gameplay/client_player.cpp index 82c1c96..0df5659 100644 --- a/src/gameplay/client_player.cpp +++ b/src/gameplay/client_player.cpp @@ -4,6 +4,7 @@ #include "Cubed/config.hpp" #include "Cubed/debug_collector.hpp" #include "Cubed/gameplay/client_world.hpp" +#include "Cubed/scene/world_scene.hpp" namespace {} // namespace @@ -582,6 +583,12 @@ bool ClientPlayer::handle_mouse_button_event(const MouseButtonEvent& e) { } bool ClientPlayer::handle_key_event(const KeyEvent& e) { + + if (e.key == Key::ESCAPE && e.action == KeyAction::PRESS) { + m_world.world_scene().set_pause(true); + return true; + } + if (update_player_move_state(e.key, e.action)) { return true; } diff --git a/src/scene/world_scene.cpp b/src/scene/world_scene.cpp index 94a37b3..3b825e2 100644 --- a/src/scene/world_scene.cpp +++ b/src/scene/world_scene.cpp @@ -8,7 +8,8 @@ WorldScene::WorldScene(SceneManager& scene_manager) : m_scene_manager(scene_manager), m_dev_panel(*this), m_client_world(scene_manager.app().audio(), scene_manager.app().config(), *this), - m_ui_manager(*this), m_argument(scene_manager.app().argument()) {} + m_pasue_menu(*this), m_ui_manager(*this), + m_argument(scene_manager.app().argument()) {} WorldScene::~WorldScene() { if (m_client) { @@ -17,45 +18,61 @@ WorldScene::~WorldScene() { } void WorldScene::update(float dt) { - m_client_world.update(dt); - m_camera.update_move_camera(); - m_client_world.get_audio().update_listener(m_camera.get_camera_pos(), - m_camera.get_camera_front(), - glm::vec3(0, 1, 0)); + if (m_paused) { + m_pasue_menu.update(dt); + } else { + m_client_world.update(dt); + m_camera.update_move_camera(); + m_client_world.get_audio().update_listener(m_camera.get_camera_pos(), + m_camera.get_camera_front(), + glm::vec3(0, 1, 0)); - /* - const auto& player = m_client_world.get_player(); - if (player_gait != player.get_gait()) { - player_gait = player.get_gait(); - float fov = m_client_world.get("player.fov", 70.0f); - if (player_gait == Gait::WALK) { - m_renderer.update_fov(fov); - } - if (player_gait == Gait::RUN) { - m_renderer.update_fov(fov + 5.0f); - } - }*/ - m_ui_manager.update(dt); + /* + const auto& player = m_client_world.get_player(); + if (player_gait != player.get_gait()) { + player_gait = player.get_gait(); + float fov = m_client_world.get("player.fov", 70.0f); + if (player_gait == Gait::WALK) { + m_renderer.update_fov(fov); + } + if (player_gait == Gait::RUN) { + m_renderer.update_fov(fov + 5.0f); + } + }*/ + m_ui_manager.update(dt); + } } void WorldScene::render(Renderer& renderer) { renderer.render_world(m_client_world); - renderer.render_dev_panel(m_dev_panel); - m_ui_manager.render(renderer); + + if (m_paused) { + m_pasue_menu.render(renderer); + } else { + renderer.render_dev_panel(m_dev_panel); + } } bool WorldScene::handle_event(const Event& e) { - if (m_ui_manager.handle_event(e)) { - return true; - } - if (m_camera.handle_event(e)) { - return true; - } - // world event needs to be processed last - if (m_client_world.handle_event(e)) { - return true; + if (m_paused) { + + if (m_pasue_menu.handle_event(e)) { + + return true; + } + } else { + if (m_ui_manager.handle_event(e)) { + return true; + } + if (m_camera.handle_event(e)) { + return true; + } + // world event needs to be processed last + if (m_client_world.handle_event(e)) { + return true; + } } return false; } @@ -76,6 +93,7 @@ void WorldScene::on_enter() { m_camera.camera_init(&m_client_world.get_player()); m_scene_manager.app().window().set_camera(&m_camera); m_dev_panel.init(); + m_pasue_menu.init(); m_ui_manager.init(); m_scene_manager.app().window().set_game_running(true); @@ -95,4 +113,11 @@ Camera& WorldScene::camera() { return m_camera; } SceneManager& WorldScene::scene_manager() { return m_scene_manager; } ClientWorld& WorldScene::client_world() { return m_client_world; } ServerWorld& WorldScene::server_world() { return m_server.server_world(); } +bool WorldScene::pause() const { return m_paused; } +void WorldScene::set_pause(bool pause) { + m_paused = pause; + auto& window = m_scene_manager.app().window(); + Logger::info("pause {}", m_paused); + window.set_game_running(!m_paused); +} } // namespace Cubed \ No newline at end of file diff --git a/src/ui/button.cpp b/src/ui/button.cpp index ecae590..ee8c537 100644 --- a/src/ui/button.cpp +++ b/src/ui/button.cpp @@ -23,11 +23,9 @@ void Button::on_render(Renderer& renderer) { bool Button::handle_mouse_move_event(const MouseMoveEvent& e) { auto pos = m_background->pos(); - if (e.xpos >= pos.x && e.xpos <= pos.x + width() && e.ypos >= pos.y && e.ypos <= pos.y + height()) { m_hovered = true; - return true; } m_hovered = false; diff --git a/src/ui/pause_menu_ui_manager.cpp b/src/ui/pause_menu_ui_manager.cpp new file mode 100644 index 0000000..b4ebb52 --- /dev/null +++ b/src/ui/pause_menu_ui_manager.cpp @@ -0,0 +1,41 @@ +#include "Cubed/app.hpp" +#include "Cubed/render/renderer.hpp" +#include "Cubed/scene/scene_manager.hpp" +#include "Cubed/scene/world_scene.hpp" +#include "Cubed/ui/button.hpp" +#include "Cubed/ui/pasue_menu_ui_manager.hpp" +#include "Cubed/ui/rect.hpp" +namespace Cubed { +PauseMenuUIManager::PauseMenuUIManager(WorldScene& scene) : m_scene(scene) {} +void PauseMenuUIManager::init() { + auto rect = std::make_unique(nullptr); + + rect->set_fill(true); + rect->set_color(Color::BLACK); + rect->set_alpha(0.5f); + rect->set_anchor(Anchor::TOP_LEFT); + auto& renderer = m_scene.scene_manager().app().renderer(); + rect->set_window_size(renderer.window_width(), renderer.window_height()); + auto& back_main = rect->add_child