diff --git a/CMakeLists.txt b/CMakeLists.txt index 45a562e..0c3c29e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,9 @@ set(SOURCE_FILES src/graphics/ui/UIRenderer.cpp src/graphics/font/BitmapFont.cpp src/utils/ConfigLoader.cpp + src/core/DebugManager.cpp + src/ui/managers/debug/DebugOverlay.cpp + src/core/Time.cpp ) diff --git a/src/core/DebugManager.cpp b/src/core/DebugManager.cpp new file mode 100644 index 0000000..9463bad --- /dev/null +++ b/src/core/DebugManager.cpp @@ -0,0 +1,52 @@ +#include "DebugManager.h" +#include "Time.h" +#include +DebugManager::DebugManager( + const SDL_Renderer* renderer, + const SDL_Window* window, + //const InputState& inputState, + UIRenderer* uiRenderer + ): + m_renderer(renderer), + m_window(window), + //m_inputState(inputState), + m_uiRenderer(uiRenderer) +{ + +} + +DebugManager::~DebugManager() { + +} + +void DebugManager::initialize() { + m_debugOverlay = std::make_unique(m_debugData); + m_debugOverlay->initialize(); + m_isDebugInfoVisible = true; +} + +void DebugManager::updateMousePos(int logicalX, int logicalY, const InputState& inputState) { + m_debugData.mousePosition = { + static_cast(inputState.mouseCurrentPosition.first), + static_cast(inputState.mouseCurrentPosition.second) + }; + m_debugData.mouseLogicalPostion = {logicalX, logicalY}; + +} + +void DebugManager::updateDebugInfo() { + m_debugData.currentFPS = static_cast(Time::fps()); + //std::cout << "FPS: " << m_debugData.currentFPS << std::endl; + + m_debugOverlay->updateDebugInfo(); + +} + +void DebugManager::showDebugInfo() { + //m_isDebugInfoVisible = !m_isDebugInfoVisible; + if (m_isDebugInfoVisible) { + + m_uiRenderer->renderUI(m_debugOverlay->getUIRenderData()); + } + +} \ No newline at end of file diff --git a/src/core/DebugManager.h b/src/core/DebugManager.h new file mode 100644 index 0000000..4e70841 --- /dev/null +++ b/src/core/DebugManager.h @@ -0,0 +1,35 @@ +#pragma once +#include "ui/managers/debug/DebugOverlay.h" +#include +#include "input/InputState.h" +#include "graphics/ui/UIRenderer.h" + +class DebugManager { +public: + DebugManager( + const SDL_Renderer* renderer, + const SDL_Window* window, + //const InputState& inputState, + UIRenderer* uiRenderer + ); + ~DebugManager(); + + void initialize(); + //void shutdown(); + + void showDebugInfo(); + + void updateMousePos(int logicalX, int logicalY, const InputState& inputState); + void updateDebugInfo(); + +private: + std::unique_ptr m_debugOverlay; + DebugData m_debugData; + const SDL_Renderer* m_renderer = nullptr; + const SDL_Window* m_window = nullptr; + //const InputState& m_inputState; + bool m_isDebugInfoVisible = false; + + UIRenderer* m_uiRenderer = nullptr; + +}; \ No newline at end of file diff --git a/src/core/GameApplication.cpp b/src/core/GameApplication.cpp index 566254f..15c76a3 100644 --- a/src/core/GameApplication.cpp +++ b/src/core/GameApplication.cpp @@ -1,5 +1,6 @@ #include "GameApplication.h" #include "utils/Tools.h" +#include "Time.h" GameApplication::GameApplication() { } @@ -21,6 +22,7 @@ bool GameApplication::initialize() { if (!ConfigLoader::load("assets/config.json", m_config)) { SDL_Log("无法加载json"); } + Time::init(); // 输入管理 m_inputManager = std::make_unique(); // 窗口管理 @@ -36,7 +38,14 @@ bool GameApplication::initialize() { m_textRenderer = std::make_unique(m_windowManager->GetRenderer(), m_fontManager.get(), m_windowManager->getViewport()); m_uiRenderer = std:: make_unique(m_windowManager->GetRenderer(), m_textRenderer.get()); - + // 调试管理 + m_debugManager = std::make_unique( + m_windowManager->GetRenderer(), + m_windowManager->GetWindow(), + //m_inputManager->GetInputState(), + m_uiRenderer.get() + ); + m_debugManager->initialize(); // 场景管理,传入窗口句柄以便 SceneManager 能获取窗口尺寸 m_sceneManager = std::make_unique(m_windowManager->GetRenderer(), m_uiRenderer.get(), m_windowManager->GetWindow()); if (!m_sceneManager->initialize()) { @@ -56,8 +65,11 @@ SDL_AppResult GameApplication::handleInputEvent(SDL_Event* event) { m_sceneManager->handleClickCurrent(pos); } auto pos = Tools::physicalToLogical(input.mouseCurrentPosition.first, input.mouseCurrentPosition.second, m_windowManager->getViewport()); + + m_debugManager->updateMousePos(pos.first, pos.second, input); m_sceneManager->handleMousePosition(pos); m_windowManager->setFullscreen(input.isFullscreen); + // 改变窗口时清理旧的缓存 if (event->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { m_windowManager->onWindowResize(); @@ -69,16 +81,17 @@ SDL_AppResult GameApplication::handleInputEvent(SDL_Event* event) { } void GameApplication::run() { - + Time::update(); m_sceneManager->updateCurrent(); - + m_debugManager->updateDebugInfo(); m_windowManager->Clear(); m_windowManager->beginWorld(); m_sceneManager->renderWorld(); m_windowManager->endWorld(); - + m_windowManager->beginUI(); - m_sceneManager->renderUI(); + m_sceneManager->renderUI(); + m_debugManager->showDebugInfo(); m_windowManager->endUI(); m_windowManager->Present(); diff --git a/src/core/GameApplication.h b/src/core/GameApplication.h index 2df6e88..e96cb3c 100644 --- a/src/core/GameApplication.h +++ b/src/core/GameApplication.h @@ -8,7 +8,7 @@ #include "utils/ConfigLoader.h" #include "graphics/font/TextRenderer.h" #include "graphics/font/FontManager.h" - +#include "core/DebugManager.h" class GameApplication { private: @@ -20,7 +20,7 @@ private: std::unique_ptr m_fontManager; std::unique_ptr m_textRenderer; std::unique_ptr m_uiRenderer; - + std::unique_ptr m_debugManager; Config m_config; public: diff --git a/src/ui/base/UIWidgetFactory.h b/src/ui/base/UIWidgetFactory.h index dc3d9e3..1c2fe33 100644 --- a/src/ui/base/UIWidgetFactory.h +++ b/src/ui/base/UIWidgetFactory.h @@ -20,6 +20,7 @@ public: label->setRect(x, y, UI::ButtonSize * 4, UI::ButtonSize * 2); label->setText(text, {"SourceHanSansSC-Regular.otf", UI::UI_NORMAL_FONT_SIZE, {0, 0, 0, 255}}); label->setName(name); + label->setVisible(true); return label; } diff --git a/src/ui/managers/debug/DebugData.h b/src/ui/managers/debug/DebugData.h new file mode 100644 index 0000000..b941a7e --- /dev/null +++ b/src/ui/managers/debug/DebugData.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include + +struct DebugData { + bool showFPS = true; + bool showMousePosition = true; + std::pair mousePosition = {0, 0}; + std::pair mouseLogicalPostion = {0, 0}; + int currentFPS = 0; + +}; \ No newline at end of file diff --git a/src/ui/managers/debug/DebugOverlay.cpp b/src/ui/managers/debug/DebugOverlay.cpp new file mode 100644 index 0000000..65070e7 --- /dev/null +++ b/src/ui/managers/debug/DebugOverlay.cpp @@ -0,0 +1,128 @@ +#include "DebugOverlay.h" +#include "ui/base/UIWidgetFactory.h" +#include +DebugOverlay::DebugOverlay(DebugData& debugData) + : m_debugData(debugData) { + +} + +DebugOverlay::~DebugOverlay() { + +} + +void DebugOverlay::initialize() { + auto fpsLabel = UIWidgetFactory::createStandardLabel( + "FPS", + "FPS: 0", + 0, + 0 + ); + + m_labels.emplace(fpsLabel->getNameHash(), std::move(fpsLabel)); + auto mousePhyicalPos = UIWidgetFactory::createStandardLabel( + "MousePhyscialPosition", + "PhyscialPos: 0, 0", + 0, + 40 + ); + m_labels.emplace(mousePhyicalPos->getNameHash(), std::move(mousePhyicalPos)); + + auto mouseLogicalPos = UIWidgetFactory::createStandardLabel( + "MouseLogicalPosition", + "LogicalPos: 0, 0", + 0, + 80 + ); + m_labels.emplace(mouseLogicalPos->getNameHash(), std::move(mouseLogicalPos)); +} + + +const UIRenderData& DebugOverlay::getUIRenderData() { + collectRenderData(); + return m_uiRenderData; +} + +void DebugOverlay::collectRenderData() { + // 清理上一帧的数据 + m_uiRenderData.buttons.clear(); + m_uiRenderData.labels.clear(); + + for (auto& label : m_labels) { + if(!label.second->isVisible()) { + continue; + + } + m_uiRenderData.labels.push_back(label.second->getLabelDate()); + //std::cout << "Collect label: " << label.second->getNameHash() << "\n"; + } +} + +void DebugOverlay::updateDebugInfo() { + const auto key = makeHash("FPS"); + auto fpsLabelIt = m_labels.find(key); + + if (fpsLabelIt != m_labels.end()) { + auto fpsLabel = fpsLabelIt->second.get(); + + if (m_debugData.showFPS) { + fpsLabel->setText("FPS: " + std::to_string(m_debugData.currentFPS)); + fpsLabel->setVisible(true); + } else { + + fpsLabel->setVisible(false); + } + } else { + std::cerr << "FPS Label not found!\n"; + } + const auto mouseKey = makeHash("MousePhyscialPosition"); + auto mousePosLabelIt = m_labels.find(mouseKey); + + if (mousePosLabelIt != m_labels.end()) { + auto mousePosLabel = mousePosLabelIt->second.get(); + + if (m_debugData.showMousePosition) { + + if (!mousePosLabel) { + std::cerr << "Mouse PhyscialPosition Label not found!\n"; + return; + } + mousePosLabel->setText( + "PhyscialPos: " + + std::to_string(m_debugData.mousePosition.first) + ", " + + std::to_string(m_debugData.mousePosition.second) + ); + + mousePosLabel->setVisible(true); + } else { + + mousePosLabel->setVisible(false); + } + } else { + std::cerr << "Mouse PhyscialPosition Label not found!\n"; + } + const auto mouseLogicalKey = makeHash("MouseLogicalPosition"); + auto mouseLogicalPosLabelIt = m_labels.find(mouseLogicalKey); + if (mouseLogicalPosLabelIt != m_labels.end()) { + auto mouseLogicalPosLabel = mouseLogicalPosLabelIt->second.get(); + + if (m_debugData.showMousePosition) { + + if (!mouseLogicalPosLabel) { + std::cerr << "Mouse LogicalPosition Label not found!\n"; + return; + } + mouseLogicalPosLabel->setText( + "LogicalPos: " + + std::to_string(m_debugData.mouseLogicalPostion.first) + ", " + + std::to_string(m_debugData.mouseLogicalPostion.second) + ); + + mouseLogicalPosLabel->setVisible(true); + } else { + + mouseLogicalPosLabel->setVisible(false); + } + } else { + std::cerr << "Mouse LogicalPosition Label not found!\n"; + } +} \ No newline at end of file diff --git a/src/ui/managers/debug/DebugOverlay.h b/src/ui/managers/debug/DebugOverlay.h new file mode 100644 index 0000000..4b0c111 --- /dev/null +++ b/src/ui/managers/debug/DebugOverlay.h @@ -0,0 +1,38 @@ +#pragma once + +#include "ui/components/Label.h" +#include "DebugData.h" +#include +#include + +class DebugOverlay { +public: + DebugOverlay(DebugData& debugData); + ~DebugOverlay(); + + void initialize(); + //void shutdown(); + + + void collectRenderData(); + + const UIRenderData& getUIRenderData(); + + void updateDebugInfo(); + + + // 应该添加: + DebugOverlay(const DebugOverlay&) = delete; + DebugOverlay& operator=(const DebugOverlay&) = delete; + DebugOverlay(DebugOverlay&&) = delete; + DebugOverlay& operator=(DebugOverlay&&) = delete; + +private: + DebugData& m_debugData; + std::unordered_map> m_labels; + UIRenderData m_uiRenderData; + + size_t makeHash(const std::string& name) { + return std::hash{}(name); + } +}; \ No newline at end of file