From 579f4886d1765137016056d96514d3f81fee49cd Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Sat, 17 Jan 2026 20:06:57 +0300 Subject: [PATCH] Finally fixed bugs, now need to do cleanup --- src/Game.cpp | 167 +++++++++++++------------------- src/Game.h | 2 +- src/network/WebSocketClient.cpp | 24 ++++- 3 files changed, 91 insertions(+), 102 deletions(-) diff --git a/src/Game.cpp b/src/Game.cpp index 7d56b67..280061a 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -240,8 +240,8 @@ namespace ZL uiManager.setSliderCallback("velocitySlider", [this](const std::string& name, float value) { int newVel = roundf(value * 10); if (newVel != Environment::shipSelectedVelocity) { - velocityChanged = true; - Environment::shipSelectedVelocity = newVel; + newShipVelocity = newVel; + //Environment::shipSelectedVelocity = newVel; /*auto now_ms = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch() ).count(); @@ -649,49 +649,37 @@ namespace ZL void Game::processTickCount() { if (lastTickCount == 0) { - lastTickCount = SDL_GetTicks64(); + //lastTickCount = SDL_GetTicks64(); + lastTickCount = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch() + ).count(); return; } - newTickCount = SDL_GetTicks64(); + //newTickCount = SDL_GetTicks64(); + newTickCount = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch() + ).count(); + if (newTickCount - lastTickCount > CONST_TIMER_INTERVAL) { - size_t delta = (newTickCount - lastTickCount > CONST_MAX_TIME_INTERVAL) ? - CONST_MAX_TIME_INTERVAL : newTickCount - lastTickCount; + + size_t delta = newTickCount - lastTickCount; + if (delta > CONST_MAX_TIME_INTERVAL) + { + throw std::runtime_error("Synchronization is lost"); + } + + auto now_ms = newTickCount; sparkEmitter.update(static_cast(delta)); planetObject.update(static_cast(delta)); extrapolateRemotePlayers(); + //bool sendRotation = false; + static float pingTimer = 0.0f; pingTimer += delta; if (pingTimer >= 1000.0f) { - - auto now_ms = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch() - ).count(); - - // 1. Извлекаем кватернион из матрицы поворота - /* - Eigen::Quaternionf q(Environment::shipMatrix); - - // 2. Формируем строку PING согласно протоколу сервера - // Формат: PING:timestamp:posX:posY:posZ:qW:qX:qY:qZ:angVelX:angVelY:angVelZ:vel:selectedVel:discMag:discAngle - std::string pingMsg = "PING:" + std::to_string(now_ms) + ":" - + std::to_string(Environment::shipPosition.x()) + ":" - + std::to_string(Environment::shipPosition.y()) + ":" - + std::to_string(Environment::shipPosition.z()) + ":" - + std::to_string(q.w()) + ":" - + std::to_string(q.x()) + ":" - + std::to_string(q.y()) + ":" - + std::to_string(q.z()) + ":" - + std::to_string(Environment::currentAngularVelocity.x()) + ":" - + std::to_string(Environment::currentAngularVelocity.y()) + ":" - + std::to_string(Environment::currentAngularVelocity.z()) + ":" - + std::to_string(Environment::shipVelocity) + ":" - + std::to_string(Environment::shipSelectedVelocity) + ":" - + std::to_string(Environment::lastSentMagnitude) + ":" // Используем те же static переменные из блока ROT - + std::to_string(Environment::lastSentAngle); - */ std::string pingMsg = "PING:" + std::to_string(now_ms) + ":" + formPingMessageContent(); networkClient->Send(pingMsg); @@ -699,50 +687,17 @@ namespace ZL pingTimer = 0.0f; } - //static const float CONST_ACCELERATION = 1.f; - - float shipDesiredVelocity = Environment::shipSelectedVelocity * 100.f; - - if (!gameOver) + if (newShipVelocity != Environment::shipSelectedVelocity) { - if (Environment::shipVelocity < shipDesiredVelocity) - { - Environment::shipVelocity += delta * SHIP_ACCEL; - if (Environment::shipVelocity > shipDesiredVelocity) - { - Environment::shipVelocity = shipDesiredVelocity; - } - } - else if (Environment::shipVelocity > shipDesiredVelocity) - { - Environment::shipVelocity -= delta * SHIP_ACCEL; - if (Environment::shipVelocity < shipDesiredVelocity) - { - Environment::shipVelocity = shipDesiredVelocity; - } - } - } + Environment::shipSelectedVelocity = newShipVelocity; - if (velocityChanged) - { - velocityChanged = false; - //if (newVel != Environment::shipSelectedVelocity) { - // velocityChanged = true; - //Environment::shipSelectedVelocity = newVel; - auto now_ms = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch() - ).count(); - std::string msg = "VEL:" + std::to_string(now_ms) + ":" + std::to_string(Environment::shipSelectedVelocity); - msg = msg + ":" + formPingMessageContent(); - networkClient->Send(msg); + std::string msg = "VEL:" + std::to_string(now_ms) + ":" + std::to_string(Environment::shipSelectedVelocity); + msg = msg + ":" + formPingMessageContent(); + networkClient->Send(msg); //} } - - - //static const float ANGULAR_ACCEL = 0.005f; - if (Environment::tapDownHold) { float diffx = Environment::tapDownCurrentPos(0) - Environment::tapDownStartPos(0); float diffy = Environment::tapDownCurrentPos(1) - Environment::tapDownStartPos(1); @@ -770,7 +725,12 @@ namespace ZL Environment::lastSentAngle = discreteAngle; Environment::lastSentMagnitude = discreteMag; - sendRotation = true; + std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(Environment::lastSentAngle) + ":" + std::to_string(Environment::lastSentMagnitude); + msg = msg + ":" + formPingMessageContent(); + networkClient->Send(msg); + std::cout << "Sending: " << msg << std::endl; + + //sendRotation = true; /*auto now_ms = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch() ).count(); @@ -828,19 +788,6 @@ namespace ZL Environment::inverseShipMatrix = Environment::shipMatrix.inverse(); } - if (sendRotation) - { - auto now_ms = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch() - ).count(); - - // Формируем сетевой пакет - // Нам нужно отправить: дискретный угол, дискретную силу и текущую матрицу/позицию для синхронизации - std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(discreteAngle) + ":" + std::to_string(discreteMag); - msg = msg + ":" + formPingMessageContent(); - networkClient->Send(msg); - std::cout << "Sending: " << msg << std::endl; - } } } else { @@ -848,13 +795,16 @@ namespace ZL int discreteAngle = -1; float discreteMag = 0.0f; - bool sendRotation = false; - if (discreteAngle != Environment::lastSentAngle || discreteMag != Environment::lastSentMagnitude) { Environment::lastSentAngle = discreteAngle; Environment::lastSentMagnitude = discreteMag; + + std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(Environment::lastSentAngle) + ":" + std::to_string(Environment::lastSentMagnitude); + msg = msg + ":" + formPingMessageContent(); + networkClient->Send(msg); + std::cout << "Sending: " << msg << std::endl; - sendRotation = true; + //sendRotation = true; /* auto now_ms = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch() @@ -890,19 +840,24 @@ namespace ZL Environment::shipMatrix = Environment::shipMatrix * rotateQuat.toRotationMatrix(); Environment::inverseShipMatrix = Environment::shipMatrix.inverse(); } + } - if (sendRotation) + float shipDesiredVelocity = Environment::shipSelectedVelocity * 100.f; + + if (Environment::shipVelocity < shipDesiredVelocity) + { + Environment::shipVelocity += delta * SHIP_ACCEL; + if (Environment::shipVelocity > shipDesiredVelocity) { - auto now_ms = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch() - ).count(); - - // Формируем сетевой пакет - // Нам нужно отправить: дискретный угол, дискретную силу и текущую матрицу/позицию для синхронизации - std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(discreteAngle) + ":" + std::to_string(discreteMag); - msg = msg + ":" + formPingMessageContent(); - networkClient->Send(msg); - std::cout << "Sending: " << msg << std::endl; + Environment::shipVelocity = shipDesiredVelocity; + } + } + else if (Environment::shipVelocity > shipDesiredVelocity) + { + Environment::shipVelocity -= delta * SHIP_ACCEL; + if (Environment::shipVelocity < shipDesiredVelocity) + { + Environment::shipVelocity = shipDesiredVelocity; } } @@ -915,6 +870,20 @@ namespace ZL Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted; } + /* + if (sendRotation) + { + sendRotation = false; + + // Формируем сетевой пакет + // Нам нужно отправить: дискретный угол, дискретную силу и текущую матрицу/позицию для синхронизации + std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(Environment::lastSentAngle) + ":" + std::to_string(Environment::lastSentMagnitude); + msg = msg + ":" + formPingMessageContent(); + networkClient->Send(msg); + std::cout << "Sending: " << msg << std::endl; + } + */ + for (auto& p : projectiles) { if (p && p->isActive()) { p->update(static_cast(delta), renderer); diff --git a/src/Game.h b/src/Game.h index d76f738..1b68e81 100644 --- a/src/Game.h +++ b/src/Game.h @@ -67,7 +67,7 @@ namespace ZL { std::unordered_map latestRemotePlayers; - bool velocityChanged = false; + float newShipVelocity = 0; static const size_t CONST_TIMER_INTERVAL = 10; static const size_t CONST_MAX_TIME_INTERVAL = 1000; diff --git a/src/network/WebSocketClient.cpp b/src/network/WebSocketClient.cpp index 8be73d9..d8d153c 100644 --- a/src/network/WebSocketClient.cpp +++ b/src/network/WebSocketClient.cpp @@ -166,7 +166,19 @@ namespace ZL { { std::lock_guard pLock(playersMutex); auto& rp = remotePlayers[remoteId]; - rp.timedRemoteStates.push_back(remoteState); + + + + if (rp.timedRemoteStates.size() > 0 && rp.timedRemoteStates[rp.timedRemoteStates.size() - 1].lastUpdateServerTime == remoteState.lastUpdateServerTime) + { + rp.timedRemoteStates[rp.timedRemoteStates.size() - 1] = remoteState; + } + else + { + rp.timedRemoteStates.push_back(remoteState); + } + + //rp.timedRemoteStates.push_back(remoteState); auto cutoff_time = nowTime - std::chrono::milliseconds(CUTOFF_TIME); @@ -304,7 +316,15 @@ namespace ZL { remoteState.lastUpdateServerTime = uptime_timepoint; auto& rp = remotePlayers[id]; - rp.timedRemoteStates.push_back(remoteState); + + if (rp.timedRemoteStates.size() > 0 && rp.timedRemoteStates[rp.timedRemoteStates.size() - 1].lastUpdateServerTime == remoteState.lastUpdateServerTime) + { + rp.timedRemoteStates[rp.timedRemoteStates.size() - 1] = remoteState; + } + else + { + rp.timedRemoteStates.push_back(remoteState); + } auto cutoff_time = now_ms - std::chrono::milliseconds(CUTOFF_TIME);