Working on server
This commit is contained in:
1 parent
ea26d6fb23
commit
1348efb5fe
13 files changed
+761
-193
No files matched your search
+201
-106
@@ -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
|
||||
Reference in new issue
Block a user