Working on minor bug fixing

This commit is contained in:
Vladislav Khorev 2026-03-10 18:03:16 +03:00
parent 5e7c050c68
commit 18674efd8e
15 changed files with 90 additions and 24 deletions

View File

@ -68,7 +68,7 @@
color: #fff; color: #fff;
cursor: pointer; cursor: pointer;
} }
#nickSkip { margin-left: 8px; background: #666; }
</style> </style>
</head> </head>
<body> <body>
@ -165,6 +165,16 @@
loadGameScript(); loadGameScript();
} }
document.getElementById('fs-button').addEventListener('click', function() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(function(e) {
console.error('Fullscreen error: ' + e.message);
});
} else {
document.exitFullscreen();
}
});
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
// Готовим Module сразу — даже если откроется модалка, поле canvas будет доступно для скрипта (если он загружается позже) // Готовим Module сразу — даже если откроется модалка, поле canvas будет доступно для скрипта (если он загружается позже)
prepareModuleEnvironment(); prepareModuleEnvironment();
@ -183,14 +193,20 @@
// Show modal to request nickname before loading WASM // Show modal to request nickname before loading WASM
showNickOverlay(); showNickOverlay();
var submit = document.getElementById('nickSubmit'); var submit = document.getElementById('nickSubmit');
var skip = document.getElementById('nickSkip');
var input = document.getElementById('nickInput'); var input = document.getElementById('nickInput');
submit.addEventListener('click', function() { submit.addEventListener('click', function() {
saveNickAndStart(input.value); saveNickAndStart(input.value);
}); });
skip.addEventListener('click', function() {
saveNickAndStart('Player'); input.addEventListener('input', function() {
// Strip any character that is not a-z, A-Z, 0-9 or space
var pos = this.selectionStart;
var cleaned = this.value.replace(/[^a-zA-Z0-9 ]/g, '');
if (cleaned !== this.value) {
this.value = cleaned;
this.setSelectionRange(pos - 1, pos - 1);
}
}); });
input.addEventListener('keydown', function(e) { input.addEventListener('keydown', function(e) {

BIN
resources/button_players_disabled.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -27,9 +27,9 @@
"horizontal_gravity": "center", "horizontal_gravity": "center",
"vertical_gravity": "center", "vertical_gravity": "center",
"textures": { "textures": {
"normal": "resources/game_over/Filledbuttons.png", "normal": "resources/game_over/reconnect1.png",
"hover": "resources/game_over/Variant5.png", "hover": "resources/game_over/reconnect2.png",
"pressed": "resources/game_over/Variant6.png" "pressed": "resources/game_over/reconnect3.png"
} }
}, },
{ {

View File

@ -27,9 +27,9 @@
"horizontal_gravity": "center", "horizontal_gravity": "center",
"vertical_gravity": "center", "vertical_gravity": "center",
"textures": { "textures": {
"normal": "resources/game_over/Filledbuttons.png", "normal": "resources/game_over/reconnect1.png",
"hover": "resources/game_over/Variant5.png", "hover": "resources/game_over/reconnect2.png",
"pressed": "resources/game_over/Variant6.png" "pressed": "resources/game_over/reconnect3.png"
} }
}, },
{ {

View File

@ -38,7 +38,7 @@
"normal": "resources/button_players.png", "normal": "resources/button_players.png",
"hover": "resources/button_players.png", "hover": "resources/button_players.png",
"pressed": "resources/button_players.png", "pressed": "resources/button_players.png",
"disabled": "resources/button_players.png" "disabled": "resources/button_players_disabled.png"
} }
}, },
{ {

BIN
resources/game_over/Variant6.png (Stored with Git LFS)

Binary file not shown.

BIN
resources/game_over/reconnect1.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/game_over/reconnect2.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/game_over/reconnect3.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/player_under.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/players_list_title.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -289,7 +289,8 @@ namespace ZL {
uiManager.replaceRoot(connectionLostRoot); uiManager.replaceRoot(connectionLostRoot);
uiManager.setButtonCallback("reconnectButton", [this](const std::string&) { uiManager.setButtonCallback("reconnectButton", [this](const std::string&) {
// TODO: reconnect logic enterConnecting();
if (onMultiplayerPressed) onMultiplayerPressed(pendingMultiNick, pendingMultiShipType);
}); });
uiManager.setButtonCallback("exitServerButton", [this](const std::string&) { uiManager.setButtonCallback("exitServerButton", [this](const std::string&) {
enterMainMenu(); enterMainMenu();

View File

@ -1796,7 +1796,9 @@ namespace ZL
shipAlive = false; shipAlive = false;
gameOver = true; gameOver = true;
Environment::shipState.selectedVelocity = 0;
Environment::shipState.velocity = 0.0f; Environment::shipState.velocity = 0.0f;
newShipVelocity = 0;
showExplosion = true; showExplosion = true;
explosionEmitter.setUseWorldSpace(true); explosionEmitter.setUseWorldSpace(true);
@ -2160,8 +2162,8 @@ namespace ZL
std::shared_ptr<UiNode> Space::buildPlayerListRoot() std::shared_ptr<UiNode> Space::buildPlayerListRoot()
{ {
const float btnW = 400; const float btnW = 250;
const float btnH = 50.0f; const float btnH = 40.0f;
// Collect alive remote players // Collect alive remote players
std::vector<std::pair<int, std::string>> players; std::vector<std::pair<int, std::string>> players;
@ -2178,7 +2180,7 @@ namespace ZL
root->height = -1.0f; root->height = -1.0f;
// List container: LinearLayout vertical, centered // List container: LinearLayout vertical, centered
float listH = btnH * (float)players.size(); float listH = btnH * (float)(players.size()+1);
auto listNode = std::make_shared<UiNode>(); auto listNode = std::make_shared<UiNode>();
listNode->name = "playerList"; listNode->name = "playerList";
listNode->layoutType = LayoutType::Linear; listNode->layoutType = LayoutType::Linear;
@ -2188,6 +2190,20 @@ namespace ZL
listNode->layoutSettings.hGravity = HorizontalGravity::Center; listNode->layoutSettings.hGravity = HorizontalGravity::Center;
listNode->layoutSettings.vGravity = VerticalGravity::Center; listNode->layoutSettings.vGravity = VerticalGravity::Center;
auto titleNode = std::make_shared<UiNode>();
titleNode->name = "player_list_title";
titleNode->layoutType = LayoutType::Frame;
titleNode->width = btnW;
titleNode->height = btnH;
auto titleImage = std::make_shared<UiButton>();
titleImage->name = "player_list_title";
titleImage->texNormal = std::make_unique<Texture>(CreateTextureDataFromPng("resources/players_list_title.png", ""));
titleImage->texPressed = titleImage->texNormal;
titleImage->texHover = titleImage->texNormal;
titleNode->button = titleImage;
listNode->children.push_back(titleNode);
for (auto& [pid, nick] : players) { for (auto& [pid, nick] : players) {
auto btnNode = std::make_shared<UiNode>(); auto btnNode = std::make_shared<UiNode>();
btnNode->name = "playerBtn_" + std::to_string(pid); btnNode->name = "playerBtn_" + std::to_string(pid);
@ -2206,7 +2222,7 @@ namespace ZL
if (!tb->textRenderer->init(renderer, tb->fontPath, tb->fontSize, CONST_ZIP_FILE)) { if (!tb->textRenderer->init(renderer, tb->fontPath, tb->fontSize, CONST_ZIP_FILE)) {
std::cerr << "Failed to init TextRenderer for TextField: " << tb->name << std::endl; std::cerr << "Failed to init TextRenderer for TextField: " << tb->name << std::endl;
} }
//tb->texNormal = std::make_unique<Texture>(CreateTextureDataFromPng("resources/black.png", "")); tb->texNormal = std::make_unique<Texture>(CreateTextureDataFromPng("resources/player_under.png", CONST_ZIP_FILE));
btnNode->textButton = tb; btnNode->textButton = tb;
/*auto button = std::make_shared<UiButton>(); /*auto button = std::make_shared<UiButton>();
@ -2266,6 +2282,9 @@ namespace ZL
menuManager.uiManager.setTextButtonCallback("playerListBackdrop", [this](const std::string&) { menuManager.uiManager.setTextButtonCallback("playerListBackdrop", [this](const std::string&) {
closePlayerList(); closePlayerList();
}); });
menuManager.uiManager.setTextButtonCallback("player_list_title", [this](const std::string&) {
closePlayerList();
});
} }
void Space::closePlayerList() void Space::closePlayerList()

View File

@ -103,10 +103,7 @@ namespace ZL {
} }
void UiTextButton::draw(Renderer& renderer) const { void UiTextButton::draw(Renderer& renderer) const {
renderer.PushMatrix();
renderer.TranslateMatrix({ animOffsetX, animOffsetY, 0.0f });
renderer.ScaleMatrix({ animScaleX, animScaleY, 1.0f });
// Draw background texture (optional) // Draw background texture (optional)
const std::shared_ptr<Texture>* tex = nullptr; const std::shared_ptr<Texture>* tex = nullptr;
switch (state) { switch (state) {
@ -115,20 +112,30 @@ namespace ZL {
case ButtonState::Pressed: tex = texPressed ? &texPressed : (texNormal ? &texNormal : nullptr); break; case ButtonState::Pressed: tex = texPressed ? &texPressed : (texNormal ? &texNormal : nullptr); break;
case ButtonState::Disabled: tex = texDisabled ? &texDisabled : (texNormal ? &texNormal : nullptr); break; case ButtonState::Disabled: tex = texDisabled ? &texDisabled : (texNormal ? &texNormal : nullptr); break;
} }
glDisable(GL_DEPTH_TEST);
if (tex && *tex) { if (tex && *tex) {
renderer.shaderManager.PushShader(defaultShaderName);
renderer.PushMatrix();
renderer.TranslateMatrix({ animOffsetX, animOffsetY, 0.0f });
renderer.ScaleMatrix({ animScaleX, animScaleY, 1.0f });
renderer.RenderUniform1i(textureUniformName, 0); renderer.RenderUniform1i(textureUniformName, 0);
glBindTexture(GL_TEXTURE_2D, (*tex)->getTexID()); glBindTexture(GL_TEXTURE_2D, (*tex)->getTexID());
renderer.DrawVertexRenderStruct(mesh); renderer.DrawVertexRenderStruct(mesh);
renderer.PopMatrix();
renderer.shaderManager.PopShader();
} }
renderer.PopMatrix();
// Draw text on top (uses absolute coords, add anim offset manually) // Draw text on top (uses absolute coords, add anim offset manually)
if (textRenderer && !text.empty()) { if (textRenderer && !text.empty()) {
float cx = rect.x + rect.w / 2.0f + animOffsetX; float cx = rect.x + rect.w / 2.0f + animOffsetX;
float cy = rect.y + rect.h / 2.0f + animOffsetY; float cy = rect.y + rect.h / 2.0f + animOffsetY;
textRenderer->drawText(text, cx, cy, 1.0f, textCentered, color); textRenderer->drawText(text, cx, cy, 1.0f, textCentered, color);
} }
glEnable(GL_DEPTH_TEST);
} }
void UiSlider::buildTrackMesh() { void UiSlider::buildTrackMesh() {

View File

@ -361,6 +361,8 @@ void TextRenderer::drawText(const std::string& text, float x, float y, float sca
// 4. Рендеринг // 4. Рендеринг
r->shaderManager.PushShader(shaderName); r->shaderManager.PushShader(shaderName);
//r->PushMatrix();
//r->LoadIdentity();
// Матрица проекции — используем виртуальные проекционные размеры, // Матрица проекции — используем виртуальные проекционные размеры,
// чтобы координаты текста были независимы от физического разрешения экрана. // чтобы координаты текста были независимы от физического разрешения экрана.
@ -373,6 +375,8 @@ void TextRenderer::drawText(const std::string& text, float x, float y, float sca
proj(0, 3) = -1.0f + 2.0f * (tx) / W; proj(0, 3) = -1.0f + 2.0f * (tx) / W;
proj(1, 3) = -1.0f + 2.0f * (ty) / H; proj(1, 3) = -1.0f + 2.0f * (ty) / H;
//cached.mesh.RefreshVBO();
r->RenderUniformMatrix4fv("uProjection", false, proj.data()); r->RenderUniformMatrix4fv("uProjection", false, proj.data());
r->RenderUniform1i("uText", 0); r->RenderUniform1i("uText", 0);
r->RenderUniform4fv("uColor", color.data()); r->RenderUniform4fv("uColor", color.data());
@ -397,6 +401,7 @@ void TextRenderer::drawText(const std::string& text, float x, float y, float sca
// glDrawArrays(GL_TRIANGLES, 0, 6); // glDrawArrays(GL_TRIANGLES, 0, 6);
//} //}
r->DrawVertexRenderStruct(cached.mesh); r->DrawVertexRenderStruct(cached.mesh);
//r->PopMatrix();
r->shaderManager.PopShader(); r->shaderManager.PopShader();
// Сброс бинда текстуры не обязателен, но можно для чистоты // Сброс бинда текстуры не обязателен, но можно для чистоты