Working on server

This commit is contained in:
Vladislav Khorev committed 2026-01-15 21:54:37 +03:00
1 parent ea26d6fb23
commit 1348efb5fe
13 files changed
+761 -193

No files matched your search

+201 -106
View File
@@ -19,6 +19,8 @@
#include "network/LocalClient.h"
#endif
#include "network/RemotePlayer.h"
namespace ZL
{
#ifdef EMSCRIPTEN
@@ -139,33 +141,6 @@ namespace ZL
ZL::BindOpenGlFunctions();
ZL::CheckGlError();
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO, "Game", "Start for Android");
const char* testFiles[] = {
"resources/shaders/default.vertex",
"resources/shaders/default_web.fragment",
nullptr
};
for (int i = 0; testFiles[i] != nullptr; i++) {
SDL_RWops* file = SDL_RWFromFile(testFiles[i], "rb");
if (file) {
Sint64 size = SDL_RWsize(file);
__android_log_print(ANDROID_LOG_INFO, "Game", "Found: %s (size: %lld)", testFiles[i], size);
SDL_RWclose(file);
}
else {
__android_log_print(ANDROID_LOG_WARN, "Game", "Not found: %s (SDL error: %s)",
testFiles[i], SDL_GetError());
}
}
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
"Step 1xxxxxxx");
#endif
// Initialize renderer
#ifndef SIMPLIFIED
renderer.shaderManager.AddShaderFromFiles("defaultColor", "resources/shaders/defaultColor.vertex", "resources/shaders/defaultColor_web.fragment", CONST_ZIP_FILE);
@@ -178,37 +153,11 @@ namespace ZL
#else
renderer.shaderManager.AddShaderFromFiles("default", "resources/shaders/default.vertex", "resources/shaders/default_web.fragment", CONST_ZIP_FILE);
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
"Step 2xxxxxxx");
#endif
renderer.shaderManager.AddShaderFromFiles("env_sky", "resources/shaders/default_env.vertex", "resources/shaders/default_env_web.fragment", CONST_ZIP_FILE);
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
"Step 2");
#endif
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "resources/shaders/default_texture.vertex", "resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
"Step 3");
#endif
renderer.shaderManager.AddShaderFromFiles("planetBake", "resources/shaders/default_texture.vertex", "resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
"Step 4");
#endif
renderer.shaderManager.AddShaderFromFiles("planetStone", "resources/shaders/default_texture.vertex", "resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
"Step 5");
#endif
renderer.shaderManager.AddShaderFromFiles("planetLand", "resources/shaders/default_texture.vertex", "resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
"Step 1");
#endif
#endif
bool cfgLoaded = sparkEmitter.loadFromJsonFile("resources/config/spark_config.json", renderer, CONST_ZIP_FILE);
@@ -289,16 +238,17 @@ namespace ZL
});
uiManager.setSliderCallback("velocitySlider", [this](const std::string& name, float value) {
Environment::shipVelocity = value * 1000.f;
int newVel = roundf(value * 10);
if (newVel != Environment::shipSelectedVelocity) {
Environment::shipSelectedVelocity = newVel;
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now().time_since_epoch()
).count();
std::string msg = "VEL:" + std::to_string(now_ms) + ":" + std::to_string(Environment::shipSelectedVelocity);
networkClient->Send(msg);
}
});
/*uiManager.setSliderCallback("musicVolumeSlider", [this](const std::string& name, float value) {
std::cerr << "Music volume slider changed to: " << value << std::endl;
musicVolume = value;
Environment::shipVelocity = musicVolume * 20.0f;
});
//#endif*/
cubemapTexture = std::make_shared<Texture>(
std::array<TextureDataStruct, 6>{
CreateTextureDataFromPng("resources/sky/space1.png", CONST_ZIP_FILE),
@@ -330,10 +280,6 @@ namespace ZL
spaceshipBase.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY())).toRotationMatrix());// QuatFromRotateAroundY(M_PI / 2.0).toRotationMatrix());
spaceshipBase.Move(Vector3f{ 1.2, 0, -5 });
//spaceshipBase.Move(Vector3f{ -0.52998, -13, 0 });
//spaceshipBase.Move(Vector3f{ -0.52998, -10, 10 });
//spaceshipBase.Move(Vector3f{ -0.52998, 0, 10 });
spaceship.AssignFrom(spaceshipBase);
spaceship.RefreshVBO();
@@ -343,16 +289,8 @@ namespace ZL
boxTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/box/box.png", CONST_ZIP_FILE));
boxBase = LoadFromTextFile02("resources/box/box.txt", CONST_ZIP_FILE);
std::cout << "Init step 1 " << std::endl;
boxCoordsArr = generateRandomBoxCoords(50);
std::cout << "Init step 2 " << std::endl;
boxRenderArr.resize(boxCoordsArr.size());
std::cout << "Init step 3x " << std::endl;
for (int i = 0; i < boxCoordsArr.size(); i++)
{
boxRenderArr[i].AssignFrom(boxBase);
@@ -362,26 +300,17 @@ namespace ZL
boxAlive.resize(boxCoordsArr.size(), true);
std::cout << "Init step 4 " << std::endl;
if (!cfgLoaded)
{
throw std::runtime_error("Failed to load spark emitter config file!");
}
std::cout << "Init step 5 " << std::endl;
renderer.InitOpenGL();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
std::cout << "Init step 6 " << std::endl;
planetObject.init();
std::cout << "Init step 7 " << std::endl;
//rockTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", CONST_ZIP_FILE));
std::cout << "Init step 8 " << std::endl;
#ifdef NETWORK
networkClient = std::make_unique<WebSocketClient>(taskManager.getIOContext());
networkClient->Connect("127.0.0.1", 8080);
@@ -639,14 +568,182 @@ namespace ZL
sparkEmitter.update(static_cast<float>(delta));
planetObject.update(static_cast<float>(delta));
updateRemotePlayers(static_cast<float>(delta));
static float pingTimer = 0.0f;
pingTimer += delta;
if (pingTimer >= 1000.0f) {
networkClient->Send("PING");
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_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);
networkClient->Send(pingMsg);
pingTimer = 0.0f;
}
static const float CONST_ACCELERATION = 1.f;
float shipDesiredVelocity = Environment::shipSelectedVelocity * 100.f;
if (!gameOver)
{
if (Environment::shipVelocity < shipDesiredVelocity)
{
Environment::shipVelocity += delta * CONST_ACCELERATION;
if (Environment::shipVelocity > shipDesiredVelocity)
{
Environment::shipVelocity = shipDesiredVelocity;
}
}
else if (Environment::shipVelocity > shipDesiredVelocity)
{
Environment::shipVelocity -= delta * CONST_ACCELERATION;
if (Environment::shipVelocity < shipDesiredVelocity)
{
Environment::shipVelocity = shipDesiredVelocity;
}
}
}
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);
float rawMag = sqrtf(diffx * diffx + diffy * diffy);
float maxRadius = 200.0f; // Максимальный вынос джойстика
if (rawMag > 10.0f) { // Мертвая зона
// 1. Дискретизируем отклонение (0.0 - 1.0 с шагом 0.1)
float normalizedMag = min(rawMag / maxRadius, 1.0f);
float discreteMag = std::round(normalizedMag * 10.0f) / 10.0f;
// 2. Дискретизируем угол (0-359 градусов)
// atan2 возвращает радианы, переводим в градусы
float radians = atan2f(diffy, diffx);
int discreteAngle = static_cast<int>(radians * 180.0f / M_PI);
if (discreteAngle < 0) discreteAngle += 360;
// 3. Проверяем, изменились ли параметры значимо для отправки на сервер
if (discreteAngle != Environment::lastSentAngle || discreteMag != Environment::lastSentMagnitude) {
Environment::lastSentAngle = discreteAngle;
Environment::lastSentMagnitude = discreteMag;
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now().time_since_epoch()
).count();
// Формируем сетевой пакет
// Нам нужно отправить: дискретный угол, дискретную силу и текущую матрицу/позицию для синхронизации
std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(discreteAngle) + ":" + std::to_string(discreteMag);
networkClient->Send(msg);
}
// 4. Логика вращения (угловое ускорение)
// Теперь используем discreteAngle и discreteMag как "цель" для набора угловой скорости
// ... (код интерполяции скорости к этой цели)
// Вычисляем целевой вектор оси вращения из дискретного угла
// В 3D пространстве экранные X и Y преобразуются в оси вращения вокруг Y и X соответственно
float rad = static_cast<float>(discreteAngle) * static_cast<float>(M_PI) / 180.0f;
// Целевая угловая скорость (дискретная сила определяет модуль вектора)
// Вектор {cos, sin, 0} дает нам направление отклонения джойстика
Eigen::Vector3f targetAngularVelDir(sinf(rad), cosf(rad), 0.0f);
Eigen::Vector3f targetAngularVelocity = targetAngularVelDir * discreteMag;
Eigen::Vector3f diffVel = targetAngularVelocity - Environment::currentAngularVelocity;
float diffLen = diffVel.norm();
if (diffLen > 0.0001f) {
// Вычисляем, на сколько мы можем изменить скорость в этом кадре
float maxChange = ANGULAR_ACCEL * static_cast<float>(delta);
if (diffLen <= maxChange) {
// Если до цели осталось меньше, чем шаг ускорения — просто прыгаем в цель
Environment::currentAngularVelocity = targetAngularVelocity;
}
else {
// Линейно двигаемся в сторону целевого вектора
Environment::currentAngularVelocity += (diffVel / diffLen) * maxChange;
}
}
// Применяем вращение к матрице корабля
float speedScale = Environment::currentAngularVelocity.norm();
if (speedScale > 0.0001f) {
// Коэффициент чувствительности вращения
const float ROTATION_SENSITIVITY = 0.002f;
float deltaAlpha = speedScale * static_cast<float>(delta) * ROTATION_SENSITIVITY;
Eigen::Vector3f axis = Environment::currentAngularVelocity.normalized();
Eigen::Quaternionf rotateQuat(Eigen::AngleAxisf(deltaAlpha, axis));
Environment::shipMatrix = Environment::shipMatrix * rotateQuat.toRotationMatrix();
Environment::inverseShipMatrix = Environment::shipMatrix.inverse();
}
}
}
else {
// Если джойстик не зажат — сбрасываем дискретные значения и плавно замедляем вращение
Environment::lastSentAngle = -1;
Environment::lastSentMagnitude = 0.0f;
float currentSpeed = Environment::currentAngularVelocity.norm();
if (currentSpeed > 0.0001f) {
float drop = ANGULAR_ACCEL * static_cast<float>(delta);
if (currentSpeed <= drop) {
Environment::currentAngularVelocity = Eigen::Vector3f::Zero();
}
else {
// Уменьшаем модуль вектора, сохраняя направление
Environment::currentAngularVelocity -= (Environment::currentAngularVelocity / currentSpeed) * drop;
}
}
// Применяем остаточное вращение (инерция)
float speedScale = Environment::currentAngularVelocity.norm();
if (speedScale > 0.0001f) {
float deltaAlpha = speedScale * static_cast<float>(delta) * 0.002f;
Eigen::Quaternionf rotateQuat(Eigen::AngleAxisf(deltaAlpha, Environment::currentAngularVelocity.normalized()));
Environment::shipMatrix = Environment::shipMatrix * rotateQuat.toRotationMatrix();
Environment::inverseShipMatrix = Environment::shipMatrix.inverse();
}
}
// Движение вперед (существующая логика)
if (fabs(Environment::shipVelocity) > 0.01f)
{
Vector3f velocityDirection = { 0,0, -Environment::shipVelocity * delta / 1000.f };
Vector3f velocityDirectionAdjusted = Environment::shipMatrix * velocityDirection;
Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted;
}
/*
if (Environment::tapDownHold) {
float diffx = Environment::tapDownCurrentPos(0) - Environment::tapDownStartPos(0);
@@ -671,14 +768,7 @@ namespace ZL
Environment::inverseShipMatrix = Environment::shipMatrix.inverse();
}
}
if (fabs(Environment::shipVelocity) > 0.01f)
{
Vector3f velocityDirection = { 0,0, -Environment::shipVelocity * delta / 1000.f };
Vector3f velocityDirectionAdjusted = Environment::shipMatrix * velocityDirection;
Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted;
}
}*/
for (auto& p : projectiles) {
if (p && p->isActive()) {
@@ -896,21 +986,7 @@ namespace ZL
{
if (event.key.keysym.sym == SDLK_i)
{
Environment::shipVelocity += 500.f;
}
if (event.key.keysym.sym == SDLK_k)
{
Environment::shipVelocity -= 500.f;
}
if (event.key.keysym.sym == SDLK_o)
{
Environment::shipVelocity += 50.f;
//x = x + 2.0;
}
if (event.key.keysym.sym == SDLK_l)
{
Environment::shipVelocity -= 50.f;
//x = x - 2.0;
}
}*/
#endif
@@ -976,5 +1052,24 @@ namespace ZL
}
}
void Game::updateRemotePlayers(float deltaMs) {
latestRemotePlayers = networkClient->getRemotePlayers();
for (auto& [id, rp] : latestRemotePlayers) {
// Увеличиваем фактор интерполяции (базируется на частоте Snapshot = 1000мс)
rp.interpolationFactor += deltaMs / 1000.0f;
if (rp.interpolationFactor > 1.0f) rp.interpolationFactor = 1.0f;
// Линейная интерполяция позиции
rp.state.position = rp.startPosition + (rp.targetPosition - rp.startPosition) * rp.interpolationFactor;
// Сферическая интерполяция вращения (Slerp)
Eigen::Quaternionf currentQ = rp.startRotation.slerp(rp.interpolationFactor, rp.targetRotation);
rp.state.rotation = currentQ.toRotationMatrix();
}
}
} // namespace ZL