Working on list of players
This commit is contained in:
1 parent
a8ded217df
commit
785b96ce82
10 files changed
+544
-13
No files matched your search
+182
-7
@@ -332,6 +332,10 @@ namespace ZL
|
||||
firePressed = true;
|
||||
};
|
||||
|
||||
menuManager.onShowPlayersPressed = [this]() {
|
||||
buildAndShowPlayerList();
|
||||
};
|
||||
|
||||
menuManager.onTakeButtonPressed = [this]() {
|
||||
if (Environment::shipState.shipType != 1) return;
|
||||
if (!networkClient) return;
|
||||
@@ -1001,6 +1005,16 @@ namespace ZL
|
||||
|
||||
int Space::pickTargetId() const
|
||||
{
|
||||
// Use manually selected target if it's still alive and in range
|
||||
if (manualTrackedTargetId >= 0) {
|
||||
auto it = remotePlayerStates.find(manualTrackedTargetId);
|
||||
if (it != remotePlayerStates.end() && !deadRemotePlayers.count(manualTrackedTargetId)) {
|
||||
float d2 = (Environment::shipState.position - it->second.position).squaredNorm();
|
||||
if (d2 <= TARGET_MAX_DIST_SQ) return manualTrackedTargetId;
|
||||
}
|
||||
// Target no longer valid — fall through to auto-pick
|
||||
}
|
||||
|
||||
int bestId = -1;
|
||||
float bestDistSq = 1e30f;
|
||||
|
||||
@@ -1008,8 +1022,8 @@ namespace ZL
|
||||
if (deadRemotePlayers.count(id)) continue;
|
||||
|
||||
float d2 = (Environment::shipState.position - st.position).squaredNorm();
|
||||
|
||||
if (d2 > TARGET_MAX_DIST_SQ) continue; // слишком далеко
|
||||
|
||||
if (d2 > TARGET_MAX_DIST_SQ) continue;
|
||||
|
||||
if (d2 < bestDistSq) {
|
||||
bestDistSq = d2;
|
||||
@@ -1728,6 +1742,7 @@ namespace ZL
|
||||
|
||||
std::cerr << "GAME OVER: collision with planet (moved back and exploded)\n";
|
||||
|
||||
clearPlayerListIfVisible();
|
||||
menuManager.showGameOver(this->playerScore);
|
||||
}
|
||||
else {
|
||||
@@ -1803,6 +1818,7 @@ namespace ZL
|
||||
planetObject.planetStones.statuses[collidedTriIdx] = ChunkStatus::Empty;
|
||||
}
|
||||
|
||||
clearPlayerListIfVisible();
|
||||
menuManager.showGameOver(this->playerScore);
|
||||
}
|
||||
}
|
||||
@@ -1885,6 +1901,7 @@ namespace ZL
|
||||
gameOver = true;
|
||||
Environment::shipState.velocity = 0.0f;
|
||||
std::cout << "Client: Lost connection to server\n";
|
||||
clearPlayerListIfVisible();
|
||||
menuManager.showConnectionLost();
|
||||
}
|
||||
|
||||
@@ -1923,6 +1940,7 @@ namespace ZL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Обработка событий смерти, присланных сервером
|
||||
auto deaths = networkClient->getPendingDeaths();
|
||||
if (!deaths.empty()) {
|
||||
@@ -1947,10 +1965,12 @@ namespace ZL
|
||||
shipAlive = false;
|
||||
gameOver = true;
|
||||
Environment::shipState.velocity = 0.0f;
|
||||
clearPlayerListIfVisible();
|
||||
menuManager.showGameOver(this->playerScore);
|
||||
}
|
||||
else {
|
||||
deadRemotePlayers.insert(d.targetId);
|
||||
if (d.targetId == manualTrackedTargetId) manualTrackedTargetId = -1;
|
||||
std::cout << "Marked remote player " << d.targetId << " as dead" << std::endl;
|
||||
}
|
||||
if (d.killerId == localId) {
|
||||
@@ -1959,6 +1979,7 @@ namespace ZL
|
||||
|
||||
}
|
||||
}
|
||||
rebuildPlayerListIfVisible();
|
||||
}
|
||||
|
||||
auto respawns = networkClient->getPendingRespawns();
|
||||
@@ -1976,6 +1997,7 @@ namespace ZL
|
||||
std::cout << "Client: Remote player " << respawnId << " respawned, removed from dead list" << std::endl;
|
||||
}
|
||||
}
|
||||
rebuildPlayerListIfVisible();
|
||||
|
||||
auto disconnects = networkClient->getPendingDisconnects();
|
||||
for (int pid : disconnects) {
|
||||
@@ -1986,9 +2008,11 @@ namespace ZL
|
||||
trackedTargetId = -1;
|
||||
targetAcquireAnim = 0.f;
|
||||
}
|
||||
if (pid == manualTrackedTargetId) manualTrackedTargetId = -1;
|
||||
std::cout << "Client: Remote player " << pid << " left the game, removed from scene\n";
|
||||
}
|
||||
|
||||
rebuildPlayerListIfVisible();
|
||||
auto boxDestructions = networkClient->getPendingBoxDestructions();
|
||||
if (!boxDestructions.empty()) {
|
||||
std::cout << "Game: Received " << boxDestructions.size() << " box destruction events" << std::endl;
|
||||
@@ -2051,13 +2075,15 @@ namespace ZL
|
||||
|
||||
void Space::handleDown(int mx, int my)
|
||||
{
|
||||
Environment::tapDownHold = true;
|
||||
if (playerListVisible) return;
|
||||
|
||||
Environment::tapDownStartPos(0) = mx;
|
||||
Environment::tapDownStartPos(1) = my;
|
||||
Environment::tapDownHold = true;
|
||||
|
||||
Environment::tapDownCurrentPos(0) = mx;
|
||||
Environment::tapDownCurrentPos(1) = my;
|
||||
Environment::tapDownStartPos(0) = mx;
|
||||
Environment::tapDownStartPos(1) = my;
|
||||
|
||||
Environment::tapDownCurrentPos(0) = mx;
|
||||
Environment::tapDownCurrentPos(1) = my;
|
||||
}
|
||||
|
||||
void Space::handleUp(int mx, int my)
|
||||
@@ -2068,6 +2094,8 @@ namespace ZL
|
||||
|
||||
void Space::handleMotion(int mx, int my)
|
||||
{
|
||||
if (playerListVisible) return;
|
||||
|
||||
if (Environment::tapDownHold) {
|
||||
Environment::tapDownCurrentPos(0) = mx;
|
||||
Environment::tapDownCurrentPos(1) = my;
|
||||
@@ -2105,4 +2133,151 @@ namespace ZL
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<UiNode> Space::buildPlayerListRoot()
|
||||
{
|
||||
const float btnW = 400;
|
||||
const float btnH = 50.0f;
|
||||
|
||||
// Collect alive remote players
|
||||
std::vector<std::pair<int, std::string>> players;
|
||||
for (auto& kv : remotePlayerStates) {
|
||||
if (!deadRemotePlayers.count(kv.first))
|
||||
players.push_back({ kv.first, kv.second.nickname });
|
||||
}
|
||||
|
||||
// Root: FrameLayout match_parent x match_parent
|
||||
auto root = std::make_shared<UiNode>();
|
||||
root->name = "playerListRoot";
|
||||
root->layoutType = LayoutType::Frame;
|
||||
root->width = -1.0f; // match_parent
|
||||
root->height = -1.0f;
|
||||
|
||||
// List container: LinearLayout vertical, centered
|
||||
float listH = btnH * (float)players.size();
|
||||
auto listNode = std::make_shared<UiNode>();
|
||||
listNode->name = "playerList";
|
||||
listNode->layoutType = LayoutType::Linear;
|
||||
listNode->orientation = Orientation::Vertical;
|
||||
listNode->width = btnW;
|
||||
listNode->height = listH;
|
||||
listNode->layoutSettings.hGravity = HorizontalGravity::Center;
|
||||
listNode->layoutSettings.vGravity = VerticalGravity::Center;
|
||||
|
||||
for (auto& [pid, nick] : players) {
|
||||
auto btnNode = std::make_shared<UiNode>();
|
||||
btnNode->name = "playerBtn_" + std::to_string(pid);
|
||||
btnNode->layoutType = LayoutType::Frame;
|
||||
btnNode->width = btnW;
|
||||
btnNode->height = btnH;
|
||||
|
||||
|
||||
auto tb = std::make_shared<UiTextButton>();
|
||||
tb->name = btnNode->name;
|
||||
tb->text = nick;
|
||||
tb->fontSize = 20;
|
||||
tb->color = { 1.f, 1.f, 1.f, 1.f };
|
||||
tb->textCentered = true;
|
||||
tb->textRenderer = std::make_unique<TextRenderer>();
|
||||
if (!tb->textRenderer->init(renderer, tb->fontPath, tb->fontSize, CONST_ZIP_FILE)) {
|
||||
std::cerr << "Failed to init TextRenderer for TextField: " << tb->name << std::endl;
|
||||
}
|
||||
//tb->texNormal = std::make_unique<Texture>(CreateTextureDataFromPng("resources/black.png", ""));
|
||||
|
||||
btnNode->textButton = tb;
|
||||
/*auto button = std::make_shared<UiButton>();
|
||||
button->name = "Hello";
|
||||
button->texNormal = std::make_unique<Texture>(CreateTextureDataFromPng("resources/loading.png", ""));
|
||||
btnNode->button = button;*/
|
||||
listNode->children.push_back(btnNode);
|
||||
}
|
||||
|
||||
// Backdrop: invisible full-screen TextButton — placed LAST so player buttons get priority
|
||||
auto backdropNode = std::make_shared<UiNode>();
|
||||
backdropNode->name = "playerListBackdrop";
|
||||
backdropNode->layoutType = LayoutType::Frame;
|
||||
backdropNode->width = -1.0f;
|
||||
backdropNode->height = -1.0f;
|
||||
auto backdropTb = std::make_shared<UiTextButton>();
|
||||
backdropTb->name = "playerListBackdrop";
|
||||
backdropNode->textButton = backdropTb;
|
||||
|
||||
|
||||
/*
|
||||
auto backgroundNode = std::make_shared<UiNode>();
|
||||
backgroundNode->name = "playerListBackground";
|
||||
backgroundNode->layoutType = LayoutType::Frame;
|
||||
backgroundNode->width = btnW;
|
||||
backgroundNode->height = listH;
|
||||
backgroundNode->layoutSettings.hGravity = HorizontalGravity::Center;
|
||||
backgroundNode->layoutSettings.vGravity = VerticalGravity::Center;
|
||||
auto backdropImage = std::make_shared<UiStaticImage>();
|
||||
backdropImage->name = "playerListBackgroundImage";
|
||||
backdropImage->texture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/blue_transparent.png", ""));
|
||||
backgroundNode->staticImage = backdropImage;
|
||||
*/
|
||||
root->children.push_back(listNode);
|
||||
root->children.push_back(backdropNode);
|
||||
//root->children.push_back(backgroundNode);
|
||||
return root;
|
||||
}
|
||||
|
||||
void Space::buildAndShowPlayerList()
|
||||
{
|
||||
auto listRoot = buildPlayerListRoot();
|
||||
menuManager.uiManager.pushMenuFromSavedRoot(listRoot);
|
||||
menuManager.uiManager.updateAllLayouts();
|
||||
playerListVisible = true;
|
||||
|
||||
for (auto& kv : remotePlayerStates) {
|
||||
if (deadRemotePlayers.count(kv.first)) continue;
|
||||
int pid = kv.first;
|
||||
std::string btnName = "playerBtn_" + std::to_string(pid);
|
||||
menuManager.uiManager.setTextButtonCallback(btnName, [this, pid](const std::string&) {
|
||||
manualTrackedTargetId = pid;
|
||||
closePlayerList();
|
||||
});
|
||||
}
|
||||
|
||||
menuManager.uiManager.setTextButtonCallback("playerListBackdrop", [this](const std::string&) {
|
||||
closePlayerList();
|
||||
});
|
||||
}
|
||||
|
||||
void Space::closePlayerList()
|
||||
{
|
||||
menuManager.uiManager.popMenu();
|
||||
menuManager.uiManager.updateAllLayouts();
|
||||
playerListVisible = false;
|
||||
}
|
||||
|
||||
void Space::rebuildPlayerListIfVisible()
|
||||
{
|
||||
if (!playerListVisible) return;
|
||||
|
||||
auto listRoot = buildPlayerListRoot();
|
||||
menuManager.uiManager.replaceRoot(listRoot);
|
||||
|
||||
for (auto& kv : remotePlayerStates) {
|
||||
if (deadRemotePlayers.count(kv.first)) continue;
|
||||
int pid = kv.first;
|
||||
std::string btnName = "playerBtn_" + std::to_string(pid);
|
||||
menuManager.uiManager.setTextButtonCallback(btnName, [this, pid](const std::string&) {
|
||||
manualTrackedTargetId = pid;
|
||||
closePlayerList();
|
||||
});
|
||||
}
|
||||
|
||||
menuManager.uiManager.setTextButtonCallback("playerListBackdrop", [this](const std::string&) {
|
||||
closePlayerList();
|
||||
});
|
||||
}
|
||||
|
||||
void Space::clearPlayerListIfVisible()
|
||||
{
|
||||
if (!playerListVisible) return;
|
||||
menuManager.uiManager.clearMenuStack();
|
||||
playerListVisible = false;
|
||||
}
|
||||
|
||||
} // namespace ZL
|
||||
Reference in new issue
Block a user