added choosing spaceship in singleplay

This commit is contained in:
Vlad 2026-02-24 20:34:01 +06:00
parent ad7294ceea
commit 5216965496
6 changed files with 140 additions and 26 deletions

View File

@ -0,0 +1,64 @@
{
"root": {
"name": "shipSelectionRoot",
"type": "node",
"children": [
{
"type": "TextField",
"name": "nicknameInput",
"x": 400,
"y": 150,
"width": 400,
"height": 50,
"placeholder": "Enter your nickname",
"fontPath": "resources/fonts/DroidSans.ttf",
"fontSize": 16,
"maxLength": 256,
"color": [122, 156, 198, 1],
"placeholderColor": [122, 156, 198, 1],
"backgroundColor": [15, 29, 51, 1],
"borderColor": [15, 29, 51, 1]
},
{
"type": "Button",
"name": "spaceshipButton",
"x": 300,
"y": 320,
"width": 200,
"height": 80,
"textures": {
"normal": "resources/multiplayer_menu/JoinServer.png",
"hover": "resources/multiplayer_menu/JoinServer.png",
"pressed": "resources/multiplayer_menu/JoinServer.png"
}
},
{
"type": "Button",
"name": "cargoshipButton",
"x": 700,
"y": 320,
"width": 200,
"height": 80,
"textures": {
"normal": "resources/multiplayer_menu/JoinServer.png",
"hover": "resources/multiplayer_menu/JoinServer.png",
"pressed": "resources/multiplayer_menu/JoinServer.png"
}
},
{
"type": "Button",
"name": "backButton",
"x": 449,
"y": 280,
"width": 382,
"height": 56,
"textures": {
"normal": "resources/multiplayer_menu/Backbutton.png",
"hover": "resources/multiplayer_menu/Backbutton.png",
"pressed": "resources/multiplayer_menu/Backbutton.png"
}
}
]
}
}

View File

@ -103,9 +103,22 @@ namespace ZL
menuManager.setupMenu(); menuManager.setupMenu();
menuManager.onSingleplayerPressed = [this]() { menuManager.onSingleplayerPressed = [this](const std::string& nickname, int shipType) {
Environment::shipState.nickname = nickname;
Environment::shipState.shipType = shipType;
networkClient = std::make_unique<LocalClient>(); networkClient = std::make_unique<LocalClient>();
networkClient->Connect("", 0); networkClient->Connect("", 0);
#ifndef NETWORK
auto localClient = dynamic_cast<ZL::LocalClient*>(networkClient.get());
if (localClient) {
ZL::ClientState st = Environment::shipState;
st.id = localClient->GetClientId();
localClient->setLocalPlayerState(st);
}
#endif
lastTickCount = 0;
spaceGameStarted = 1; spaceGameStarted = 1;
}; };

View File

@ -21,6 +21,7 @@ namespace ZL {
gameOverSavedRoot = loadUiFromFile("resources/config/game_over.json", renderer, CONST_ZIP_FILE); gameOverSavedRoot = loadUiFromFile("resources/config/game_over.json", renderer, CONST_ZIP_FILE);
auto shipSelectionRoot = loadUiFromFile("resources/config/ship_selection_menu.json", renderer, CONST_ZIP_FILE);
std::function<void()> loadGameplayUI; std::function<void()> loadGameplayUI;
loadGameplayUI = [this]() { loadGameplayUI = [this]() {
uiManager.replaceRoot(uiSavedRoot); uiManager.replaceRoot(uiSavedRoot);
@ -114,10 +115,38 @@ namespace ZL {
}); });
}; };
uiManager.setButtonCallback("singleButton", [loadGameplayUI, this](const std::string& name) { uiManager.setButtonCallback("singleButton", [this, shipSelectionRoot, loadGameplayUI](const std::string& name) {
std::cerr << "Single button pressed: " << name << " -> load gameplay UI\n"; std::cerr << "Single button pressed: " << name << " -> open ship selection UI\n";
loadGameplayUI(); if (!shipSelectionRoot) {
onSingleplayerPressed(); std::cerr << "Failed to load ship selection UI\n";
return;
}
if (uiManager.pushMenuFromSavedRoot(shipSelectionRoot)) {
uiManager.setButtonCallback("spaceshipButton", [this, loadGameplayUI](const std::string& btnName) {
std::string nick = uiManager.getTextFieldValue("nicknameInput");
if (nick.empty()) nick = "Player";
int shipType = 0;
uiManager.popMenu();
loadGameplayUI();
if (onSingleplayerPressed) onSingleplayerPressed(nick, shipType);
});
uiManager.setButtonCallback("cargoshipButton", [this, loadGameplayUI](const std::string& btnName) {
std::string nick = uiManager.getTextFieldValue("nicknameInput");
if (nick.empty()) nick = "Player";
int shipType = 1;
uiManager.popMenu();
loadGameplayUI();
if (onSingleplayerPressed) onSingleplayerPressed(nick, shipType);
});
uiManager.setButtonCallback("backButton", [this](const std::string& btnName) {
uiManager.popMenu();
});
}
else {
std::cerr << "Failed to push ship selection menu\n";
}
}); });
uiManager.setButtonCallback("multiplayerButton", [loadGameplayUI, this](const std::string& name) { uiManager.setButtonCallback("multiplayerButton", [loadGameplayUI, this](const std::string& name) {
std::cerr << "Multiplayer button pressed: " << name << " -> load gameplay UI\n"; std::cerr << "Multiplayer button pressed: " << name << " -> load gameplay UI\n";

View File

@ -34,7 +34,7 @@ namespace ZL {
std::function<void(float)> onVelocityChanged; std::function<void(float)> onVelocityChanged;
std::function<void()> onFirePressed; std::function<void()> onFirePressed;
std::function<void()> onSingleplayerPressed; std::function<void(const std::string&, int)> onSingleplayerPressed;
std::function<void()> onMultiplayerPressed; std::function<void()> onMultiplayerPressed;
}; };

View File

@ -454,8 +454,14 @@ namespace ZL
renderer.TranslateMatrix({ 0, -6.f, 0 }); //Ship camera offset renderer.TranslateMatrix({ 0, -6.f, 0 }); //Ship camera offset
if (shipAlive) { if (shipAlive) {
glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID()); if (Environment::shipState.shipType == 1 && cargoTexture) {
renderer.DrawVertexRenderStruct(spaceship); glBindTexture(GL_TEXTURE_2D, cargoTexture->getTexID());
renderer.DrawVertexRenderStruct(cargo);
}
else {
glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID());
renderer.DrawVertexRenderStruct(spaceship);
}
} }
renderer.PopMatrix(); renderer.PopMatrix();
glEnable(GL_BLEND); glEnable(GL_BLEND);

View File

@ -4,6 +4,7 @@
#define _USE_MATH_DEFINES #define _USE_MATH_DEFINES
#include <math.h> #include <math.h>
#include <iostream> #include <iostream>
#include <string>
using std::min; using std::min;
@ -29,36 +30,37 @@ constexpr long long CUTOFF_TIME = 5000; //ms
uint32_t fnv1a_hash(const std::string& data); uint32_t fnv1a_hash(const std::string& data);
struct ClientState { struct ClientState {
int id = 0; int id = 0;
Eigen::Vector3f position = { 0, 0, 45000.0f }; Eigen::Vector3f position = { 0, 0, 45000.0f };
Eigen::Matrix3f rotation = Eigen::Matrix3f::Identity(); Eigen::Matrix3f rotation = Eigen::Matrix3f::Identity();
Eigen::Vector3f currentAngularVelocity = Eigen::Vector3f::Zero(); Eigen::Vector3f currentAngularVelocity = Eigen::Vector3f::Zero();
float velocity = 0.0f; float velocity = 0.0f;
int selectedVelocity = 0; int selectedVelocity = 0;
float discreteMag = 0; float discreteMag = 0;
int discreteAngle = -1; int discreteAngle = -1;
int shipType = 0; std::string nickname = "Player";
// ??? ??????? ???? int shipType = 0;
std::chrono::system_clock::time_point lastUpdateServerTime; // ??? ??????? ????
std::chrono::system_clock::time_point lastUpdateServerTime;
void simulate_physics(size_t delta); void simulate_physics(size_t delta);
void apply_lag_compensation(std::chrono::system_clock::time_point nowTime); void apply_lag_compensation(std::chrono::system_clock::time_point nowTime);
void handle_full_sync(const std::vector<std::string>& parts, int startFrom); void handle_full_sync(const std::vector<std::string>& parts, int startFrom);
std::string formPingMessageContent(); std::string formPingMessageContent();
}; };
struct ClientStateInterval struct ClientStateInterval
{ {
std::vector<ClientState> timedStates; std::vector<ClientState> timedStates;
void add_state(const ClientState& state); void add_state(const ClientState& state);
bool canFetchClientStateAtTime(std::chrono::system_clock::time_point targetTime) const; bool canFetchClientStateAtTime(std::chrono::system_clock::time_point targetTime) const;
ClientState fetchClientStateAtTime(std::chrono::system_clock::time_point targetTime) const; ClientState fetchClientStateAtTime(std::chrono::system_clock::time_point targetTime) const;
}; };