3d8566bc-063f-41e8-8934-68c9ac5b8211
This commit is contained in:
+30
-7
@@ -10,7 +10,10 @@ import { Codex } from "@/components/game/Codex";
|
||||
import { PrestigeDialog } from "@/components/game/PrestigeDialog";
|
||||
import { SettingsDialog } from "@/components/game/SettingsDialog";
|
||||
import { ExpeditionPanel } from "@/components/game/ExpeditionPanel";
|
||||
import { AchievementsPanel } from "@/components/game/AchievementsPanel";
|
||||
import { AchievementNotifier } from "@/components/game/AchievementNotifier";
|
||||
import { useGameLoop } from "@/hooks/useGameLoop";
|
||||
import { useAudioSync } from "@/hooks/useAudio";
|
||||
import { useGameStore } from "@/store/gameStore";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -23,11 +26,14 @@ import {
|
||||
BarChart3,
|
||||
Rocket,
|
||||
Github,
|
||||
Trophy,
|
||||
} from "lucide-react";
|
||||
import { TECH_TREE, FRAGMENTS, formatNum } from "@/lib/game/config";
|
||||
import { ACHIEVEMENTS } from "@/lib/game/achievements";
|
||||
|
||||
export default function Page() {
|
||||
useGameLoop();
|
||||
useAudioSync();
|
||||
const [prestigeOpen, setPrestigeOpen] = useState(false);
|
||||
const [settingsOpen, setSettingsOpen] = useState(false);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
@@ -38,6 +44,7 @@ export default function Page() {
|
||||
const ascensions = useGameStore((s) => s.ascensions);
|
||||
const ownedTech = useGameStore((s) => s.tech);
|
||||
const ownedFragments = useGameStore((s) => s.fragments);
|
||||
const ownedAchievements = useGameStore((s) => s.achievements);
|
||||
const crystals = useGameStore((s) => s.crystals);
|
||||
const crystalCap = useGameStore((s) => s.crystalCap);
|
||||
const energy = useGameStore((s) => s.energy);
|
||||
@@ -60,6 +67,7 @@ export default function Page() {
|
||||
|
||||
const ownedTechCount = Object.values(ownedTech).filter((v) => v > 0).length;
|
||||
const ownedFragCount = Object.values(ownedFragments).filter(Boolean).length;
|
||||
const ownedAchCount = Object.values(ownedAchievements).filter(Boolean).length;
|
||||
const canPrestige = contact >= 100;
|
||||
|
||||
// 仓库满仓警告
|
||||
@@ -100,7 +108,7 @@ export default function Page() {
|
||||
<div className="leading-tight">
|
||||
<h1 className="text-base sm:text-lg font-bold text-gradient">回响星核</h1>
|
||||
<p className="text-[9px] sm:text-[10px] text-muted-foreground/70 -mt-0.5 tracking-wider">
|
||||
ECHO NEXUS · v0.1
|
||||
ECHO NEXUS · v0.2.1
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -147,11 +155,11 @@ export default function Page() {
|
||||
<div className="glass rounded-2xl p-4 flex-1 min-h-[360px] max-h-[560px]">
|
||||
<DecodePanel />
|
||||
</div>
|
||||
{/* 标签面板:探险 / 技术 / 图谱 / 统计 */}
|
||||
{/* 标签面板:探险 / 技术 / 图谱 / 成就 / 统计 */}
|
||||
<div className="glass rounded-2xl p-3 min-h-[320px] max-h-[440px]">
|
||||
<Tabs defaultValue={hasActiveExpedition ? "expedition" : "tech"} className="h-full flex flex-col">
|
||||
<TabsList className="grid grid-cols-4 h-8 bg-black/30">
|
||||
<TabsTrigger value="expedition" className="text-xs gap-1 relative">
|
||||
<TabsList className="grid grid-cols-5 h-8 bg-black/30">
|
||||
<TabsTrigger value="expedition" className="text-[11px] gap-0.5 relative px-1">
|
||||
<Rocket className="h-3 w-3" />
|
||||
探险
|
||||
{energy >= 1 && !hasActiveExpedition && (
|
||||
@@ -161,15 +169,22 @@ export default function Page() {
|
||||
<span className="absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-rose-400 animate-pulse" />
|
||||
)}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="tech" className="text-xs gap-1">
|
||||
<TabsTrigger value="tech" className="text-[11px] gap-0.5 px-1">
|
||||
<Cpu className="h-3 w-3" />
|
||||
技术
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="codex" className="text-xs gap-1">
|
||||
<TabsTrigger value="codex" className="text-[11px] gap-0.5 px-1">
|
||||
<BookOpen className="h-3 w-3" />
|
||||
图谱
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="stats" className="text-xs gap-1">
|
||||
<TabsTrigger value="ach" className="text-[11px] gap-0.5 relative px-1">
|
||||
<Trophy className="h-3 w-3" />
|
||||
成就
|
||||
{ownedAchCount < ACHIEVEMENTS.length && (
|
||||
<span className="absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-amber-400 animate-pulse" />
|
||||
)}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="stats" className="text-[11px] gap-0.5 px-1">
|
||||
<BarChart3 className="h-3 w-3" />
|
||||
统计
|
||||
</TabsTrigger>
|
||||
@@ -183,6 +198,9 @@ export default function Page() {
|
||||
<TabsContent value="codex" className="flex-1 mt-2 min-h-0 data-[state=active]:flex data-[state=active]:flex-col">
|
||||
<Codex />
|
||||
</TabsContent>
|
||||
<TabsContent value="ach" className="flex-1 mt-2 min-h-0 data-[state=active]:flex data-[state=active]:flex-col">
|
||||
<AchievementsPanel />
|
||||
</TabsContent>
|
||||
<TabsContent value="stats" className="flex-1 mt-2 min-h-0">
|
||||
<StatsPanel />
|
||||
</TabsContent>
|
||||
@@ -215,22 +233,27 @@ export default function Page() {
|
||||
|
||||
<PrestigeDialog open={prestigeOpen} onOpenChange={setPrestigeOpen} />
|
||||
<SettingsDialog open={settingsOpen} onOpenChange={setSettingsOpen} />
|
||||
<AchievementNotifier />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function StatsPanel() {
|
||||
const s = useGameStore();
|
||||
const achCount = Object.values(s.achievements).filter(Boolean).length;
|
||||
const rows = [
|
||||
{ label: "累计解码晶体", value: `${s.totalDecoded} 颗` },
|
||||
{ label: "飞升周目", value: `${s.ascensions}` },
|
||||
{ label: "持有蓝图", value: `${s.blueprints.length} / 6` },
|
||||
{ label: "已学技术", value: `${Object.values(s.tech).filter((v) => v > 0).length} / ${TECH_TREE.length}` },
|
||||
{ label: "已获碎片", value: `${Object.values(s.fragments).filter(Boolean).length} / ${FRAGMENTS.length}` },
|
||||
{ label: "已解锁成就", value: `${achCount} / ${ACHIEVEMENTS.length}` },
|
||||
{ label: "接触进度", value: `${s.contact.toFixed(1)}%` },
|
||||
{ label: "晶体产能", value: `${s.crystalsPerSec.toFixed(2)} /s` },
|
||||
{ label: "仓库上限", value: `${formatNum(s.crystalCap)}` },
|
||||
{ label: "洞见倍率", value: `×${s.insightMult.toFixed(2)}` },
|
||||
{ label: "累计探险", value: `${s.totalExpeditions} 次` },
|
||||
{ label: "探险能量", value: `${Math.floor(s.energy)} / ${s.energyMax}` },
|
||||
];
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-1.5 text-xs">
|
||||
|
||||
Reference in New Issue
Block a user