diff --git a/resources/config/ui.json b/resources/config/ui.json index 678e35e..644f035 100644 --- a/resources/config/ui.json +++ b/resources/config/ui.json @@ -163,7 +163,19 @@ "hover": "resources/shoot_hover.png", "pressed": "resources/shoot_pressed.png" } - } + }, + { + "type": "TextView", + "name": "velocityText", + "x": 10, + "y": 10, + "width": 200, + "height": 40, + "text": "Velocity: 0", + "fontSize": 24, + "color": [1.0, 1.0, 1.0, 1.0], + "centered": false + } ] } } \ No newline at end of file diff --git a/server/server.cpp b/server/server.cpp index bce913b..9f6ef0f 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -755,6 +755,7 @@ int main() { } net::io_context ioc; tcp::acceptor acceptor{ ioc, {tcp::v4(), 8080} }; + int next_id = 1000; std::cout << "Server started on port 8080...\n"; diff --git a/src/Game.cpp b/src/Game.cpp index b5d0cc1..ec7a61d 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -275,6 +275,15 @@ namespace ZL loadGameplayUI = [this]() { uiManager.loadFromFile("resources/config/ui.json", renderer, CONST_ZIP_FILE); + auto velocityTv = uiManager.findTextView("velocityText"); + if (velocityTv) { + velocityTv->rect.x = 10.0f; + velocityTv->rect.y = static_cast(Environment::height) - velocityTv->rect.h - 10.0f; + } + else { + std::cerr << "Failed to find velocityText in UI" << std::endl; + } + uiManager.startAnimationOnNode("backgroundNode", "bgScroll"); static bool isExitButtonAnimating = false; uiManager.setAnimationCallback("settingsButton", "buttonsExit", [this]() { @@ -812,6 +821,7 @@ namespace ZL for (auto const& [id, remotePlayer] : remotePlayerStates) { +//<<<<<<< HEAD const ClientState& st = remotePlayer; // Позиция корабля в мире Vector3f shipWorld = st.position; @@ -1233,6 +1243,15 @@ namespace ZL } }*/ + // update velocity text + if (shipAlive && !gameOver) { + auto velocityTv = uiManager.findTextView("velocityText"); + if (velocityTv) { + std::string velocityStr = "Velocity: " + std::to_string(static_cast(Environment::shipState.velocity)); + uiManager.setText("velocityText", velocityStr); + } + } + uiManager.update(static_cast(delta)); lastTickCount = newTickCount; } diff --git a/src/Game.h b/src/Game.h index 273eaf4..02711f6 100644 --- a/src/Game.h +++ b/src/Game.h @@ -119,6 +119,7 @@ namespace ZL { uint64_t lastExplosionTime = 0; const uint64_t explosionDurationMs = 500; + bool serverBoxesApplied = false; static constexpr float MAX_DIST_SQ = 10000.f * 10000.f; @@ -127,10 +128,12 @@ namespace ZL { static constexpr float BASE_SCALE = 140.f; static constexpr float PERSPECTIVE_K = 0.05f; // Tune static constexpr float MIN_SCALE = 0.4f; - static constexpr float MAX_SCALE = 1.5f; + static constexpr float MAX_SCALE = 0.8f; + static constexpr float CLOSE_DIST = 600.0f; std::unordered_set deadRemotePlayers; + }; diff --git a/src/UiManager.cpp b/src/UiManager.cpp index 5187433..86a4fb5 100644 --- a/src/UiManager.cpp +++ b/src/UiManager.cpp @@ -1,5 +1,6 @@ #include "UiManager.h" #include "utils/Utils.h" +#include "render/TextRenderer.h" #include #include #include @@ -205,6 +206,7 @@ namespace ZL { layoutNode(root); buttons.clear(); sliders.clear(); + textViews.clear(); collectButtonsAndSliders(root); nodeActiveAnims.clear(); @@ -327,6 +329,29 @@ namespace ZL { } } + if (node->type == "TextView") { + auto tv = std::make_shared(); + tv->name = node->name; + tv->rect = node->rect; + + if (j.contains("text")) tv->text = j["text"].get(); + if (j.contains("fontPath")) tv->fontPath = j["fontPath"].get(); + if (j.contains("fontSize")) tv->fontSize = j["fontSize"].get(); + if (j.contains("color") && j["color"].is_array() && j["color"].size() == 4) { + for (int i = 0; i < 4; ++i) { + tv->color[i] = j["color"][i].get(); + } + } + if (j.contains("centered")) tv->centered = j["centered"].get(); + + tv->textRenderer = std::make_unique(); + if (!tv->textRenderer->init(renderer, tv->fontPath, tv->fontSize)) { + std::cerr << "Failed to init TextRenderer for TextView: " << tv->name << std::endl; + } + + node->textView = tv; + } + if (j.contains("children") && j["children"].is_array()) { for (const auto& ch : j["children"]) { node->children.push_back(parseNode(ch, renderer, zipFile)); @@ -376,7 +401,10 @@ namespace ZL { if (node->slider) { sliders.push_back(node->slider); } - for (auto& c : node->children) collectButtonsAndSliders(c); + if (node->textView) { + textViews.push_back(node->textView); + } + for (auto& c : node->children) collectButtonsAndSliders(c); // collectControls } bool UiManager::setButtonCallback(const std::string& name, std::function cb) { @@ -532,6 +560,9 @@ namespace ZL { for (const auto& s : sliders) { s->draw(renderer); } + for (const auto& tv : textViews) { + tv->draw(renderer); + } renderer.PopMatrix(); renderer.PopProjectionMatrix(); @@ -862,4 +893,20 @@ namespace ZL { return true; } + std::shared_ptr UiManager::findTextView(const std::string& name) { + for (auto& tv : textViews) { + if (tv->name == name) return tv; + } + return nullptr; + } + + bool UiManager::setText(const std::string& name, const std::string& newText) { + auto tv = findTextView(name); + if (!tv) { + return false; + } + tv->text = newText; + return true; + } + } // namespace ZL \ No newline at end of file diff --git a/src/UiManager.h b/src/UiManager.h index 5891566..5cfe6c8 100644 --- a/src/UiManager.h +++ b/src/UiManager.h @@ -2,6 +2,7 @@ #include "render/Renderer.h" #include "render/TextureManager.h" +#include "render/TextRenderer.h" #include "Environment.h" #include "external/nlohmann/json.hpp" #include @@ -71,6 +72,24 @@ namespace ZL { void draw(Renderer& renderer) const; }; + struct UiTextView { + std::string name; + UiRect rect; + std::string text = ""; + std::string fontPath = "resources/fonts/DroidSans.ttf"; + int fontSize = 32; + std::array color = { 1.f, 1.f, 1.f, 1.f }; // rgba + bool centered = true; + + std::unique_ptr textRenderer; + + void draw(Renderer& renderer) const { + if (textRenderer) { + textRenderer->drawText(text, rect.x + rect.w / 2, rect.y + rect.h / 2, 1.0f, centered, color); + } + } + }; + struct UiNode { std::string type; UiRect rect; @@ -78,6 +97,7 @@ namespace ZL { std::vector> children; std::shared_ptr button; std::shared_ptr slider; + std::shared_ptr textView; std::string orientation = "vertical"; float spacing = 0.0f; @@ -135,6 +155,9 @@ namespace ZL { bool setSliderCallback(const std::string& name, std::function cb); bool setSliderValue(const std::string& name, float value); // programmatic set (clamped 0..1) + std::shared_ptr findTextView(const std::string& name); + bool setText(const std::string& name, const std::string& newText); + bool pushMenuFromFile(const std::string& path, Renderer& renderer, const std::string& zipFile = ""); bool popMenu(); void clearMenuStack(); @@ -176,6 +199,7 @@ namespace ZL { std::shared_ptr root; std::vector> buttons; std::vector> sliders; + std::vector> textViews; std::map, std::vector> nodeActiveAnims; std::map, std::function> animCallbacks; // key: (nodeName, animName) @@ -194,6 +218,7 @@ namespace ZL { }; std::vector menuStack; + }; } // namespace ZL \ No newline at end of file