- 排行榜30秒自动刷新(进入页面已刷新,定时器仅home界面生效,刷新不闪屏) - boss榜不再统计累计击坠:改为Boss挑战(rush)击败过的不同Boss数/总数(11),按mode=rush+win=1去重stage;rush局stage记录Boss索引 - Boss挑战一命制:startRushGo强制lives=1/maxLives=1,掉落与拾取加命均以maxLives为上限,中途无法再加命 - 排行榜文案:Boss挑战tab/Boss列头
95 lines
4.0 KiB
JavaScript
95 lines
4.0 KiB
JavaScript
"use strict";
|
||
/* ================= 飞行员大厅(主页):排行榜 + 图鉴展柜背景 ================= */
|
||
let LB_SORT = "endless";
|
||
let LB_T = 0; // 排行榜自动刷新定时器
|
||
|
||
/* 排行榜 30 秒自动刷新(进入页面时 enterHome 已刷新一次) */
|
||
function lbAutoRefresh() {
|
||
if (LB_T) return;
|
||
LB_T = setInterval(() => { if (UI === "home") buildLeaderboard(LB_SORT); }, 30000);
|
||
}
|
||
|
||
/* 图鉴已收集数(只统计合法 key) */
|
||
function codexCount() {
|
||
let n = 0;
|
||
for (const k in SAVE.codex)
|
||
if (SAVE.codex[k] && (WEAPONS[k] || SUBS[k] || DRONES[k] || PASSIVES[k])) n++;
|
||
return n;
|
||
}
|
||
|
||
async function enterHome() {
|
||
G = null; // 触发主循环看门狗重建实战模拟背景
|
||
UI = "home";
|
||
show("o-home");
|
||
/* 刷新账号数据(stats/codex),再渲染面板与排行榜 */
|
||
const r = await NET.api("/api/me", "GET");
|
||
if (r.ok && r.data.user) NET._apply(r.data);
|
||
else if (r.ok) { NET.user = null; UI = "auth"; show("o-auth"); return; } // 会话失效
|
||
/* status===0 网络抖动:沿用现有数据,不踢出 */
|
||
buildHomeStats();
|
||
buildLeaderboard(LB_SORT);
|
||
lbAutoRefresh();
|
||
}
|
||
|
||
function buildHomeStats() {
|
||
const s = NET.stats || { bossKills: 0, endlessHigh: 0 };
|
||
const nm = NET.user ? NET.user.username : "--";
|
||
$("home-stats").textContent =
|
||
`${nm} · 击坠Boss ${s.bossKills} · 图鉴 ${codexCount()}/${NET.codexTotal} · 无尽最高 ${s.endlessHigh}`;
|
||
}
|
||
|
||
/* ---------- 排行榜 ---------- */
|
||
document.querySelectorAll(".lb-tabs button").forEach((b) => {
|
||
b.onclick = () => {
|
||
LB_SORT = b.dataset.s;
|
||
document.querySelectorAll(".lb-tabs button").forEach((x) => x.classList.toggle("on", x === b));
|
||
SFX.pick();
|
||
buildLeaderboard(LB_SORT);
|
||
};
|
||
});
|
||
|
||
async function buildLeaderboard(sort) {
|
||
const list = $("lb-list");
|
||
if (!list.children.length) list.innerHTML = '<div class="lb-empty">载入中...</div>'; // 首次/空态才显示载入,自动刷新不闪屏
|
||
const r = await NET.api("/api/leaderboard?sort=" + sort, "GET");
|
||
if (!r.ok) { list.innerHTML = '<div class="lb-empty">载入失败</div>'; return; }
|
||
const rows = r.data.rows || [];
|
||
list.innerHTML = "";
|
||
if (!rows.length) { list.innerHTML = '<div class="lb-empty">虚位以待</div>'; return; }
|
||
const meName = NET.user && NET.user.username;
|
||
const bossTotal = r.data.bossTotal || 11;
|
||
rows.forEach((row, i) => {
|
||
const d = document.createElement("div");
|
||
d.className = "lb-row" + (meName && row.username === meName ? " me" : "");
|
||
const bossCell = sort === "boss" ? row.bossKills + "/" + bossTotal : String(row.bossKills); // boss 榜显示“击败几个/总共几个”
|
||
const cells = [String(i + 1), row.username, bossCell, row.codexN + "/" + r.data.codexTotal, String(row.endlessHigh)];
|
||
for (const c of cells) {
|
||
const s = document.createElement("span");
|
||
s.textContent = c; // textContent 防注入
|
||
d.appendChild(s);
|
||
}
|
||
list.appendChild(d);
|
||
});
|
||
}
|
||
|
||
/* ---------- 大厅/基地背景:实战模拟 ----------
|
||
复用真实战斗引擎:随机 3主武Lv3 + 3副武Lv3 + 2僚机Lv2,自动驾驶,随机刷怪。
|
||
与图鉴演示同源(G.demoSim 真值→自动走位/无HUD/demoSpawn),G.homeSim 标记用于静音与渲染门控 */
|
||
function startHomeSim() {
|
||
newRun("stage", "falcon", 0);
|
||
const build = rollRushBuild(); // 与BOSS挑战同款随机武装
|
||
G.weapons = {}; build.m.forEach((k) => (G.weapons[k] = 3)); G.loadout = build.m.slice();
|
||
G.subs = {}; build.s.forEach((k) => (G.subs[k] = 3)); G.subLoadout = build.s.slice();
|
||
G.drones = {}; build.d.forEach((k) => (G.drones[k] = 2)); G.droneLoadout = build.d.slice();
|
||
G.xpNeed = 1e9; // 不升级打断
|
||
G.p.inv = 999999; // 背景模拟:玩家无伤
|
||
G.demoSim = { home: true };
|
||
G.homeSim = true;
|
||
}
|
||
|
||
/* ================= 视口自适应(手机/折叠屏/平板) =================
|
||
首次加载即适配当前屏幕;旋转/缩放时重新计算逻辑分辨率并铺满全屏 */
|
||
addEventListener("resize",fitViewport);
|
||
addEventListener("orientationchange",()=>setTimeout(fitViewport,250));
|
||
fitViewport();
|