Working on new scene

This commit is contained in:
Vladislav Khorev committed 2026-04-01 12:03:16 +03:00
1 parent beac06fd45
commit 5364b97235
16 files changed
+19356 -202

No files matched your search

+83 -174
View File
@@ -61,12 +61,9 @@ namespace ZL
#endif
Game::Game()
: /*window(nullptr)
, glContext(nullptr)
, */newTickCount(0)
: newTickCount(0)
, lastTickCount(0)
, menuManager(renderer)
, space(renderer, taskManager, mainThreadHandler, networkClient, menuManager)
{
}
@@ -79,9 +76,6 @@ namespace ZL
}
void Game::setup() {
//glContext = SDL_GL_CreateContext(ZL::Environment::window);
//glContext = in_glContext;
Environment::width = Environment::CONST_DEFAULT_WIDTH;
Environment::height = Environment::CONST_DEFAULT_HEIGHT;
Environment::computeProjectionDimensions();
@@ -95,12 +89,11 @@ namespace ZL
// so they are available immediately without waiting for resources.zip.
renderer.shaderManager.AddShaderFromFiles("defaultColor", "resources/shaders/defaultColor.vertex", "resources/shaders/defaultColor_web.fragment", "");
renderer.shaderManager.AddShaderFromFiles("default", "resources/shaders/default.vertex", "resources/shaders/default_web.fragment", "");
loadingTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/loading.png", ""));
#else
renderer.shaderManager.AddShaderFromFiles("defaultColor", "resources/shaders/defaultColor.vertex", "resources/shaders/defaultColor_desktop.fragment", CONST_ZIP_FILE);
renderer.shaderManager.AddShaderFromFiles("default", "resources/shaders/default.vertex", "resources/shaders/default_desktop.fragment", CONST_ZIP_FILE);
loadingTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/loading.png", CONST_ZIP_FILE));
#endif
loadingTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/loading.png", CONST_ZIP_FILE));
float minDimension;
float width = Environment::projectionWidth;
@@ -155,77 +148,34 @@ namespace ZL
renderer.shaderManager.AddShaderFromFiles("spark", "resources/shaders/spark.vertex", "resources/shaders/spark_desktop.fragment", CONST_ZIP_FILE);
#endif
menuManager.setupMenu();
roomTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/room005.png", CONST_ZIP_FILE));
roomMesh.data = LoadFromTextFile02("resources/w/room001.txt", CONST_ZIP_FILE);
roomMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI*0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
roomMesh.RefreshVBO();
menuManager.onMainMenuEntered = [this]() {
if (networkClient) {
networkClient->Disconnect();
networkClient.reset();
}
};
fireboxTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/Cube001.png", CONST_ZIP_FILE));
fireboxMesh.data = LoadFromTextFile02("resources/w/firebox.txt", CONST_ZIP_FILE);
fireboxMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
fireboxMesh.RefreshVBO();
menuManager.onSingleplayerPressed = [this](const std::string& nickname, int shipType) {
Environment::shipState.nickname = nickname;
Environment::shipState.shipType = shipType;
inaiTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/inai001.png", CONST_ZIP_FILE));
inaiMesh.data = LoadFromTextFile02("resources/w/inai001.txt", CONST_ZIP_FILE);
inaiMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
inaiMesh.data.Move({ 2.5, 1.4, -9.9 });
inaiMesh.RefreshVBO();
if (Environment::shipState.shipType == 1)
{
menuManager.uiManager.findButton("shootButton")->state = ButtonState::Disabled;
menuManager.uiManager.findButton("shootButton2")->state = ButtonState::Disabled;
}
else
{
menuManager.uiManager.findButton("shootButton")->state = ButtonState::Normal;
menuManager.uiManager.findButton("shootButton2")->state = ButtonState::Normal;
}
auto localClient = new LocalClient;
ClientState st = Environment::shipState;
st.id = localClient->GetClientId();
localClient->setLocalPlayerState(st);
networkClient = std::unique_ptr<INetworkClient>(localClient);
networkClient->Connect("", 0);
space.resetPlayerState();
lastTickCount = 0;
};
menuManager.onMultiplayerPressed = [this](const std::string& nickname, int shipType) {
Environment::shipState.nickname = nickname;
Environment::shipState.shipType = shipType;
#ifdef EMSCRIPTEN
networkClient = std::make_unique<WebSocketClientEmscripten>();
networkClient->Connect("localhost", 8081);
#else
networkClient = std::make_unique<WebSocketClient>(taskManager.getIOContext());
networkClient->Connect("localhost", 8081);
#endif
if (networkClient) {
std::string joinMsg = std::string("JOIN:") + nickname + ":" + std::to_string(shipType);
networkClient->Send(joinMsg);
std::cerr << "Sent JOIN: " << joinMsg << std::endl;
}
space.boxCoordsArr.clear();
space.boxRenderArr.clear();
space.boxAlive.clear();
space.serverBoxesApplied = false;
space.resetPlayerState();
connectingStartTicks = SDL_GetTicks();
lastTickCount = 0;
};
space.setup();
benchTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/bench001opt.png", CONST_ZIP_FILE));
benchMesh.data = LoadFromTextFile02("resources/w/bench002opt.txt", CONST_ZIP_FILE);
benchMesh.data.Scale(3.f);
benchMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY())).toRotationMatrix());
benchMesh.data.Move({ -2.1, 0.5, -7.9 });
benchMesh.RefreshVBO();
loadingCompleted = true;
}
void Game::drawUI()
{
glClear(GL_DEPTH_BUFFER_BIT);
@@ -239,13 +189,44 @@ namespace ZL
CheckGlError();
}
void Game::drawUnderMainMenu()
void Game::drawGame()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
}
renderer.shaderManager.PushShader(defaultShaderName);
renderer.RenderUniform1i(textureUniformName, 0);
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
renderer.PushMatrix();
renderer.LoadIdentity();
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
renderer.TranslateMatrix({ 0, -6.f, 0 }); //Ship camera offset
renderer.RotateMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI * 30 / 180.f, Eigen::Vector3f::UnitX())).toRotationMatrix());
glBindTexture(GL_TEXTURE_2D, roomTexture->getTexID());
renderer.DrawVertexRenderStruct(roomMesh);
glBindTexture(GL_TEXTURE_2D, fireboxTexture->getTexID());
renderer.DrawVertexRenderStruct(fireboxMesh);
glBindTexture(GL_TEXTURE_2D, inaiTexture->getTexID());
renderer.DrawVertexRenderStruct(inaiMesh);
glBindTexture(GL_TEXTURE_2D, benchTexture->getTexID());
renderer.DrawVertexRenderStruct(benchMesh);
renderer.PopMatrix();
renderer.PopProjectionMatrix();
renderer.shaderManager.PopShader();
}
void Game::drawScene() {
glViewport(0, 0, Environment::width, Environment::height);
if (!loadingCompleted) {
@@ -253,14 +234,7 @@ namespace ZL
}
else
{
if (menuManager.shouldRenderSpace()) {
space.drawScene();
}
else
{
drawUnderMainMenu();
}
drawGame();
drawUI();
}
CheckGlError();
@@ -293,18 +267,13 @@ namespace ZL
CheckGlError();
}
int64_t Game::getSyncTimeMs() {
int64_t localNow = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count();
if(networkClient)
{
return localNow + networkClient->getTimeOffset();
}
else
{
return localNow;
}
return localNow;
}
void Game::processTickCount() {
@@ -323,30 +292,19 @@ namespace ZL
if (newTickCount - lastTickCount > CONST_TIMER_INTERVAL) {
int64_t delta = newTickCount - lastTickCount;
if (delta > CONST_MAX_TIME_INTERVAL)
{
//throw std::runtime_error("Synchronization is lost");
}
if (menuManager.shouldRenderSpace()) {
space.processTickCount(newTickCount, delta);
}
menuManager.uiManager.update(static_cast<float>(delta));
lastTickCount = newTickCount;
}
}
void Game::render() {
//SDL_GL_MakeCurrent(ZL::Environment::window, glContext);
ZL::CheckGlError();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//processTickCount();
drawScene();
processTickCount();
//std::this_thread::sleep_for(std::chrono::milliseconds(50));
SDL_GL_SwapWindow(ZL::Environment::window);
}
@@ -364,10 +322,10 @@ namespace ZL
Environment::width = event.window.data1;
Environment::height = event.window.data2;
Environment::computeProjectionDimensions();
menuManager.uiManager.updateAllLayouts();
//menuManager.uiManager.updateAllLayouts();
std::cout << "Window resized: " << Environment::width << "x" << Environment::height << std::endl;
space.clearTextRendererCache();
//space.clearTextRendererCache();
}
#ifdef __ANDROID__
@@ -445,14 +403,14 @@ namespace ZL
// Обработка ввода текста
if (event.type == SDL_KEYDOWN) {
if (event.key.keysym.sym == SDLK_BACKSPACE) {
menuManager.uiManager.onKeyBackspace();
//menuManager.uiManager.onKeyBackspace();
}
}
if (event.type == SDL_TEXTINPUT) {
// Пропускаем ctrl+c и другие команды
if ((event.text.text[0] & 0x80) == 0) { // ASCII символы
menuManager.uiManager.onKeyPress((unsigned char)event.text.text[0]);
//menuManager.uiManager.onKeyPress((unsigned char)event.text.text[0]);
}
}
@@ -461,65 +419,30 @@ namespace ZL
std::cout << "Camera position: x=" << x << " y=" << y << " z=" << z << std::endl;
}
}
if (event.type == SDL_KEYUP) {
/*benchMesh.data.Move({-x, -y, 0});
if (event.key.keysym.sym == SDLK_a) {
x = x - 0.1;
}
if (event.key.keysym.sym == SDLK_d) {
x = x + 0.1;
}
if (event.key.keysym.sym == SDLK_w) {
y = y - 0.1;
}
if (event.key.keysym.sym == SDLK_s) {
y = y + 0.1;
}
benchMesh.data.Move({ x, y, 0 });
benchMesh.RefreshVBO();*/
}
#endif
}
render();
if (networkClient) {
//#ifndef NETWORK
auto localClient = dynamic_cast<ZL::LocalClient*>(networkClient.get());
if (localClient) {
localClient->setLocalPlayerState(Environment::shipState);
}
//#endif
networkClient->Poll();
if (menuManager.getState() == GameState::Connecting) {
if (networkClient->IsConnected()) {
menuManager.notifyConnected();
// Enable/disable shoot buttons based on ship type
if (Environment::shipState.shipType == 1) {
if (auto b = menuManager.uiManager.findButton("shootButton")) b->state = ButtonState::Disabled;
if (auto b = menuManager.uiManager.findButton("shootButton2")) b->state = ButtonState::Disabled;
} else {
if (auto b = menuManager.uiManager.findButton("shootButton")) b->state = ButtonState::Normal;
if (auto b = menuManager.uiManager.findButton("shootButton2")) b->state = ButtonState::Normal;
}
} else if (SDL_GetTicks() - connectingStartTicks > CONNECTING_TIMEOUT_MS) {
menuManager.notifyConnectionFailed();
}
}
#ifdef NETWORK
auto* wsBase = dynamic_cast<ZL::WebSocketClientBase*>(networkClient.get());
if (wsBase) {
auto spawns = wsBase->getPendingSpawns();
for (auto& st : spawns) {
if (st.id == wsBase->getClientId()) {
// применяем к локальному кораблю
ZL::Environment::shipState.position = st.position;
ZL::Environment::shipState.rotation = st.rotation;
// обнуляем движение чтобы не было рывков
ZL::Environment::shipState.currentAngularVelocity = Eigen::Vector3f::Zero();
ZL::Environment::shipState.velocity = 0.0f;
ZL::Environment::shipState.selectedVelocity = 0;
ZL::Environment::shipState.discreteMag = 0.0f;
ZL::Environment::shipState.discreteAngle = -1;
std::cout << "Game: Applied SPAWN at "
<< st.position.x() << ", "
<< st.position.y() << ", "
<< st.position.z() << std::endl;
}
}
}
#endif
}
mainThreadHandler.processMainThreadTasks();
if (menuManager.shouldRenderSpace()) {
space.update();
}
}
void Game::handleDown(int64_t fingerId, int mx, int my)
@@ -527,13 +450,9 @@ namespace ZL
int uiX = mx;
int uiY = Environment::projectionHeight - my;
menuManager.uiManager.onTouchDown(fingerId, uiX, uiY);
if (!menuManager.uiManager.isUiInteractionForFinger(fingerId)) {
if (menuManager.shouldRenderSpace()) {
space.handleDown(mx, my);
}
}
}
void Game::handleUp(int64_t fingerId, int mx, int my)
@@ -547,11 +466,6 @@ namespace ZL
bool wasUiInteraction = menuManager.uiManager.isUiInteractionForFinger(fingerId);
menuManager.uiManager.onTouchUp(fingerId, uiX, uiY);
if (!wasUiInteraction) {
if (menuManager.shouldRenderSpace()) {
space.handleUp(mx, my);
}
}
}
void Game::handleMotion(int64_t fingerId, int mx, int my)
@@ -564,11 +478,6 @@ namespace ZL
bool wasUiInteraction = menuManager.uiManager.isUiInteractionForFinger(fingerId);
menuManager.uiManager.onTouchMove(fingerId, uiX, uiY);
if (!wasUiInteraction) {
if (menuManager.shouldRenderSpace()) {
space.handleMotion(mx, my);
}
}
}
+15 -3
View File
@@ -37,19 +37,31 @@ namespace ZL {
Renderer renderer;
TaskManager taskManager;
MainThreadHandler mainThreadHandler;
std::unique_ptr<INetworkClient> networkClient;
//std::unique_ptr<INetworkClient> networkClient;
std::shared_ptr<Texture> loadingTexture;
VertexRenderStruct loadingMesh;
bool loadingCompleted = false;
std::shared_ptr<Texture> roomTexture;
VertexRenderStruct roomMesh;
std::shared_ptr<Texture> fireboxTexture;
VertexRenderStruct fireboxMesh;
std::shared_ptr<Texture> inaiTexture;
VertexRenderStruct inaiMesh;
std::shared_ptr<Texture> benchTexture;
VertexRenderStruct benchMesh;
private:
int64_t getSyncTimeMs();
void processTickCount();
void drawScene();
void drawUI();
void drawUnderMainMenu();
void drawGame();
void drawLoading();
void handleDown(int64_t fingerId, int mx, int my);
void handleUp(int64_t fingerId, int mx, int my);
@@ -73,7 +85,7 @@ namespace ZL {
static const size_t CONST_MAX_TIME_INTERVAL = 1000;
MenuManager menuManager;
Space space;
//Space space;
};
+3 -15
View File
@@ -15,6 +15,7 @@ namespace ZL {
{
}
/*
void MenuManager::setupMenu()
{
mainMenuRoot = loadUiFromFile("resources/config/main_menu.json", renderer, CONST_ZIP_FILE);
@@ -256,12 +257,7 @@ namespace ZL {
}
/*
auto velocityTv = uiManager.findTextView("velocityText");
if (velocityTv) {
velocityTv->rect.x = 10.0f;
velocityTv->rect.y = static_cast<float>(Environment::height) - velocityTv->rect.h - 10.0f;
}*/
uiManager.setButtonPressCallback("shootButton", [this](const std::string&) {
if (onFirePressed) onFirePressed();
@@ -317,14 +313,6 @@ namespace ZL {
});
/*
uiManager.setSliderCallback("velocitySlider", [this](const std::string&, float value) {
int newVel = static_cast<int>(roundf(value * 10));
if (newVel > 2) newVel = 2;
if (newVel != Environment::shipState.selectedVelocity) {
if (onVelocityChanged) onVelocityChanged(newVel);
}
});*/
}
// ── State: GameOver ──────────────────────────────────────────────────────
@@ -399,6 +387,6 @@ namespace ZL {
if (state == GameState::Gameplay) {
enterConnectionLost();
}
}
}*/
} // namespace ZL
+5 -4
View File
@@ -24,7 +24,7 @@ namespace ZL {
class MenuManager {
protected:
Renderer& renderer;
/*
// Pre-loaded UI roots (loaded once in setupMenu)
std::shared_ptr<UiNode> mainMenuRoot;
std::shared_ptr<UiNode> aboutMenuRoot;
@@ -53,14 +53,15 @@ namespace ZL {
void enterGameOver(int score);
void enterHelp();
void enterConnectionLost();
*/
public:
UiManager uiManager;
MenuManager(Renderer& iRenderer);
void setupMenu();
//void setupMenu();
/*
// Returns true for states where Space should render and run (Gameplay, GameOver, ConnectionLost)
bool shouldRenderSpace() const;
GameState getState() const { return state; }
@@ -81,7 +82,7 @@ namespace ZL {
std::function<void(const std::string&, int)> onMultiplayerPressed;
std::function<void()> onShowPlayersPressed;
std::function<void()> forceSetupSpaceUICallback;
std::function<void()> forceSetupSpaceUICallback;*/
};
} // namespace ZL
+6 -1
View File
@@ -265,7 +265,7 @@ namespace ZL
// Обновленные регулярки
// pattern_float стал чуть надежнее для чисел вида "0" или "-1" без точки, если вдруг Python округлит до int
static const std::regex pattern_count(R"(\d+)");
static const std::regex pattern_float(R"([-]?\d+(\.\d+)?)");
static const std::regex pattern_float(R"([-+]?\d*\.?\d+([eE][-+]?\d+)?)");
static const std::regex pattern_int(R"([-]?\d+)");
// --- 2. Парсинг Вершин (Pos + Norm + UV) ---
@@ -317,6 +317,11 @@ namespace ZL
throw std::runtime_error("Malformed vertex line at index " + std::to_string(i));
}
/*if (floatValues[2] > 1.f)
{
std::cout << "got" << std::endl;
}*/
tempPositions[i] = Vector3f{ floatValues[1], floatValues[2], floatValues[3] };
tempNormals[i] = Vector3f{ floatValues[4], floatValues[5], floatValues[6] };
tempUVs[i] = Vector2f{ floatValues[7], floatValues[8] };