adjust label scale: constant far, smooth growth near
This commit is contained in:
commit
c8076b6018
18 files changed
+867
-325
No files matched your search
+196
-78
@@ -10,6 +10,7 @@
|
||||
#include <random>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
@@ -268,83 +269,119 @@ namespace ZL
|
||||
bool explosionCfgLoaded = explosionEmitter.loadFromJsonFile("resources/config/explosion_config.json", renderer, CONST_ZIP_FILE);
|
||||
explosionEmitter.setEmissionPoints(std::vector<Vector3f>());
|
||||
projectileEmitter.setEmissionPoints(std::vector<Vector3f>());
|
||||
uiManager.loadFromFile("resources/config/ui.json", renderer, CONST_ZIP_FILE);
|
||||
|
||||
uiManager.startAnimationOnNode("backgroundNode", "bgScroll");
|
||||
static bool isExitButtonAnimating = false;
|
||||
uiManager.setAnimationCallback("settingsButton", "buttonsExit", [this]() {
|
||||
std::cerr << "Settings button animation finished -> переход в настройки" << std::endl;
|
||||
if (uiManager.pushMenuFromFile("resources/config/settings.json", this->renderer, CONST_ZIP_FILE)) {
|
||||
uiManager.setButtonCallback("Opt1", [this](const std::string& n) {
|
||||
std::cerr << "Opt1 pressed: " << n << std::endl;
|
||||
});
|
||||
uiManager.setButtonCallback("Opt2", [this](const std::string& n) {
|
||||
std::cerr << "Opt2 pressed: " << n << std::endl;
|
||||
});
|
||||
uiManager.setButtonCallback("backButton", [this](const std::string& n) {
|
||||
uiManager.stopAllAnimations();
|
||||
uiManager.popMenu();
|
||||
});
|
||||
}
|
||||
else {
|
||||
std::cerr << "Failed to open settings menu after animations" << std::endl;
|
||||
}
|
||||
});
|
||||
uiManager.loadFromFile("resources/config/main_menu.json", renderer, CONST_ZIP_FILE);
|
||||
std::function<void()> loadGameplayUI;
|
||||
loadGameplayUI = [this]() {
|
||||
uiManager.loadFromFile("resources/config/ui.json", renderer, CONST_ZIP_FILE);
|
||||
|
||||
uiManager.setAnimationCallback("exitButton", "bgScroll", []() {
|
||||
std::cerr << "Exit button bgScroll animation finished" << std::endl;
|
||||
g_exitBgAnimating = false;
|
||||
});
|
||||
|
||||
// Set UI button callbacks
|
||||
uiManager.setButtonCallback("playButton", [this](const std::string& name) {
|
||||
std::cerr << "Play button pressed: " << name << std::endl;
|
||||
|
||||
});
|
||||
|
||||
uiManager.setButtonCallback("settingsButton", [this](const std::string& name) {
|
||||
std::cerr << "Settings button pressed: " << name << std::endl;
|
||||
uiManager.startAnimationOnNode("playButton", "buttonsExit");
|
||||
uiManager.startAnimationOnNode("settingsButton", "buttonsExit");
|
||||
uiManager.startAnimationOnNode("exitButton", "buttonsExit");
|
||||
});
|
||||
|
||||
uiManager.setButtonCallback("exitButton", [this](const std::string& name) {
|
||||
std::cerr << "Exit button pressed: " << name << std::endl;
|
||||
|
||||
if (!g_exitBgAnimating) {
|
||||
std::cerr << "start repeat anim bgScroll on exitButton" << std::endl;
|
||||
g_exitBgAnimating = true;
|
||||
uiManager.startAnimationOnNode("exitButton", "bgScroll");
|
||||
}
|
||||
else {
|
||||
std::cerr << "stop repeat anim bgScroll on exitButton" << std::endl;
|
||||
g_exitBgAnimating = false;
|
||||
uiManager.stopAnimationOnNode("exitButton", "bgScroll");
|
||||
|
||||
auto exitButton = uiManager.findButton("exitButton");
|
||||
if (exitButton) {
|
||||
exitButton->animOffsetX = 0.0f;
|
||||
exitButton->animOffsetY = 0.0f;
|
||||
exitButton->animScaleX = 1.0f;
|
||||
exitButton->animScaleY = 1.0f;
|
||||
exitButton->buildMesh();
|
||||
uiManager.startAnimationOnNode("backgroundNode", "bgScroll");
|
||||
static bool isExitButtonAnimating = false;
|
||||
uiManager.setAnimationCallback("settingsButton", "buttonsExit", [this]() {
|
||||
std::cerr << "Settings button animation finished -> переход в настройки" << std::endl;
|
||||
if (uiManager.pushMenuFromFile("resources/config/settings.json", this->renderer, CONST_ZIP_FILE)) {
|
||||
uiManager.setButtonCallback("Opt1", [this](const std::string& n) {
|
||||
std::cerr << "Opt1 pressed: " << n << std::endl;
|
||||
});
|
||||
uiManager.setButtonCallback("Opt2", [this](const std::string& n) {
|
||||
std::cerr << "Opt2 pressed: " << n << std::endl;
|
||||
});
|
||||
uiManager.setButtonCallback("backButton", [this](const std::string& n) {
|
||||
uiManager.stopAllAnimations();
|
||||
uiManager.popMenu();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
uiManager.setButtonCallback("shootButton", [this](const std::string& name) {
|
||||
uint64_t now = SDL_GetTicks64();
|
||||
if (now - lastProjectileFireTime >= static_cast<uint64_t>(projectileCooldownMs)) {
|
||||
lastProjectileFireTime = now;
|
||||
fireProjectiles();
|
||||
}
|
||||
});
|
||||
else {
|
||||
std::cerr << "Failed to open settings menu after animations" << std::endl;
|
||||
}
|
||||
});
|
||||
|
||||
uiManager.setSliderCallback("velocitySlider", [this](const std::string& name, float value) {
|
||||
int newVel = roundf(value * 10);
|
||||
if (newVel != Environment::shipState.selectedVelocity) {
|
||||
newShipVelocity = newVel;
|
||||
}
|
||||
uiManager.setAnimationCallback("exitButton", "bgScroll", []() {
|
||||
std::cerr << "Exit button bgScroll animation finished" << std::endl;
|
||||
g_exitBgAnimating = false;
|
||||
});
|
||||
|
||||
uiManager.setButtonCallback("playButton", [this](const std::string& name) {
|
||||
std::cerr << "Play button pressed: " << name << std::endl;
|
||||
});
|
||||
|
||||
uiManager.setButtonCallback("settingsButton", [this](const std::string& name) {
|
||||
std::cerr << "Settings button pressed: " << name << std::endl;
|
||||
uiManager.startAnimationOnNode("playButton", "buttonsExit");
|
||||
uiManager.startAnimationOnNode("settingsButton", "buttonsExit");
|
||||
uiManager.startAnimationOnNode("exitButton", "buttonsExit");
|
||||
});
|
||||
|
||||
uiManager.setButtonCallback("exitButton", [this](const std::string& name) {
|
||||
std::cerr << "Exit button pressed: " << name << std::endl;
|
||||
|
||||
if (!g_exitBgAnimating) {
|
||||
std::cerr << "start repeat anim bgScroll on exitButton" << std::endl;
|
||||
g_exitBgAnimating = true;
|
||||
uiManager.startAnimationOnNode("exitButton", "bgScroll");
|
||||
}
|
||||
else {
|
||||
std::cerr << "stop repeat anim bgScroll on exitButton" << std::endl;
|
||||
g_exitBgAnimating = false;
|
||||
uiManager.stopAnimationOnNode("exitButton", "bgScroll");
|
||||
|
||||
auto exitButton = uiManager.findButton("exitButton");
|
||||
if (exitButton) {
|
||||
exitButton->animOffsetX = 0.0f;
|
||||
exitButton->animOffsetY = 0.0f;
|
||||
exitButton->animScaleX = 1.0f;
|
||||
exitButton->animScaleY = 1.0f;
|
||||
exitButton->buildMesh();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
uiManager.setButtonCallback("shootButton", [this](const std::string& name) {
|
||||
uint64_t now = SDL_GetTicks64();
|
||||
if (now - lastProjectileFireTime >= static_cast<uint64_t>(projectileCooldownMs)) {
|
||||
lastProjectileFireTime = now;
|
||||
|
||||
this->fireProjectiles();
|
||||
|
||||
Eigen::Vector3f localForward = { 0, 0, -1 };
|
||||
Eigen::Vector3f worldForward = (Environment::shipState.rotation * localForward).normalized();
|
||||
|
||||
Eigen::Vector3f centerPos = Environment::shipState.position +
|
||||
Environment::shipState.rotation * Vector3f{ 0, 0.9f, 5.0f };
|
||||
|
||||
std::string fireMsg = "FIRE:" +
|
||||
std::to_string(now) + ":" +
|
||||
std::to_string(centerPos.x()) + ":" +
|
||||
std::to_string(centerPos.y()) + ":" +
|
||||
std::to_string(centerPos.z()) + ":" +
|
||||
std::to_string(worldForward.x()) + ":" +
|
||||
std::to_string(worldForward.y()) + ":" +
|
||||
std::to_string(worldForward.z()) + ":" +
|
||||
"2";
|
||||
|
||||
networkClient->Send(fireMsg);
|
||||
}
|
||||
});
|
||||
|
||||
uiManager.setSliderCallback("velocitySlider", [this](const std::string& name, float value) {
|
||||
int newVel = roundf(value * 10);
|
||||
if (newVel != Environment::shipState.selectedVelocity) {
|
||||
newShipVelocity = newVel;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
uiManager.setButtonCallback("singleButton", [loadGameplayUI](const std::string& name) {
|
||||
std::cerr << "Single button pressed: " << name << " -> load gameplay UI\n";
|
||||
loadGameplayUI();
|
||||
});
|
||||
uiManager.setButtonCallback("multiplayerButton", [loadGameplayUI](const std::string& name) {
|
||||
std::cerr << "Multiplayer button pressed: " << name << " -> load gameplay UI\n";
|
||||
loadGameplayUI();
|
||||
});
|
||||
uiManager.setButtonCallback("exitButton", [](const std::string& name) {
|
||||
std::cerr << "Exit from main menu pressed: " << name << " -> exiting\n";
|
||||
Environment::exitGameLoop = true;
|
||||
});
|
||||
|
||||
cubemapTexture = std::make_shared<Texture>(
|
||||
@@ -692,6 +729,27 @@ namespace ZL
|
||||
|
||||
latestRemotePlayers = networkClient->getRemotePlayers();
|
||||
|
||||
// Если сервер прислал коробки, применяем их однократно вместо локальной генерации
|
||||
if (!serverBoxesApplied && networkClient) {
|
||||
auto sboxes = networkClient->getServerBoxes();
|
||||
if (!sboxes.empty()) {
|
||||
boxCoordsArr.clear();
|
||||
for (auto& b : sboxes) {
|
||||
BoxCoords bc;
|
||||
bc.pos = b.first;
|
||||
bc.m = b.second;
|
||||
boxCoordsArr.push_back(bc);
|
||||
}
|
||||
boxRenderArr.resize(boxCoordsArr.size());
|
||||
for (int i = 0; i < (int)boxCoordsArr.size(); ++i) {
|
||||
boxRenderArr[i].AssignFrom(boxBase);
|
||||
boxRenderArr[i].RefreshVBO();
|
||||
}
|
||||
boxAlive.assign(boxCoordsArr.size(), true);
|
||||
serverBoxesApplied = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Итерируемся по актуальным данным из extrapolateRemotePlayers
|
||||
for (auto const& [id, remotePlayer] : latestRemotePlayers) {
|
||||
|
||||
@@ -701,7 +759,7 @@ namespace ZL
|
||||
}
|
||||
|
||||
ClientState playerState = remotePlayer.fetchClientStateAtTime(now);
|
||||
|
||||
|
||||
|
||||
renderer.PushMatrix();
|
||||
renderer.LoadIdentity();
|
||||
@@ -770,7 +828,16 @@ namespace ZL
|
||||
continue;
|
||||
|
||||
float uiX = sx, uiY = sy;
|
||||
float scale = std::clamp(BASE_SCALE / (dist * PERSPECTIVE_K + 1.f), MIN_SCALE, MAX_SCALE);
|
||||
//float scale = std::clamp(BASE_SCALE / (dist * PERSPECTIVE_K + 1.f), MIN_SCALE, MAX_SCALE);
|
||||
float scale;
|
||||
if (dist > CLOSE_DIST) {
|
||||
scale = 0.4f;
|
||||
}
|
||||
else {
|
||||
float t = 1.0f - (dist / CLOSE_DIST);
|
||||
scale = 0.4f + (MAX_SCALE - 0.4f) * t;
|
||||
}
|
||||
scale = std::clamp(scale, MIN_SCALE, MAX_SCALE);
|
||||
|
||||
// Дефолтный лейбл
|
||||
std::string label = "Player (" + std::to_string(st.id) + ") " + std::to_string((int)dist) + "m";
|
||||
@@ -854,7 +921,7 @@ namespace ZL
|
||||
float radians = atan2f(diffy, diffx);
|
||||
discreteAngle = static_cast<int>(radians * 180.0f / M_PI);
|
||||
if (discreteAngle < 0) discreteAngle += 360;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -868,7 +935,7 @@ namespace ZL
|
||||
discreteMag = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (discreteAngle != Environment::shipState.discreteAngle || discreteMag != Environment::shipState.discreteMag) {
|
||||
Environment::shipState.discreteAngle = discreteAngle;
|
||||
Environment::shipState.discreteMag = discreteMag;
|
||||
@@ -1247,7 +1314,7 @@ namespace ZL
|
||||
{
|
||||
if (event.key.keysym.sym == SDLK_i)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
@@ -1255,6 +1322,57 @@ namespace ZL
|
||||
render();
|
||||
mainThreadHandler.processMainThreadTasks();
|
||||
networkClient->Poll();
|
||||
|
||||
if (networkClient) {
|
||||
auto pending = networkClient->getPendingProjectiles();
|
||||
if (!pending.empty()) {
|
||||
const float projectileSpeed = 60.0f;
|
||||
const float lifeMs = 5000.0f;
|
||||
const float size = 0.5f;
|
||||
|
||||
auto remotePlayersSnapshot = networkClient->getRemotePlayers();
|
||||
for (const auto& pi : pending) {
|
||||
Eigen::Vector3f dir = pi.direction;
|
||||
float len = dir.norm();
|
||||
if (len <= 1e-6f) continue;
|
||||
dir /= len;
|
||||
|
||||
Eigen::Matrix3f shooterRot = Eigen::Matrix3f::Identity();
|
||||
float shooterVel = 0.0f;
|
||||
auto it = remotePlayersSnapshot.find(pi.shooterId);
|
||||
if (it != remotePlayersSnapshot.end()) {
|
||||
std::chrono::system_clock::time_point pktTime{ std::chrono::milliseconds(pi.clientTime) };
|
||||
if (it->second.canFetchClientStateAtTime(pktTime)) {
|
||||
ClientState shooterState = it->second.fetchClientStateAtTime(pktTime);
|
||||
shooterRot = shooterState.rotation;
|
||||
shooterVel = shooterState.velocity;
|
||||
}
|
||||
}
|
||||
|
||||
float speedWithOwner = projectileSpeed + shooterVel;
|
||||
Eigen::Vector3f baseVel = dir * speedWithOwner;
|
||||
|
||||
int shotCount = 2;
|
||||
|
||||
std::vector<Eigen::Vector3f> localOffsets = {
|
||||
{-1.5f, 0.9f, 5.0f},
|
||||
{ 1.5f, 0.9f, 5.0f}
|
||||
};
|
||||
|
||||
for (int i = 0; i < shotCount; ++i) {
|
||||
Eigen::Vector3f rotatedOffset = shooterRot * localOffsets[i];
|
||||
Eigen::Vector3f shotPos = pi.position + rotatedOffset;
|
||||
|
||||
for (auto& p : projectiles) {
|
||||
if (!p->isActive()) {
|
||||
p->init(shotPos, baseVel, lifeMs, size, projectileTexture, renderer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game::handleDown(int mx, int my)
|
||||
|
||||
Reference in new issue
Block a user