v0.6: 深空巡航 Canvas 2D 实时玩法 + UI 偏移重叠修复

## 玩法拓展(回应用户: 玩法太单调/全是点点点)
- 新增「深空巡航」Canvas 2D 全屏实时玩法
  - 飞船操控(WASD/方向键/移动端虚拟摇杆)
  - 实时躲避陨石/虚空风暴,收集晶体/洞见/信标
  - 到达星门通关,护盾归零失败
  - 3层视差星空 + 粒子系统(尾焰/收集/碰撞/烟花) + 辉光 + 屏幕震动
  - 奖励同步主游戏(grantCruiseReward)
  - 独立 localStorage 记录最高分/通关数

## UI 修复(回应用户: 解析球左上偏移/成就小屏重叠)
- DecodeArray 节点: 移除 Tailwind translate 与 inline transform 冲突
- AchievementsPanel: 移除固定 max-h, 改 flex-1 min-h-0 自适应
- page.tsx 布局: 小屏减小 min-h, 避免挤压重叠

## 集成
- gameStore 新增 grantCruiseReward action
- header 新增 amber 主题「巡航」按钮 + 全屏 CruiseMode 渲染

## 文件
- src/lib/game/cruise.ts (新增, ~1008行)
- src/components/game/CruiseMode.tsx (新增, ~1350行)
- src/app/page.tsx (集成巡航入口)
- src/store/gameStore.ts (grantCruiseReward action)
- src/components/game/DecodeArray.tsx (节点偏移修复)
- src/components/game/AchievementsPanel.tsx (小屏重叠修复)

QA: lint 零错误; agent-browser+VLM 验证主界面无偏移+巡航玩法正常运行
This commit is contained in:
2026-06-23 19:33:51 +00:00
parent fcf94b6c3f
commit fafa2ee20a
9 changed files with 3382 additions and 8 deletions
+19 -4
View File
@@ -18,6 +18,7 @@ import { ChronicleDialog } from "@/components/game/ChronicleDialog";
import { BeaconPanel } from "@/components/game/BeaconPanel";
import { TutorialOverlay } from "@/components/game/TutorialOverlay";
import { OfflineReportDialog } from "@/components/game/OfflineReportDialog";
import { CruiseMode } from "@/components/game/CruiseMode";
import {
StarTideNotifier,
StarTideIndicator,
@@ -40,6 +41,7 @@ import {
Trophy,
Star,
Radio,
Navigation,
} from "lucide-react";
import { TECH_TREE, FRAGMENTS, formatNum } from "@/lib/game/config";
import { ACHIEVEMENTS } from "@/lib/game/achievements";
@@ -54,6 +56,7 @@ export default function Page() {
const [settingsOpen, setSettingsOpen] = useState(false);
const [constellationOpen, setConstellationOpen] = useState(false);
const [chronicleOpen, setChronicleOpen] = useState(false);
const [cruiseOpen, setCruiseOpen] = useState(false);
const [mounted, setMounted] = useState(false);
const contact = useGameStore((s) => s.contact);
@@ -172,6 +175,17 @@ export default function Page() {
</div>
<div className="ml-auto flex items-center gap-1.5">
<StarTideIndicator />
<Button
size="sm"
variant="outline"
onClick={() => setCruiseOpen(true)}
className="border-amber-400/50 text-amber-200 hover:bg-amber-500/10 h-8 px-2.5"
aria-label="深空巡航"
title="深空巡航 · 实时玩法"
>
<Navigation className="h-3.5 w-3.5 mr-1" />
</Button>
<Button
size="icon"
variant="ghost"
@@ -224,11 +238,11 @@ export default function Page() {
<ResourceBar onPrestige={() => setPrestigeOpen(true)} />
</header>
{/* 主体 */}
{/* 主体 — 小屏允许自然滚动,避免 min-h 总和超过视口导致挤压重叠 */}
<main className="flex-1 px-3 sm:px-5 pb-3 min-h-0">
<div className="grid grid-cols-1 lg:grid-cols-[1fr_minmax(360px,420px)] gap-3 h-full">
{/* 左侧:脉冲晶体 */}
<section className="glass rounded-2xl p-4 sm:p-6 flex flex-col items-center justify-center min-h-[420px] relative overflow-hidden">
<section className="glass rounded-2xl p-4 sm:p-6 flex flex-col items-center justify-center min-h-[340px] sm:min-h-[420px] relative overflow-hidden">
{/* 装饰光圈 */}
<div className="pointer-events-none absolute -top-20 -left-20 h-60 w-60 rounded-full bg-emerald-500/10 blur-3xl" />
<div className="pointer-events-none absolute -bottom-20 -right-20 h-60 w-60 rounded-full bg-fuchsia-500/10 blur-3xl" />
@@ -240,11 +254,11 @@ export default function Page() {
{/* 右侧:解码 + 标签面板 */}
<section className="flex flex-col gap-3 min-h-0">
{/* 解码面板 */}
<div data-tut="decode-panel" className="glass rounded-2xl p-4 flex-1 min-h-[360px] max-h-[560px]">
<div data-tut="decode-panel" className="glass rounded-2xl p-4 flex-1 min-h-[300px] sm:min-h-[360px] max-h-[560px]">
<DecodePanel />
</div>
{/* 标签面板:探险 / 技术 / 星图 / 图谱 / 成就 / 信标 / 统计 */}
<div className="glass rounded-2xl p-3 min-h-[320px] max-h-[440px]">
<div className="glass rounded-2xl p-3 min-h-[280px] sm:min-h-[320px] max-h-[440px] flex flex-col">
<Tabs defaultValue={hasActiveExpedition ? "expedition" : hasPendingPerk ? "constellation" : "tech"} className="h-full flex flex-col">
<TabsList className="grid grid-cols-7 h-9 bg-black/30 gap-0.5 p-1">
<TabsTrigger value="expedition" data-tut="tab-expedition" className="text-[11px] gap-1 relative px-0.5 flex-col h-7 data-[state=active]:bg-amber-500/15 data-[state=active]:shadow-[0_0_12px_rgba(251,191,36,0.3)] transition-all">
@@ -373,6 +387,7 @@ export default function Page() {
<StarTideNotifier />
<TutorialOverlay />
<OfflineReportDialog />
{cruiseOpen && <CruiseMode onClose={() => setCruiseOpen(false)} />}
</div>
);
}