Files
echo-nexus/.next/dev/static/chunks/src_fe091346._.js
T

4988 lines
316 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(globalThis.TURBOPACK || (globalThis.TURBOPACK = [])).push([typeof document === "object" ? document.currentScript : undefined,
"[project]/src/lib/game/cruise.ts [app-client] (ecmascript)", ((__turbopack_context__) => {
"use strict";
// 回响星核 / Echo Nexus — 深空巡航(v0.8 Canvas 2D 实时玩法)
// 一个自包含的"实时操作"玩法模块:操控飞船穿越陨石带、虚空风暴,
// 收集晶体碎片/洞见光球/信标,最终抵达星门通关。奖励同步到主游戏。
// v0.8 新增:BOSS 战(每 5 关)/ 飞船射击 / 道具掉落 / 事件选择节点。
// 独立 localStorageecho-nexus-cruise-v1),不污染 GameState schema。
// ============================================================
// 类型定义
// ============================================================
/** 游戏阶段 */ __turbopack_context__.s([
"CRUISE_CONFIG",
()=>CRUISE_CONFIG,
"UPGRADE_POOL",
()=>UPGRADE_POOL,
"applyUpgradeCard",
()=>applyUpgradeCard,
"burstParticles",
()=>burstParticles,
"computeRewards",
()=>computeRewards,
"cruiseSeed",
()=>cruiseSeed,
"defaultUpgrades",
()=>defaultUpgrades,
"generateLevel",
()=>generateLevel,
"loadCruiseStats",
()=>loadCruiseStats,
"recordRun",
()=>recordRun,
"resetCruiseStats",
()=>resetCruiseStats,
"rollUpgradeChoices",
()=>rollUpgradeChoices,
"saveCruiseStats",
()=>saveCruiseStats,
"shootShip",
()=>shootShip,
"updateCruise",
()=>updateCruise
]);
const CRUISE_CONFIG = {
/** 飞船最大速度(px/s */ shipMaxSpeed: 280,
/** 飞船加速度(px/s²) */ shipAccel: 900,
/** 飞船摩擦系数(每秒衰减比例) */ shipFriction: 0.88,
/** 飞船半径 */ shipRadius: 14,
/** 护盾上限 */ shieldMax: 100,
/** 护盾恢复速率(/s,仅在未受击时) */ shieldRegen: 2,
/** 能量上限 */ energyMax: 100,
/** 能量恢复速率(/s */ energyRegen: 8,
/** 收集物吸引半径 */ attractRadius: 90,
/** 收集物吸入半径(实际收集) */ collectRadius: 22,
/** 陨石基础伤害 */ asteroidBaseDamage: 18,
/** 风暴持续伤害(/s */ stormDps: 12,
/** 受击后无敌时间(ms */ invulnMs: 600,
/** 屏幕震动时长(ms */ shakeMs: 280,
/** 屏幕震动强度 */ shakeIntensity: 14,
/** 粒子上限 */ maxParticles: 200,
/** 子弹粒子上限 */ maxBullets: 80,
/** 道具上限 */ maxPowerups: 12,
/** 离屏剔除余量(px */ cullMargin: 100,
/** 基础关卡时长(秒) */ baseDuration: 60,
/** 每关增加时长(秒) */ durationPerLevel: 3,
/** 关卡时长上限(秒) */ maxDuration: 90,
/** BOSS 关卡时长(秒,更长) */ bossDuration: 120,
/** 视差星空层数 */ parallaxLayers: 3,
/** 最大关卡(用于 stats 显示) */ maxLevel: 99,
// ---- 射击 ----
/** 子弹速度(px/s */ bulletSpeed: 540,
/** 子弹伤害(飞船) */ bulletDamage: 8,
/** 每发消耗能量 */ bulletEnergyCost: 5,
/** 射击冷却(ms */ shootCooldownMs: 150,
/** 子弹生命(秒) */ bulletLife: 1.4,
/** 子弹半径 */ bulletRadius: 4,
// ---- BOSS ----
/** BOSS 基础 HP */ bossBaseHp: 100,
/** 每关 HP 增量 */ bossHpPerLevel: 20,
/** BOSS 半径 */ bossRadius: 70,
/** BOSS 子弹伤害 */ bossBulletDamage: 14,
/** BOSS 直射间隔(秒) */ bossDirectInterval: 1.5,
/** BOSS 散射间隔(秒) */ bossScatterInterval: 2.2,
/** BOSS 追踪弹间隔(秒) */ bossHomingInterval: 2.0,
/** BOSS 召唤间隔(秒) */ bossSummonInterval: 4.5,
/** BOSS 漂移速度 */ bossDriftSpeed: 18,
/** BOSS 接触伤害 */ bossContactDamage: 22,
// ---- 道具 ----
/** 道具拾取半径 */ powerupPickupRadius: 26,
/** 道具吸引半径(基础,受 magnet buff 加成) */ powerupAttractRadius: 120,
/** BOSS 战掉落物寿命(秒) */ powerupLifeBoss: 18,
/** 普通关卡掉落物寿命(秒) */ powerupLifeNormal: 10,
// ---- Buff 时长(秒) ----
buffRapidDuration: 8,
buffOverdriveDuration: 8,
buffMagnetDuration: 6
};
const UPGRADE_POOL = [
{
id: "speed",
title: "速度 +12%",
desc: "飞船最大速度提升",
color: "#34d399",
icon: "Wind"
},
{
id: "accel",
title: "加速度 +15%",
desc: "更灵活的转向响应",
color: "#34d399",
icon: "Gauge"
},
{
id: "friction",
title: "摩擦优化 +5%",
desc: "惯性更小,转向更利落",
color: "#34d399",
icon: "Feather"
},
{
id: "shield_max",
title: "护盾上限 +25",
desc: "最高护盾值提升",
color: "#34d399",
icon: "Shield"
},
{
id: "shield_regen",
title: "护盾恢复 +50%",
desc: "未受击时护盾回血更快",
color: "#34d399",
icon: "HeartPulse"
},
{
id: "energy_max",
title: "能量上限 +25",
desc: "更多射击储备",
color: "#fbbf24",
icon: "Battery"
},
{
id: "energy_regen",
title: "能量恢复 +30%",
desc: "能量回充加速",
color: "#fbbf24",
icon: "Zap"
},
{
id: "firepower",
title: "火力 +25%",
desc: "每发子弹伤害更高",
color: "#fb7185",
icon: "Flame"
},
{
id: "fire_rate",
title: "射速 +20%",
desc: "射击间隔更短",
color: "#fb7185",
icon: "Timer"
},
{
id: "double_shot",
title: "双发",
desc: "每次射击发射 2 发(仅一次)",
color: "#e879f9",
icon: "Split"
},
{
id: "attract_radius",
title: "吸引半径 +40%",
desc: "更远距离吸取收集物",
color: "#e879f9",
icon: "Magnet"
},
{
id: "collect_radius",
title: "收集半径 +50%",
desc: "更易拾取道具与晶体",
color: "#e879f9",
icon: "Circle"
},
{
id: "invuln_time",
title: "无敌时间 +200ms",
desc: "受击后更多喘息",
color: "#34d399",
icon: "ShieldCheck"
},
{
id: "damage_reduce",
title: "受击伤害 -20%",
desc: "减少承受的伤害",
color: "#34d399",
icon: "ShieldHalf"
},
{
id: "boss_bonus",
title: "BOSS 战金币 +50%",
desc: "击败 BOSS 奖励翻倍加成",
color: "#fbbf24",
icon: "Crown"
},
{
id: "normal_score",
title: "普通关卡分数 +30%",
desc: "通关得分提升",
color: "#fbbf24",
icon: "Star"
},
{
id: "start_shield",
title: "起始护盾 +20",
desc: "每局开局更高护盾",
color: "#34d399",
icon: "ShieldPlus"
},
{
id: "start_energy",
title: "起始能量 +20",
desc: "每局开局更多能量",
color: "#fbbf24",
icon: "BatteryCharging"
}
];
function defaultUpgrades() {
return {
speedMult: 1,
accelMult: 1,
frictionBonus: 0,
shieldMaxBonus: 0,
shieldRegenMult: 1,
energyMaxBonus: 0,
energyRegenMult: 1,
firepowerMult: 1,
fireRateMult: 1,
doubleShot: false,
attractRadiusMult: 1,
collectRadiusMult: 1,
invulnBonusMs: 0,
damageReduceMult: 1,
bossBonusMult: 1,
normalScoreMult: 1,
startShieldBonus: 0,
startEnergyBonus: 0
};
}
function applyUpgradeCard(upgrades, card) {
switch(card.id){
case "speed":
upgrades.speedMult *= 1.12;
break;
case "accel":
upgrades.accelMult *= 1.15;
break;
case "friction":
// 摩擦优化 = 减少 friction 衰减,用正值表示优化程度
upgrades.frictionBonus = Math.min(0.2, upgrades.frictionBonus + 0.05);
break;
case "shield_max":
upgrades.shieldMaxBonus += 25;
break;
case "shield_regen":
upgrades.shieldRegenMult *= 1.5;
break;
case "energy_max":
upgrades.energyMaxBonus += 25;
break;
case "energy_regen":
upgrades.energyRegenMult *= 1.3;
break;
case "firepower":
upgrades.firepowerMult *= 1.25;
break;
case "fire_rate":
upgrades.fireRateMult *= 0.8; // 间隔更短 = 更快
break;
case "double_shot":
upgrades.doubleShot = true;
break;
case "attract_radius":
upgrades.attractRadiusMult *= 1.4;
break;
case "collect_radius":
upgrades.collectRadiusMult *= 1.5;
break;
case "invuln_time":
upgrades.invulnBonusMs += 200;
break;
case "damage_reduce":
upgrades.damageReduceMult *= 0.8;
break;
case "boss_bonus":
upgrades.bossBonusMult *= 1.5;
break;
case "normal_score":
upgrades.normalScoreMult *= 1.3;
break;
case "start_shield":
upgrades.startShieldBonus += 20;
break;
case "start_energy":
upgrades.startEnergyBonus += 20;
break;
}
}
function rollUpgradeChoices(count = 3, exclude = []) {
const pool = UPGRADE_POOL.filter((c)=>!exclude.includes(c.id));
const shuffled = [
...pool
].sort(()=>Math.random() - 0.5);
return shuffled.slice(0, Math.min(count, shuffled.length));
}
// ============================================================
// 随机数(mulberry32,与 beacon 模块风格一致)
// ============================================================
function mulberry32(seed) {
let a = seed >>> 0;
return function() {
a |= 0;
a = a + 0x6d2b79f5 | 0;
let t = a;
t = Math.imul(t ^ t >>> 15, t | 1);
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
return ((t ^ t >>> 14) >>> 0) / 4294967296;
};
}
/** FNV-1a 哈希(用于种子生成) */ function fnv1a(str) {
let hash = 0x811c9dc5;
for(let i = 0; i < str.length; i++){
hash ^= str.charCodeAt(i);
hash = Math.imul(hash, 0x01000193);
}
return hash >>> 0;
}
function cruiseSeed(level, salt = Date.now()) {
return fnv1a(`cruise-l${level}-s${salt}`);
}
// ============================================================
// 工具:根据 upgrades 计算实时数值
// ============================================================
function effectiveShieldMax(state) {
return CRUISE_CONFIG.shieldMax + state.upgrades.shieldMaxBonus;
}
function effectiveEnergyMax(state) {
return CRUISE_CONFIG.energyMax + state.upgrades.energyMaxBonus;
}
function effectiveShipMaxSpeed(state) {
let mult = state.upgrades.speedMult;
// overdrive buff 期间 ×1.5
if (state.activeBuffs.some((b)=>b.type === "overdrive")) mult *= 1.5;
return CRUISE_CONFIG.shipMaxSpeed * mult;
}
function effectiveShipAccel(state) {
return CRUISE_CONFIG.shipAccel * state.upgrades.accelMult;
}
function effectiveFriction(state) {
// 摩擦优化让 friction 衰减更慢(更接近 1
return Math.min(0.98, CRUISE_CONFIG.shipFriction + state.upgrades.frictionBonus);
}
function effectiveAttractRadius(state) {
let mult = state.upgrades.attractRadiusMult;
// magnet buff 期间 ×3
if (state.activeBuffs.some((b)=>b.type === "magnet")) mult *= 3;
return CRUISE_CONFIG.attractRadius * mult;
}
function effectiveCollectRadius(state) {
return CRUISE_CONFIG.collectRadius * state.upgrades.collectRadiusMult;
}
function effectiveShootCooldownMs(state) {
let mult = state.upgrades.fireRateMult;
// rapid buff 期间 ×0.5
if (state.activeBuffs.some((b)=>b.type === "rapid")) mult *= 0.5;
return CRUISE_CONFIG.shootCooldownMs * mult;
}
function effectiveBulletDamage(state) {
return CRUISE_CONFIG.bulletDamage * state.upgrades.firepowerMult;
}
function effectiveInvulnMs(state) {
return CRUISE_CONFIG.invulnMs + state.upgrades.invulnBonusMs;
}
function generateLevel(level, seed, worldWidth, worldHeight, upgrades = defaultUpgrades(), appliedUpgrades = []) {
const rng = mulberry32(seed);
const W = worldWidth;
const H = worldHeight;
let nextId = 1;
const isBossLevel = level > 0 && level % 5 === 0;
// 飞船:底部中央,起始护盾/能量受 upgrades 加成
const startShield = Math.min(CRUISE_CONFIG.shieldMax + upgrades.shieldMaxBonus, CRUISE_CONFIG.shieldMax + upgrades.shieldMaxBonus + upgrades.startShieldBonus);
const startEnergy = Math.min(CRUISE_CONFIG.energyMax + upgrades.energyMaxBonus, CRUISE_CONFIG.energyMax + upgrades.energyMaxBonus + upgrades.startEnergyBonus);
const ship = {
id: nextId++,
type: "ship",
x: W / 2,
y: H - 80,
vx: 0,
vy: 0,
heading: -Math.PI / 2,
shield: startShield,
energy: startEnergy,
radius: CRUISE_CONFIG.shipRadius,
thrust: 0
};
const entities = [];
let boss = null;
let crystalCount = 0;
let insightCount = 0;
let beaconCount = 0;
let durationSec;
if (isBossLevel) {
// ---- BOSS 关卡:只生成 BOSS + 少量环境装饰(无星门) ----
const bossHp = CRUISE_CONFIG.bossBaseHp + level * CRUISE_CONFIG.bossHpPerLevel;
boss = {
id: nextId++,
type: "boss",
x: W / 2,
y: H * 0.3,
vx: 0,
vy: 0,
hp: bossHp,
maxHp: bossHp,
radius: CRUISE_CONFIG.bossRadius,
rotation: 0,
rotationSpeed: 0.3,
pulsePhase: 0,
attackPhase: 1,
directTimer: 1.5,
homingTimer: 2,
summonTimer: 4,
driftAngle: 0,
dropStage: 0,
breathPhase: 0,
tentaclePhase: 0
};
durationSec = CRUISE_CONFIG.bossDuration;
// 少量装饰性小陨石(缓慢飘动,增加视觉层次)
const decorAsteroids = 4;
for(let i = 0; i < decorAsteroids; i++){
const radius = 14 + rng() * 16;
const x = 60 + rng() * (W - 120);
const y = 60 + rng() * (H - 120);
const speed = 20 + rng() * 30;
const angle = rng() * Math.PI * 2;
const vertCount = 7 + Math.floor(rng() * 4);
const vertices = [];
for(let v = 0; v < vertCount; v++)vertices.push(0.75 + rng() * 0.4);
entities.push({
id: nextId++,
type: "asteroid",
x,
y,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
radius,
rotation: rng() * Math.PI * 2,
rotationSpeed: (rng() - 0.5) * 1.2,
vertices,
damage: CRUISE_CONFIG.asteroidBaseDamage + level * 1.5
});
}
// 几枚晶体作为补给
crystalCount = 4;
for(let i = 0; i < crystalCount; i++){
const x = 80 + rng() * (W - 160);
const y = 120 + rng() * (H - 240);
entities.push({
id: nextId++,
type: "crystal",
x,
y,
vx: 0,
vy: 0,
radius: 12,
rotation: rng() * Math.PI * 2,
rotationSpeed: (rng() - 0.5) * 2,
pulsePhase: rng() * Math.PI * 2,
collected: false
});
}
} else {
// ---- 普通关卡:星门 + 陨石带 + 风暴 + 收集物 ----
// 星门:顶部中央
const stargate = {
id: nextId++,
type: "stargate",
x: W / 2,
y: 70,
vx: 0,
vy: 0,
radius: 42,
rotation: 0,
rotationSpeed: 0.6,
pulsePhase: 0,
active: false
};
entities.push(stargate);
// 陨石带:数量随关卡递增
const asteroidCount = Math.min(8 + level * 2, 32);
for(let i = 0; i < asteroidCount; i++){
const radius = 16 + rng() * 28;
let x = 0, y = 0, tries = 0;
do {
x = 40 + rng() * (W - 80);
y = 140 + rng() * (H - 260);
tries++;
}while (tries < 20 && (Math.hypot(x - ship.x, y - ship.y) < 120 || Math.hypot(x - stargate.x, y - stargate.y) < 100))
const speed = 30 + rng() * 60 + level * 4;
const angle = rng() * Math.PI * 2;
const vertCount = 7 + Math.floor(rng() * 4);
const vertices = [];
for(let v = 0; v < vertCount; v++){
vertices.push(0.75 + rng() * 0.4);
}
entities.push({
id: nextId++,
type: "asteroid",
x,
y,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
radius,
rotation: rng() * Math.PI * 2,
rotationSpeed: (rng() - 0.5) * 1.2,
vertices,
damage: CRUISE_CONFIG.asteroidBaseDamage + level * 1.5
});
}
// 虚空风暴:随关卡递增(最多 5 个)
const stormCount = Math.min(1 + Math.floor(level / 2), 5);
for(let i = 0; i < stormCount; i++){
const radius = 60 + rng() * 50;
let x = 0, y = 0, tries = 0;
do {
x = 100 + rng() * (W - 200);
y = 180 + rng() * (H - 320);
tries++;
}while (tries < 20 && (Math.hypot(x - ship.x, y - ship.y) < 180 || Math.hypot(x - stargate.x, y - stargate.y) < 150))
const speed = 12 + rng() * 18;
const angle = rng() * Math.PI * 2;
entities.push({
id: nextId++,
type: "storm",
x,
y,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
radius,
rotation: rng() * Math.PI * 2,
rotationSpeed: (rng() - 0.5) * 0.4,
lightningTimer: rng() * 0.5,
cloudSeed: Math.floor(rng() * 10000)
});
}
// 晶体碎片:5 + level
crystalCount = 5 + level;
for(let i = 0; i < crystalCount; i++){
let x = 0, y = 0, tries = 0;
do {
x = 50 + rng() * (W - 100);
y = 120 + rng() * (H - 220);
tries++;
}while (tries < 20 && Math.hypot(x - ship.x, y - ship.y) < 90)
entities.push({
id: nextId++,
type: "crystal",
x,
y,
vx: 0,
vy: 0,
radius: 12,
rotation: rng() * Math.PI * 2,
rotationSpeed: (rng() - 0.5) * 2,
pulsePhase: rng() * Math.PI * 2,
collected: false
});
}
// 洞见光球:2 + floor(level/3)
insightCount = 2 + Math.floor(level / 3);
for(let i = 0; i < insightCount; i++){
let x = 0, y = 0, tries = 0;
do {
x = 60 + rng() * (W - 120);
y = 140 + rng() * (H - 240);
tries++;
}while (tries < 20 && Math.hypot(x - ship.x, y - ship.y) < 100)
entities.push({
id: nextId++,
type: "insight",
x,
y,
vx: 0,
vy: 0,
radius: 14,
pulsePhase: rng() * Math.PI * 2,
swirlAngle: rng() * Math.PI * 2,
collected: false
});
}
// 信标:1 + floor(level/4)
beaconCount = 1 + Math.floor(level / 4);
for(let i = 0; i < beaconCount; i++){
let x = 0, y = 0, tries = 0;
do {
x = 80 + rng() * (W - 160);
y = 160 + rng() * (H - 280);
tries++;
}while (tries < 20 && Math.hypot(x - ship.x, y - ship.y) < 110)
entities.push({
id: nextId++,
type: "beacon",
x,
y,
vx: 0,
vy: 0,
radius: 16,
rotation: rng() * Math.PI * 2,
rotationSpeed: (rng() - 0.5) * 1.5,
pulsePhase: rng() * Math.PI * 2,
collected: false
});
}
durationSec = Math.min(CRUISE_CONFIG.baseDuration + (level - 1) * CRUISE_CONFIG.durationPerLevel, CRUISE_CONFIG.maxDuration);
}
return {
phase: "ready",
level,
seed,
ship,
entities,
particles: [],
bullets: [],
powerups: [],
boss,
isBossLevel,
score: 0,
timeSec: 0,
durationSec,
collectedCrystals: 0,
collectedInsights: 0,
collectedBeacons: 0,
totalCrystals: crystalCount,
totalInsights: insightCount,
totalBeacons: beaconCount,
shakeAmount: 0,
shakeTimer: 0,
flashLowShield: false,
pickupFlash: null,
worldWidth: W,
worldHeight: H,
nextEntityId: nextId,
invulnTimer: 0,
shootCooldown: 0,
endedAt: null,
upgrades,
appliedUpgrades,
pendingUpgradeChoice: [],
activeBuffs: [],
bossDefeated: false
};
}
/** 计算 upgrades 在无 state 时的 shield 上限(用于 generateLevel 初始化) */ function effectiveShieldMaxRaw(upgrades) {
return CRUISE_CONFIG.shieldMax + upgrades.shieldMaxBonus + upgrades.startShieldBonus;
}
function effectiveEnergyMaxRaw(upgrades) {
return CRUISE_CONFIG.energyMax + upgrades.energyMaxBonus + upgrades.startEnergyBonus;
}
// ============================================================
// 物理与碰撞更新
// ============================================================
/** 触发屏幕震动 */ function triggerShake(state, intensity) {
state.shakeAmount = intensity ?? CRUISE_CONFIG.shakeIntensity;
state.shakeTimer = CRUISE_CONFIG.shakeMs;
}
/** 添加粒子(自动限制数量) */ function addParticle(state, p) {
state.particles.push({
id: state.nextEntityId++,
type: "particle",
...p
});
// 超出上限移除最老的
while(state.particles.length > CRUISE_CONFIG.maxParticles){
state.particles.shift();
}
}
function burstParticles(state, x, y, color, count, speed = 180, life = 0.6, size = 3) {
for(let i = 0; i < count; i++){
const angle = i / count * Math.PI * 2 + Math.random() * 0.4;
const sp = speed * (0.4 + Math.random() * 0.8);
addParticle(state, {
x,
y,
vx: Math.cos(angle) * sp,
vy: Math.sin(angle) * sp,
life: life * (0.7 + Math.random() * 0.6),
maxLife: life,
size: size * (0.6 + Math.random() * 0.8),
color,
shrink: true
});
}
}
/** 飞船尾焰粒子 */ function emitThrustParticle(state, ship) {
const back = ship.heading + Math.PI;
const spread = (Math.random() - 0.5) * 0.6;
const ang = back + spread;
const sp = 80 + Math.random() * 60;
// 颜色:emerald → amber 随推力变化
const t = Math.min(1, ship.thrust);
const r = Math.round(52 + t * (251 - 52));
const g = Math.round(211 + t * (191 - 211));
const b = Math.round(153 + t * (36 - 153));
const color = `rgba(${r},${g},${b},0.9)`;
addParticle(state, {
x: ship.x + Math.cos(back) * ship.radius,
y: ship.y + Math.sin(back) * ship.radius,
vx: Math.cos(ang) * sp + ship.vx * 0.3,
vy: Math.sin(ang) * sp + ship.vy * 0.3,
life: 0.35 + Math.random() * 0.25,
maxLife: 0.6,
size: 2.5 + Math.random() * 2,
color,
shrink: true
});
}
/** 添加子弹(自动限制数量) */ function addBullet(state, b) {
if (state.bullets.length >= CRUISE_CONFIG.maxBullets) {
state.bullets.shift();
}
state.bullets.push({
id: state.nextEntityId++,
type: "bullet",
...b
});
}
/** 添加道具 */ function addPowerup(state, p) {
if (state.powerups.length >= CRUISE_CONFIG.maxPowerups) {
state.powerups.shift();
}
state.powerups.push({
id: state.nextEntityId++,
type: "powerup",
...p
});
}
function shootShip(state) {
if (state.phase !== "playing") return;
if (state.shootCooldown > 0) return;
const ship = state.ship;
const energyCost = CRUISE_CONFIG.bulletEnergyCost;
if (ship.energy < energyCost) return;
ship.energy -= energyCost;
state.shootCooldown = effectiveShootCooldownMs(state);
const dmg = effectiveBulletDamage(state);
const ang = ship.heading;
const muzzleX = ship.x + Math.cos(ang) * (ship.radius + 4);
const muzzleY = ship.y + Math.sin(ang) * (ship.radius + 4);
const v = CRUISE_CONFIG.bulletSpeed;
// 主弹
addBullet(state, {
x: muzzleX,
y: muzzleY,
vx: Math.cos(ang) * v,
vy: Math.sin(ang) * v,
owner: "ship",
radius: CRUISE_CONFIG.bulletRadius,
damage: dmg,
life: CRUISE_CONFIG.bulletLife,
homing: false,
homingTime: 0,
color: "#34d399"
});
// 双发:上下偏移 8°
if (state.upgrades.doubleShot) {
for (const offset of [
0.14,
-0.14
]){
const a2 = ang + offset;
addBullet(state, {
x: ship.x + Math.cos(a2) * (ship.radius + 4),
y: ship.y + Math.sin(a2) * (ship.radius + 4),
vx: Math.cos(a2) * v,
vy: Math.sin(a2) * v,
owner: "ship",
radius: CRUISE_CONFIG.bulletRadius,
damage: dmg,
life: CRUISE_CONFIG.bulletLife,
homing: false,
homingTime: 0,
color: "#34d399"
});
}
}
// 枪口闪光粒子
burstParticles(state, muzzleX, muzzleY, "#a7f3d0", 4, 120, 0.25, 2);
}
// ============================================================
// BOSS AI
// ============================================================
/** BOSS 攻击模式更新 */ function updateBoss(state, dt) {
const boss = state.boss;
if (!boss) return;
const ship = state.ship;
// 阶段切换(HP 比例)
const hpPct = boss.hp / boss.maxHp;
if (hpPct > 0.66) boss.attackPhase = 1;
else if (hpPct > 0.33) boss.attackPhase = 2;
else boss.attackPhase = 3;
// 视觉相位
boss.rotation += boss.rotationSpeed * dt;
boss.pulsePhase += dt * 2;
boss.breathPhase += dt * 1.4;
boss.tentaclePhase += dt * 0.8;
// 漂浮:以画布中心区域为目标,缓慢游走
boss.driftAngle += dt * 0.4;
const cx = state.worldWidth / 2 + Math.cos(boss.driftAngle) * (state.worldWidth * 0.25);
const cy = state.worldHeight * 0.32 + Math.sin(boss.driftAngle * 1.3) * 40;
const dx = cx - boss.x;
const dy = cy - boss.y;
const dist = Math.hypot(dx, dy) || 1;
const driftSpeed = CRUISE_CONFIG.bossDriftSpeed;
boss.vx = dx / dist * driftSpeed;
boss.vy = dy / dist * driftSpeed;
boss.x += boss.vx * dt;
boss.y += boss.vy * dt;
// 边界
boss.x = Math.max(boss.radius + 20, Math.min(state.worldWidth - boss.radius - 20, boss.x));
boss.y = Math.max(boss.radius + 20, Math.min(state.worldHeight * 0.55, boss.y));
// ---- 攻击 ----
// 阶段1:直射
if (boss.attackPhase >= 1) {
boss.directTimer -= dt;
if (boss.directTimer <= 0) {
boss.directTimer = boss.attackPhase === 1 ? CRUISE_CONFIG.bossDirectInterval : CRUISE_CONFIG.bossScatterInterval;
if (boss.attackPhase === 1) {
// 直射一发,朝飞船方向
const a = Math.atan2(ship.y - boss.y, ship.x - boss.x);
const v = 260;
addBullet(state, {
x: boss.x + Math.cos(a) * boss.radius,
y: boss.y + Math.sin(a) * boss.radius,
vx: Math.cos(a) * v,
vy: Math.sin(a) * v,
owner: "boss",
radius: 6,
damage: CRUISE_CONFIG.bossBulletDamage,
life: 4,
homing: false,
homingTime: 0,
color: "#fb7185"
});
} else {
// 阶段2+:散射 5 发扇形
const baseA = Math.atan2(ship.y - boss.y, ship.x - boss.x);
const v = 240;
for(let i = -2; i <= 2; i++){
const a = baseA + i * 0.18;
addBullet(state, {
x: boss.x + Math.cos(a) * boss.radius,
y: boss.y + Math.sin(a) * boss.radius,
vx: Math.cos(a) * v,
vy: Math.sin(a) * v,
owner: "boss",
radius: 6,
damage: CRUISE_CONFIG.bossBulletDamage,
life: 4,
homing: false,
homingTime: 0,
color: "#fb7185"
});
}
}
}
}
// 阶段2+:召唤小陨石
if (boss.attackPhase >= 2) {
boss.summonTimer -= dt;
if (boss.summonTimer <= 0) {
boss.summonTimer = CRUISE_CONFIG.bossSummonInterval;
for(let i = 0; i < 2; i++){
const a = Math.random() * Math.PI * 2;
const r = boss.radius + 10;
const sx = boss.x + Math.cos(a) * r;
const sy = boss.y + Math.sin(a) * r;
const v = 100 + Math.random() * 60;
const ang = Math.atan2(ship.y - sy, ship.x - sx) + (Math.random() - 0.5) * 0.8;
const vertCount = 7;
const vertices = [];
for(let k = 0; k < vertCount; k++)vertices.push(0.75 + Math.random() * 0.4);
state.entities.push({
id: state.nextEntityId++,
type: "asteroid",
x: sx,
y: sy,
vx: Math.cos(ang) * v,
vy: Math.sin(ang) * v,
radius: 14 + Math.random() * 8,
rotation: Math.random() * Math.PI * 2,
rotationSpeed: (Math.random() - 0.5) * 2,
vertices,
damage: CRUISE_CONFIG.asteroidBaseDamage,
summoned: true
});
}
// 召唤特效
burstParticles(state, boss.x, boss.y, "#e879f9", 12, 200, 0.5, 3);
}
}
// 阶段3:追踪弹
if (boss.attackPhase >= 3) {
boss.homingTimer -= dt;
if (boss.homingTimer <= 0) {
boss.homingTimer = CRUISE_CONFIG.bossHomingInterval;
const a = Math.atan2(ship.y - boss.y, ship.x - boss.x);
const v = 200;
addBullet(state, {
x: boss.x + Math.cos(a) * boss.radius,
y: boss.y + Math.sin(a) * boss.radius,
vx: Math.cos(a) * v,
vy: Math.sin(a) * v,
owner: "boss",
radius: 7,
damage: CRUISE_CONFIG.bossBulletDamage,
life: 5,
homing: true,
homingTime: 3,
color: "#e879f9"
});
}
}
// ---- 道具掉落:每损失 25% HP 掉 1 个 ----
const newDropStage = Math.min(3, Math.floor((1 - hpPct) / 0.25));
while(boss.dropStage < newDropStage){
boss.dropStage++;
dropRandomPowerup(state, boss.x + (Math.random() - 0.5) * 80, boss.y + 40, "boss");
burstParticles(state, boss.x, boss.y, "#fbbf24", 16, 200, 0.6, 3);
}
}
/** 掉落随机道具 */ function dropRandomPowerup(state, x, y, source) {
const types = [
"shield",
"energy",
"rapid",
"overdrive",
"magnet"
];
const t = types[Math.floor(Math.random() * types.length)];
const life = source === "boss" ? CRUISE_CONFIG.powerupLifeBoss : CRUISE_CONFIG.powerupLifeNormal;
addPowerup(state, {
x,
y,
vx: (Math.random() - 0.5) * 30,
vy: 20 + Math.random() * 20,
powerupType: t,
radius: 14,
rotation: 0,
rotationSpeed: (Math.random() - 0.5) * 2,
pulsePhase: Math.random() * Math.PI * 2,
life,
maxLife: life,
collected: false
});
}
// ============================================================
// 子弹更新
// ============================================================
function updateBullets(state, dt) {
const ship = state.ship;
for(let i = state.bullets.length - 1; i >= 0; i--){
const b = state.bullets[i];
b.life -= dt;
if (b.life <= 0) {
state.bullets.splice(i, 1);
continue;
}
// 追踪弹
if (b.homing && b.homingTime > 0) {
b.homingTime -= dt;
const a = Math.atan2(ship.y - b.y, ship.x - b.x);
const v = Math.hypot(b.vx, b.vy);
// 平滑转向
const curA = Math.atan2(b.vy, b.vx);
let diff = a - curA;
while(diff > Math.PI)diff -= Math.PI * 2;
while(diff < -Math.PI)diff += Math.PI * 2;
const turn = Math.max(-2 * dt, Math.min(2 * dt, diff));
const newA = curA + turn;
b.vx = Math.cos(newA) * v;
b.vy = Math.sin(newA) * v;
}
b.x += b.vx * dt;
b.y += b.vy * dt;
// 离屏剔除
const m = 50;
if (b.x < -m || b.x > state.worldWidth + m || b.y < -m || b.y > state.worldHeight + m) {
state.bullets.splice(i, 1);
continue;
}
// 尾焰粒子(少量)
if (Math.random() < 0.4) {
addParticle(state, {
x: b.x,
y: b.y,
vx: -b.vx * 0.05,
vy: -b.vy * 0.05,
life: 0.2,
maxLife: 0.3,
size: 2,
color: b.color,
shrink: true
});
}
// ---- 碰撞 ----
if (b.owner === "ship") {
// 飞船子弹 vs 陨石(小陨石/召唤陨石一击碎;大陨石伤害衰减)
let consumed = false;
for (const e of state.entities){
if (e.type !== "asteroid") continue;
const d = Math.hypot(b.x - e.x, b.y - e.y);
if (d < e.radius + b.radius) {
if (e.summoned || e.radius < 22) {
// 一击碎
burstParticles(state, e.x, e.y, "#fb7185", 14, 220, 0.5, 3);
// 标记移除(后面统一过滤)
e.damage = -999; // 标记删除
state.score += 30;
} else {
// 大陨石:只是擦伤
burstParticles(state, b.x, b.y, "#fbbf24", 6, 160, 0.3, 2);
}
consumed = true;
break;
}
}
// 飞船子弹 vs BOSS
if (!consumed && state.boss) {
const d = Math.hypot(b.x - state.boss.x, b.y - state.boss.y);
if (d < state.boss.radius + b.radius) {
state.boss.hp = Math.max(0, state.boss.hp - b.damage);
burstParticles(state, b.x, b.y, "#fbbf24", 8, 180, 0.4, 2.5);
// BOSS 受击闪光
burstParticles(state, b.x, b.y, "#fb7185", 4, 100, 0.2, 2);
consumed = true;
}
}
if (consumed) {
state.bullets.splice(i, 1);
continue;
}
} else {
// BOSS 子弹 vs 飞船
if (state.invulnTimer <= 0) {
const d = Math.hypot(b.x - ship.x, b.y - ship.y);
if (d < ship.radius + b.radius) {
// 受击
const overdrive = state.activeBuffs.some((bb)=>bb.type === "overdrive");
if (!overdrive) {
const dmg = b.damage * state.upgrades.damageReduceMult;
ship.shield = Math.max(0, ship.shield - dmg);
burstParticles(state, ship.x, ship.y, "#fb7185", 10, 200, 0.4, 3);
triggerShake(state, 10);
state.invulnTimer = effectiveInvulnMs(state);
}
state.bullets.splice(i, 1);
continue;
}
}
}
}
// 移除被子弹击碎的陨石
state.entities = state.entities.filter((e)=>{
if (e.type === "asteroid" && e.damage <= -100) return false;
return true;
});
}
// ============================================================
// 道具更新 + 拾取
// ============================================================
function updatePowerups(state, dt) {
const ship = state.ship;
for(let i = state.powerups.length - 1; i >= 0; i--){
const p = state.powerups[i];
if (p.collected) {
state.powerups.splice(i, 1);
continue;
}
p.life -= dt;
if (p.life <= 0) {
state.powerups.splice(i, 1);
continue;
}
p.rotation += p.rotationSpeed * dt;
p.pulsePhase += dt * 3;
p.x += p.vx * dt;
p.y += p.vy * dt;
// 摩擦衰减
p.vx *= 0.96;
p.vy *= 0.96;
// 边界
p.x = Math.max(p.radius, Math.min(state.worldWidth - p.radius, p.x));
p.y = Math.max(p.radius, Math.min(state.worldHeight - p.radius, p.y));
const d = Math.hypot(ship.x - p.x, ship.y - p.y);
// 吸引半径(受 magnet buff 影响)
const attractR = CRUISE_CONFIG.powerupAttractRadius * (state.activeBuffs.some((b)=>b.type === "magnet") ? 3 : 1);
if (d < attractR) {
const a = Math.atan2(ship.y - p.y, ship.x - p.x);
const pull = (1 - d / attractR) * 380;
p.x += Math.cos(a) * pull * dt;
p.y += Math.sin(a) * pull * dt;
}
// 拾取
if (d < CRUISE_CONFIG.powerupPickupRadius + ship.radius) {
p.collected = true;
applyPowerup(state, p.powerupType);
state.powerups.splice(i, 1);
}
}
}
/** 应用道具效果 */ function applyPowerup(state, type) {
const ship = state.ship;
let color = "#34d399";
switch(type){
case "shield":
ship.shield = Math.min(effectiveShieldMax(state), ship.shield + 30);
color = "#34d399";
burstParticles(state, ship.x, ship.y, color, 18, 220, 0.6, 3);
break;
case "energy":
ship.energy = Math.min(effectiveEnergyMax(state), ship.energy + 50);
color = "#fbbf24";
burstParticles(state, ship.x, ship.y, color, 18, 220, 0.6, 3);
break;
case "rapid":
state.activeBuffs.push({
type: "rapid",
remaining: CRUISE_CONFIG.buffRapidDuration,
total: CRUISE_CONFIG.buffRapidDuration
});
color = "#e879f9";
break;
case "overdrive":
state.activeBuffs.push({
type: "overdrive",
remaining: CRUISE_CONFIG.buffOverdriveDuration,
total: CRUISE_CONFIG.buffOverdriveDuration
});
color = "#fb7185";
break;
case "magnet":
state.activeBuffs.push({
type: "magnet",
remaining: CRUISE_CONFIG.buffMagnetDuration,
total: CRUISE_CONFIG.buffMagnetDuration
});
color = "#a7f3d0";
break;
}
// 屏幕边缘闪光
state.pickupFlash = {
color,
timer: 400
};
state.score += 50;
}
// ============================================================
// Buff 计时
// ============================================================
function updateBuffs(state, dt) {
for(let i = state.activeBuffs.length - 1; i >= 0; i--){
state.activeBuffs[i].remaining -= dt;
if (state.activeBuffs[i].remaining <= 0) state.activeBuffs.splice(i, 1);
}
}
function updateCruise(state, dtMs, input) {
if (state.phase !== "playing") return null;
const dt = Math.min(dtMs / 1000, 0.05); // 限制最大帧间隔,避免卡顿后大跳
state.timeSec += dt;
// 震动衰减
if (state.shakeTimer > 0) {
state.shakeTimer -= dtMs;
if (state.shakeTimer <= 0) {
state.shakeTimer = 0;
state.shakeAmount = 0;
}
}
// 拾取闪光衰减
if (state.pickupFlash) {
state.pickupFlash.timer -= dtMs;
if (state.pickupFlash.timer <= 0) state.pickupFlash = null;
}
// 无敌时间衰减
if (state.invulnTimer > 0) {
state.invulnTimer = Math.max(0, state.invulnTimer - dtMs);
}
// 射击冷却衰减
if (state.shootCooldown > 0) {
state.shootCooldown = Math.max(0, state.shootCooldown - dtMs);
}
// Buff 计时
updateBuffs(state, dt);
const ship = state.ship;
// ---- 飞船控制 ----
if (input.active && (input.dx !== 0 || input.dy !== 0)) {
const mag = Math.hypot(input.dx, input.dy);
const nx = input.dx / mag;
const ny = input.dy / mag;
ship.vx += nx * effectiveShipAccel(state) * dt;
ship.vy += ny * effectiveShipAccel(state) * dt;
ship.heading = Math.atan2(ny, nx);
ship.thrust = Math.min(1, ship.thrust + dt * 4);
// 尾焰粒子
if (Math.random() < 0.9) emitThrustParticle(state, ship);
if (Math.random() < 0.5) emitThrustParticle(state, ship);
} else {
ship.thrust = Math.max(0, ship.thrust - dt * 3);
}
// 摩擦(指数衰减)
const fric = Math.pow(effectiveFriction(state), dt * 60);
ship.vx *= fric;
ship.vy *= fric;
// 限速
const sp = Math.hypot(ship.vx, ship.vy);
const maxSp = effectiveShipMaxSpeed(state);
if (sp > maxSp) {
ship.vx = ship.vx / sp * maxSp;
ship.vy = ship.vy / sp * maxSp;
}
// 位置更新 + 边界反弹
ship.x += ship.vx * dt;
ship.y += ship.vy * dt;
if (ship.x < ship.radius) {
ship.x = ship.radius;
ship.vx = Math.abs(ship.vx) * 0.4;
}
if (ship.x > state.worldWidth - ship.radius) {
ship.x = state.worldWidth - ship.radius;
ship.vx = -Math.abs(ship.vx) * 0.4;
}
if (ship.y < ship.radius) {
ship.y = ship.radius;
ship.vy = Math.abs(ship.vy) * 0.4;
}
if (ship.y > state.worldHeight - ship.radius) {
ship.y = state.worldHeight - ship.radius;
ship.vy = -Math.abs(ship.vy) * 0.4;
}
// ---- 射击输入 ----
if (input.shoot) shootShip(state);
// 护盾恢复(未受击时)
if (state.invulnTimer <= 0 && ship.shield < effectiveShieldMax(state)) {
ship.shield = Math.min(effectiveShieldMax(state), ship.shield + CRUISE_CONFIG.shieldRegen * state.upgrades.shieldRegenMult * dt);
}
// 能量恢复
if (ship.energy < effectiveEnergyMax(state)) {
ship.energy = Math.min(effectiveEnergyMax(state), ship.energy + CRUISE_CONFIG.energyRegen * state.upgrades.energyRegenMult * dt);
}
// 低护盾闪烁标记
state.flashLowShield = ship.shield < effectiveShieldMax(state) * 0.3;
// ---- 实体更新 ----
for (const e of state.entities){
e.x += e.vx * dt;
e.y += e.vy * dt;
switch(e.type){
case "asteroid":
{
e.rotation += e.rotationSpeed * dt;
// 离屏剔除 + 重生
const m = CRUISE_CONFIG.cullMargin;
if (e.x < -m || e.x > state.worldWidth + m || e.y < -m || e.y > state.worldHeight + m) {
// 召唤陨石离屏就消失(不重生)
if (e.summoned) {
e.damage = -999;
break;
}
// 从随机边缘重生,朝场内运动
const edge = Math.floor(Math.random() * 4);
if (edge === 0) {
e.x = -e.radius;
e.y = Math.random() * state.worldHeight;
e.vx = Math.abs(e.vx);
} else if (edge === 1) {
e.x = state.worldWidth + e.radius;
e.y = Math.random() * state.worldHeight;
e.vx = -Math.abs(e.vx);
} else if (edge === 2) {
e.x = Math.random() * state.worldWidth;
e.y = -e.radius;
e.vy = Math.abs(e.vy);
} else {
e.x = Math.random() * state.worldWidth;
e.y = state.worldHeight + e.radius;
e.vy = -Math.abs(e.vy);
}
}
break;
}
case "storm":
{
e.rotation += e.rotationSpeed * dt;
e.lightningTimer -= dt;
if (e.lightningTimer <= 0) {
e.lightningTimer = 0.3 + Math.random() * 0.5;
}
// 风暴边界软反弹
if (e.x < e.radius || e.x > state.worldWidth - e.radius) e.vx *= -1;
if (e.y < e.radius || e.y > state.worldHeight - e.radius) e.vy *= -1;
break;
}
case "crystal":
{
e.rotation += e.rotationSpeed * dt;
e.pulsePhase += dt * 3;
break;
}
case "insight":
{
e.pulsePhase += dt * 2.5;
e.swirlAngle += dt * 1.5;
break;
}
case "beacon":
{
e.rotation += e.rotationSpeed * dt;
e.pulsePhase += dt * 2;
break;
}
case "stargate":
{
e.rotation += e.rotationSpeed * dt;
e.pulsePhase += dt * 2;
const dist = Math.hypot(ship.x - e.x, ship.y - e.y);
e.active = dist < 200;
break;
}
}
}
// 清理被击碎的陨石
state.entities = state.entities.filter((e)=>{
if (e.type === "asteroid" && e.damage <= -100) return false;
return true;
});
// ---- BOSS 更新 ----
if (state.boss) updateBoss(state, dt);
// ---- 子弹更新 ----
updateBullets(state, dt);
// ---- 道具更新 ----
updatePowerups(state, dt);
// ---- 粒子更新 ----
for(let i = state.particles.length - 1; i >= 0; i--){
const p = state.particles[i];
p.life -= dt;
if (p.life <= 0) {
state.particles.splice(i, 1);
continue;
}
p.x += p.vx * dt;
p.y += p.vy * dt;
p.vx *= 0.96;
p.vy *= 0.96;
}
// ---- 碰撞检测 ----
// 飞船 vs 陨石
if (state.invulnTimer <= 0) {
const overdrive = state.activeBuffs.some((b)=>b.type === "overdrive");
for (const e of state.entities){
if (e.type !== "asteroid") continue;
const dist = Math.hypot(ship.x - e.x, ship.y - e.y);
if (dist < ship.radius + e.radius) {
if (!overdrive) {
// 受击
const dmg = e.damage * state.upgrades.damageReduceMult;
ship.shield = Math.max(0, ship.shield - dmg);
}
// 击退
const ang = Math.atan2(ship.y - e.y, ship.x - e.x);
ship.vx += Math.cos(ang) * 200;
ship.vy += Math.sin(ang) * 200;
// 陨石反向
e.vx = -Math.cos(ang) * Math.abs(e.vx) * 0.5;
e.vy = -Math.sin(ang) * Math.abs(e.vy) * 0.5;
// 爆炸粒子
burstParticles(state, ship.x, ship.y, "#fb7185", 18, 260, 0.7, 3.5);
burstParticles(state, ship.x, ship.y, "#fbbf24", 8, 180, 0.5, 2.5);
triggerShake(state, CRUISE_CONFIG.shakeIntensity);
state.invulnTimer = effectiveInvulnMs(state);
break;
}
}
}
// 飞船 vs 风暴(持续伤害)
if (state.invulnTimer <= 0) {
const overdrive = state.activeBuffs.some((b)=>b.type === "overdrive");
for (const e of state.entities){
if (e.type !== "storm") continue;
const dist = Math.hypot(ship.x - e.x, ship.y - e.y);
if (dist < ship.radius + e.radius * 0.7) {
if (!overdrive) {
const dmg = CRUISE_CONFIG.stormDps * dt * state.upgrades.damageReduceMult;
ship.shield = Math.max(0, ship.shield - dmg);
}
// 风暴边缘小粒子
if (Math.random() < 0.3) {
burstParticles(state, ship.x, ship.y, "#e879f9", 2, 100, 0.4, 2);
}
}
}
}
// 飞船 vs BOSS(接触伤害)
if (state.invulnTimer <= 0 && state.boss) {
const overdrive = state.activeBuffs.some((b)=>b.type === "overdrive");
const dist = Math.hypot(ship.x - state.boss.x, ship.y - state.boss.y);
if (dist < ship.radius + state.boss.radius * 0.85) {
if (!overdrive) {
const dmg = CRUISE_CONFIG.bossContactDamage * state.upgrades.damageReduceMult;
ship.shield = Math.max(0, ship.shield - dmg);
}
// 击退
const ang = Math.atan2(ship.y - state.boss.y, ship.x - state.boss.x);
ship.vx += Math.cos(ang) * 280;
ship.vy += Math.sin(ang) * 280;
burstParticles(state, ship.x, ship.y, "#fb7185", 14, 240, 0.5, 3);
triggerShake(state, 16);
state.invulnTimer = effectiveInvulnMs(state);
}
}
// 收集物:吸引 + 收集
const attractR = effectiveAttractRadius(state);
const collectR = effectiveCollectRadius(state);
for (const e of state.entities){
if (e.type === "crystal" || e.type === "insight" || e.type === "beacon") {
if (e.collected) continue;
const dist = Math.hypot(ship.x - e.x, ship.y - e.y);
// 吸引
if (dist < attractR) {
const ang = Math.atan2(ship.y - e.y, ship.x - e.x);
const pull = (1 - dist / attractR) * 320;
e.x += Math.cos(ang) * pull * dt;
e.y += Math.sin(ang) * pull * dt;
}
// 收集
if (dist < collectR) {
e.collected = true;
if (e.type === "crystal") {
state.collectedCrystals++;
state.score += Math.round(100 * state.upgrades.normalScoreMult);
burstParticles(state, e.x, e.y, "#34d399", 10, 200, 0.6, 3);
} else if (e.type === "insight") {
state.collectedInsights++;
state.score += Math.round(250 * state.upgrades.normalScoreMult);
burstParticles(state, e.x, e.y, "#e879f9", 10, 200, 0.6, 3);
} else if (e.type === "beacon") {
state.collectedBeacons++;
state.score += Math.round(500 * state.upgrades.normalScoreMult);
burstParticles(state, e.x, e.y, "#fbbf24", 12, 220, 0.7, 3.5);
// 信标 5% 概率掉落道具
if (!e.powerupDropped && Math.random() < 0.05) {
e.powerupDropped = true;
dropRandomPowerup(state, e.x, e.y, "beacon");
}
}
}
}
}
// ---- 关卡结束判定 ----
// BOSS 关:BOSS HP 归零 → 胜利
if (state.boss && state.boss.hp <= 0 && !state.bossDefeated) {
state.bossDefeated = true;
state.phase = "won";
state.endedAt = Date.now();
// 大爆炸(200+ 粒子)
const bx = state.boss.x;
const by = state.boss.y;
const colors = [
"#fb7185",
"#fbbf24",
"#e879f9",
"#34d399"
];
for(let k = 0; k < 8; k++){
const col = colors[k % colors.length];
burstParticles(state, bx + (Math.random() - 0.5) * 80, by + (Math.random() - 0.5) * 80, col, 28, 360, 1.0, 4);
}
triggerShake(state, 28);
const result = computeRewards(state);
return result;
}
// 普通关卡:星门到达判定
if (!state.isBossLevel) {
for (const e of state.entities){
if (e.type !== "stargate") continue;
const dist = Math.hypot(ship.x - e.x, ship.y - e.y);
if (dist < ship.radius + e.radius * 0.6) {
// 通关!
state.phase = "won";
state.endedAt = Date.now();
// 烟花
for(let k = 0; k < 5; k++){
const cx = state.worldWidth * (0.2 + Math.random() * 0.6);
const cy = state.worldHeight * (0.2 + Math.random() * 0.6);
const colors = [
"#34d399",
"#fb7185",
"#fbbf24",
"#e879f9"
];
const col = colors[k % colors.length];
burstParticles(state, cx, cy, col, 24, 320, 1.0, 4);
}
const result = computeRewards(state);
return result;
}
}
}
// 护盾归零 → 失败
if (ship.shield <= 0) {
state.phase = "lost";
state.endedAt = Date.now();
// 大爆炸
burstParticles(state, ship.x, ship.y, "#fb7185", 30, 360, 1.0, 4.5);
burstParticles(state, ship.x, ship.y, "#fbbf24", 16, 240, 0.8, 3);
triggerShake(state, 24);
const result = computeRewards(state);
return result;
}
// 时间耗尽 → 失败
if (state.timeSec >= state.durationSec) {
state.phase = "lost";
state.endedAt = Date.now();
const result = computeRewards(state);
return result;
}
return null;
}
function computeRewards(state) {
const level = state.level;
const baseCrystals = state.collectedCrystals * (8 + level * 2);
const baseInsights = state.collectedInsights * (2 + level * 0.5);
const baseContact = state.collectedBeacons * (1.5 + level * 0.3);
let mult = 1;
if (state.phase === "won") {
mult = state.isBossLevel ? 3 : 1.5;
if (state.isBossLevel) mult *= state.upgrades.bossBonusMult;
} else if (state.phase === "lost") {
mult = 0.5;
}
const rewards = {
crystals: Math.round(baseCrystals * mult),
insights: Math.round(baseInsights * mult * 10) / 10,
contact: Math.round(baseContact * mult * 10) / 10
};
// 综合得分(用于排行榜/统计)
const timeBonus = Math.max(0, 1000 - state.timeSec * 5);
const shieldBonus = Math.round(state.ship.shield * 10);
const winBonus = state.phase === "won" ? state.isBossLevel ? 5000 : 2000 : 0;
const score = state.score + timeBonus + shieldBonus + winBonus + level * 500;
return {
level,
phase: state.phase,
isBossLevel: state.isBossLevel,
durationSec: Math.round(state.timeSec * 10) / 10,
collectedCrystals: state.collectedCrystals,
collectedInsights: state.collectedInsights,
collectedBeacons: state.collectedBeacons,
remainingShield: Math.round(state.ship.shield),
score: Math.round(score),
rewards,
timestamp: Date.now()
};
}
// ============================================================
// localStorage 持久化(独立 key,不污染 GameState
// ============================================================
const STORAGE_KEY = "echo-nexus-cruise-v1";
function emptyStats() {
return {
highScore: 0,
totalRuns: 0,
totalWins: 0,
bestLevel: 0,
totalCrystals: 0,
totalInsights: 0,
totalContact: 0,
bossKills: 0,
lastResult: null,
recentResults: []
};
}
function loadCruiseStats() {
if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable
;
try {
const raw = window.localStorage.getItem(STORAGE_KEY);
if (!raw) return emptyStats();
const parsed = JSON.parse(raw);
return {
...emptyStats(),
...parsed,
recentResults: Array.isArray(parsed.recentResults) ? parsed.recentResults.slice(0, 20) : []
};
} catch {
return emptyStats();
}
}
function saveCruiseStats(stats) {
if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable
;
try {
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(stats));
} catch {
// 忽略写入失败(隐私模式 / 配额满)
}
}
function recordRun(result) {
const stats = loadCruiseStats();
stats.totalRuns++;
if (result.phase === "won") {
stats.totalWins++;
stats.bestLevel = Math.max(stats.bestLevel, result.level);
if (result.isBossLevel) stats.bossKills++;
}
stats.highScore = Math.max(stats.highScore, result.score);
stats.totalCrystals += result.rewards.crystals;
stats.totalInsights += result.rewards.insights;
stats.totalContact += result.rewards.contact;
stats.lastResult = result;
stats.recentResults = [
result,
...stats.recentResults
].slice(0, 20);
saveCruiseStats(stats);
return stats;
}
function resetCruiseStats() {
const empty = emptyStats();
saveCruiseStats(empty);
return empty;
}
if (typeof globalThis.$RefreshHelpers$ === 'object' && globalThis.$RefreshHelpers !== null) {
__turbopack_context__.k.registerExports(__turbopack_context__.m, globalThis.$RefreshHelpers$);
}
}),
"[project]/src/components/game/CruiseMode.tsx [app-client] (ecmascript) <locals>", ((__turbopack_context__) => {
"use strict";
__turbopack_context__.s([
"CruiseMode",
()=>CruiseMode
]);
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/next/dist/compiled/react/jsx-dev-runtime.js [app-client] (ecmascript)");
// 回响星核 / Echo Nexus — 深空巡航 Canvas 2D 实时玩法渲染层 (v0.8)
// v0.8 新增:BOSS 战 / 飞船射击 / 道具掉落 / 事件选择节点
// 全屏 fixed 覆盖,rAF 驱动游戏循环,HTML HUD 叠层 + Canvas 实体绘制。
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/next/dist/compiled/react/index.js [app-client] (ecmascript)");
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/components/ui/button.tsx [app-client] (ecmascript)");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$x$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__X$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/x.js [app-client] (ecmascript) <export default as X>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$play$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Play$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/play.js [app-client] (ecmascript) <export default as Play>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$rotate$2d$ccw$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__RotateCcw$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/rotate-ccw.js [app-client] (ecmascript) <export default as RotateCcw>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$chevron$2d$right$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__ChevronRight$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/chevron-right.js [app-client] (ecmascript) <export default as ChevronRight>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$pause$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Pause$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/pause.js [app-client] (ecmascript) <export default as Pause>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$gem$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Gem$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/gem.js [app-client] (ecmascript) <export default as Gem>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$brain$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Brain$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/brain.js [app-client] (ecmascript) <export default as Brain>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$radio$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Radio$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/radio.js [app-client] (ecmascript) <export default as Radio>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$shield$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Shield$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/shield.js [app-client] (ecmascript) <export default as Shield>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$zap$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Zap$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/zap.js [app-client] (ecmascript) <export default as Zap>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$clock$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Clock$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/clock.js [app-client] (ecmascript) <export default as Clock>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$trophy$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Trophy$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/trophy.js [app-client] (ecmascript) <export default as Trophy>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$crosshair$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Crosshair$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/crosshair.js [app-client] (ecmascript) <export default as Crosshair>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$skull$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Skull$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/skull.js [app-client] (ecmascript) <export default as Skull>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$sparkles$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Sparkles$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/sparkles.js [app-client] (ecmascript) <export default as Sparkles>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$wind$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Wind$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/wind.js [app-client] (ecmascript) <export default as Wind>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$gauge$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Gauge$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/gauge.js [app-client] (ecmascript) <export default as Gauge>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$feather$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Feather$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/feather.js [app-client] (ecmascript) <export default as Feather>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$heart$2d$pulse$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__HeartPulse$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/heart-pulse.js [app-client] (ecmascript) <export default as HeartPulse>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$battery$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Battery$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/battery.js [app-client] (ecmascript) <export default as Battery>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$timer$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Timer$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/timer.js [app-client] (ecmascript) <export default as Timer>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$flame$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Flame$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/flame.js [app-client] (ecmascript) <export default as Flame>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$split$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Split$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/split.js [app-client] (ecmascript) <export default as Split>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$magnet$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Magnet$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/magnet.js [app-client] (ecmascript) <export default as Magnet>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$circle$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Circle$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/circle.js [app-client] (ecmascript) <export default as Circle>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$shield$2d$check$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__ShieldCheck$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/shield-check.js [app-client] (ecmascript) <export default as ShieldCheck>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$shield$2d$half$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__ShieldHalf$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/shield-half.js [app-client] (ecmascript) <export default as ShieldHalf>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$crown$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Crown$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/crown.js [app-client] (ecmascript) <export default as Crown>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$star$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Star$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/star.js [app-client] (ecmascript) <export default as Star>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$shield$2d$plus$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__ShieldPlus$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/shield-plus.js [app-client] (ecmascript) <export default as ShieldPlus>");
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$battery$2d$charging$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__BatteryCharging$3e$__ = __turbopack_context__.i("[project]/node_modules/lucide-react/dist/esm/icons/battery-charging.js [app-client] (ecmascript) <export default as BatteryCharging>");
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/cruise.ts [app-client] (ecmascript)");
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__ = __turbopack_context__.i("[project]/src/store/gameStore.ts [app-client] (ecmascript) <locals>");
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/config.ts [app-client] (ecmascript)");
;
var _s = __turbopack_context__.k.signature();
"use client";
;
;
;
;
;
;
// ============================================================
// 颜色常量(避开蓝色/靛色,使用 emerald/rose/amber/fuchsia 四色全息色谱)
// ============================================================
const C = {
ship: "#34d399",
shipCore: "#a7f3d0",
asteroid: "#3a2a2a",
asteroidStroke: "#7f1d1d",
asteroidGlow: "#fb7185",
storm: "#e879f9",
stormCore: "#fdf4ff",
crystal: "#34d399",
crystalCore: "#d1fae5",
insight: "#e879f9",
insightCore: "#fae8ff",
beacon: "#fbbf24",
beaconCore: "#fef3c7",
stargate: "#fb7185",
stargateCore: "#ffe4e6",
boss: "#fb7185",
bossGlow: "#e879f9",
bossCore: "#ffe4e6",
shipBullet: "#34d399",
bossBullet: "#fb7185",
homingBullet: "#e879f9"
};
// 道具颜色
const POWERUP_COLOR = {
shield: "#34d399",
energy: "#fbbf24",
rapid: "#e879f9",
overdrive: "#fb7185",
magnet: "#a7f3d0"
};
// 道具图标 key → lucide 组件
const POWERUP_ICON_KEY = {
shield: "Shield",
energy: "Zap",
rapid: "Timer",
overdrive: "Flame",
magnet: "Magnet"
};
// 升级卡图标 key → lucide
const UPGRADE_ICON_MAP = {
Wind: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$wind$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Wind$3e$__["Wind"],
Gauge: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$gauge$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Gauge$3e$__["Gauge"],
Feather: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$feather$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Feather$3e$__["Feather"],
Shield: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$shield$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Shield$3e$__["Shield"],
HeartPulse: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$heart$2d$pulse$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__HeartPulse$3e$__["HeartPulse"],
Battery: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$battery$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Battery$3e$__["Battery"],
Zap: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$zap$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Zap$3e$__["Zap"],
Flame: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$flame$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Flame$3e$__["Flame"],
Timer: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$timer$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Timer$3e$__["Timer"],
Split: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$split$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Split$3e$__["Split"],
Magnet: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$magnet$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Magnet$3e$__["Magnet"],
Circle: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$circle$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Circle$3e$__["Circle"],
ShieldCheck: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$shield$2d$check$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__ShieldCheck$3e$__["ShieldCheck"],
ShieldHalf: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$shield$2d$half$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__ShieldHalf$3e$__["ShieldHalf"],
Crown: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$crown$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Crown$3e$__["Crown"],
Star: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$star$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Star$3e$__["Star"],
ShieldPlus: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$shield$2d$plus$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__ShieldPlus$3e$__["ShieldPlus"],
BatteryCharging: __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$battery$2d$charging$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__BatteryCharging$3e$__["BatteryCharging"]
};
function generateStars(w, h) {
const layers = [
{
stars: [],
speed: 8,
parallax: 0.1
},
{
stars: [],
speed: 18,
parallax: 0.25
},
{
stars: [],
speed: 36,
parallax: 0.5
}
];
const counts = [
100,
60,
30
];
for(let li = 0; li < layers.length; li++){
const layer = layers[li];
for(let i = 0; i < counts[li]; i++){
layer.stars.push({
x: Math.random() * w,
y: Math.random() * h,
size: 0.5 + li * 0.6 + Math.random() * (0.5 + li * 0.5),
brightness: 0.2 + li * 0.25 + Math.random() * 0.25,
twinkle: Math.random() * Math.PI * 2,
twinkleSpeed: 0.5 + Math.random() * 2
});
}
}
return layers;
}
function drawStars(ctx, layers, dt, w, h, shipVx, shipVy) {
for (const layer of layers){
for (const s of layer.stars){
// 向下漂移 + 受飞船速度影响的视差
s.y += (layer.speed + shipVy * layer.parallax) * dt;
s.x -= shipVx * layer.parallax * dt;
// 环绕
if (s.y > h + 5) s.y = -5;
if (s.y < -5) s.y = h + 5;
if (s.x > w + 5) s.x = -5;
if (s.x < -5) s.x = w + 5;
s.twinkle += s.twinkleSpeed * dt;
const tw = 0.6 + 0.4 * Math.sin(s.twinkle);
const alpha = s.brightness * tw;
ctx.fillStyle = `rgba(220,230,255,${alpha})`;
ctx.beginPath();
ctx.arc(s.x, s.y, s.size, 0, Math.PI * 2);
ctx.fill();
}
}
}
// ============================================================
// 实体绘制函数
// ============================================================
function drawShip(ctx, ship, invuln, buffs) {
ctx.save();
ctx.translate(ship.x, ship.y);
// buff 光环(在飞船下层)
if (buffs.length > 0) {
for (const buff of buffs){
const color = POWERUP_COLOR[buff.type];
const pct = buff.remaining / buff.total;
const r = ship.radius * (1.6 + 0.2 * Math.sin(Date.now() / 200));
ctx.beginPath();
ctx.arc(0, 0, r, 0, Math.PI * 2);
ctx.strokeStyle = `${color}${Math.round(pct * 200).toString(16).padStart(2, "0")}`;
ctx.lineWidth = 2;
ctx.stroke();
// 进度弧
ctx.beginPath();
ctx.arc(0, 0, r + 3, -Math.PI / 2, -Math.PI / 2 + Math.PI * 2 * pct);
ctx.strokeStyle = color;
ctx.lineWidth = 1.5;
ctx.stroke();
}
}
ctx.rotate(ship.heading);
// 受击闪烁
const blink = invuln && Math.floor(Date.now() / 80) % 2 === 0;
// 尾焰(在飞船后方)
if (ship.thrust > 0.1) {
const flameLen = ship.radius * (1.5 + ship.thrust * 1.5);
const grad = ctx.createLinearGradient(-ship.radius * 0.4, 0, -flameLen, 0);
grad.addColorStop(0, `rgba(251,191,36,${0.8 * ship.thrust})`);
grad.addColorStop(0.5, `rgba(232,121,249,${0.4 * ship.thrust})`);
grad.addColorStop(1, "rgba(232,121,249,0)");
ctx.fillStyle = grad;
ctx.beginPath();
ctx.moveTo(-ship.radius * 0.4, ship.radius * 0.4);
ctx.lineTo(-flameLen, 0);
ctx.lineTo(-ship.radius * 0.4, -ship.radius * 0.4);
ctx.closePath();
ctx.fill();
}
// 飞船辉光
ctx.shadowBlur = 22;
ctx.shadowColor = C.ship;
// 飞船主体(三角形)
const r = ship.radius;
ctx.beginPath();
ctx.moveTo(r, 0);
ctx.lineTo(-r * 0.7, r * 0.75);
ctx.lineTo(-r * 0.35, 0);
ctx.lineTo(-r * 0.7, -r * 0.75);
ctx.closePath();
const bodyGrad = ctx.createLinearGradient(-r, 0, r, 0);
bodyGrad.addColorStop(0, blink ? "#fb7185" : "#065f46");
bodyGrad.addColorStop(0.5, blink ? "#fda4af" : C.ship);
bodyGrad.addColorStop(1, blink ? "#fecdd3" : C.shipCore);
ctx.fillStyle = bodyGrad;
ctx.fill();
ctx.shadowBlur = 0;
ctx.lineWidth = 1.5;
ctx.strokeStyle = blink ? "#ffe4e6" : "#d1fae5";
ctx.stroke();
// 驾驶舱
ctx.beginPath();
ctx.arc(r * 0.15, 0, r * 0.22, 0, Math.PI * 2);
ctx.fillStyle = "rgba(255,255,255,0.85)";
ctx.fill();
ctx.restore();
}
function drawAsteroid(ctx, a) {
ctx.save();
ctx.translate(a.x, a.y);
ctx.rotate(a.rotation);
ctx.shadowBlur = 14;
ctx.shadowColor = C.asteroidGlow;
ctx.beginPath();
const n = a.vertices.length;
for(let i = 0; i < n; i++){
const ang = i / n * Math.PI * 2;
const rad = a.radius * a.vertices[i];
const x = Math.cos(ang) * rad;
const y = Math.sin(ang) * rad;
if (i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.closePath();
const grad = ctx.createRadialGradient(0, 0, a.radius * 0.2, 0, 0, a.radius);
grad.addColorStop(0, "#5a3a3a");
grad.addColorStop(0.7, C.asteroid);
grad.addColorStop(1, "#1a0808");
ctx.fillStyle = grad;
ctx.fill();
ctx.shadowBlur = 0;
ctx.lineWidth = 1.2;
ctx.strokeStyle = C.asteroidStroke;
ctx.stroke();
// 内部裂纹
ctx.beginPath();
ctx.moveTo(-a.radius * 0.3, -a.radius * 0.2);
ctx.lineTo(a.radius * 0.2, a.radius * 0.3);
ctx.strokeStyle = "rgba(127,29,29,0.5)";
ctx.lineWidth = 1;
ctx.stroke();
ctx.restore();
}
function drawStorm(ctx, s) {
ctx.save();
ctx.translate(s.x, s.y);
ctx.shadowBlur = 30;
ctx.shadowColor = C.storm;
// 多层云团
const cloudCount = 5;
for(let i = 0; i < cloudCount; i++){
const ang = i / cloudCount * Math.PI * 2 + s.rotation;
const dist = s.radius * 0.4 * (0.5 + 0.5 * Math.sin(s.cloudSeed + i));
const cx = Math.cos(ang) * dist;
const cy = Math.sin(ang) * dist;
const cr = s.radius * (0.5 + 0.2 * Math.sin(s.cloudSeed * 0.7 + i * 2));
const grad = ctx.createRadialGradient(cx, cy, 0, cx, cy, cr);
grad.addColorStop(0, "rgba(232,121,249,0.55)");
grad.addColorStop(0.6, "rgba(168,85,247,0.3)");
grad.addColorStop(1, "rgba(88,28,135,0)");
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(cx, cy, cr, 0, Math.PI * 2);
ctx.fill();
}
// 核心
ctx.shadowBlur = 0;
const coreGrad = ctx.createRadialGradient(0, 0, 0, 0, 0, s.radius * 0.3);
coreGrad.addColorStop(0, "rgba(253,244,255,0.8)");
coreGrad.addColorStop(1, "rgba(232,121,249,0)");
ctx.fillStyle = coreGrad;
ctx.beginPath();
ctx.arc(0, 0, s.radius * 0.3, 0, Math.PI * 2);
ctx.fill();
// 闪电
if (s.lightningTimer < 0.12) {
ctx.strokeStyle = "rgba(253,244,255,0.9)";
ctx.lineWidth = 2;
ctx.shadowBlur = 12;
ctx.shadowColor = C.stormCore;
ctx.beginPath();
let lx = 0, ly = 0;
ctx.moveTo(lx, ly);
for(let i = 0; i < 4; i++){
lx += (Math.random() - 0.5) * s.radius * 0.5;
ly += (Math.random() - 0.5) * s.radius * 0.5;
ctx.lineTo(lx, ly);
}
ctx.stroke();
}
ctx.restore();
}
function drawCrystal(ctx, c) {
if (c.collected) return;
ctx.save();
ctx.translate(c.x, c.y);
// 脉冲光环
const pulse = 0.5 + 0.5 * Math.sin(c.pulsePhase);
ctx.shadowBlur = 20;
ctx.shadowColor = C.crystal;
ctx.beginPath();
ctx.arc(0, 0, c.radius * (1.4 + pulse * 0.4), 0, Math.PI * 2);
ctx.strokeStyle = `rgba(52,211,153,${0.15 + pulse * 0.2})`;
ctx.lineWidth = 2;
ctx.stroke();
// 菱形
ctx.rotate(c.rotation);
ctx.beginPath();
ctx.moveTo(0, -c.radius);
ctx.lineTo(c.radius * 0.7, 0);
ctx.lineTo(0, c.radius);
ctx.lineTo(-c.radius * 0.7, 0);
ctx.closePath();
const grad = ctx.createLinearGradient(-c.radius, -c.radius, c.radius, c.radius);
grad.addColorStop(0, "#065f46");
grad.addColorStop(0.5, C.crystal);
grad.addColorStop(1, C.crystalCore);
ctx.fillStyle = grad;
ctx.fill();
ctx.shadowBlur = 0;
ctx.lineWidth = 1.2;
ctx.strokeStyle = C.crystalCore;
ctx.stroke();
// 高光
ctx.beginPath();
ctx.moveTo(0, -c.radius * 0.7);
ctx.lineTo(c.radius * 0.3, -c.radius * 0.2);
ctx.strokeStyle = "rgba(255,255,255,0.6)";
ctx.lineWidth = 1;
ctx.stroke();
ctx.restore();
}
function drawInsight(ctx, i) {
if (i.collected) return;
ctx.save();
ctx.translate(i.x, i.y);
const pulse = 0.5 + 0.5 * Math.sin(i.pulsePhase);
ctx.shadowBlur = 22;
ctx.shadowColor = C.insight;
// 外光环
ctx.beginPath();
ctx.arc(0, 0, i.radius * (1.3 + pulse * 0.3), 0, Math.PI * 2);
ctx.strokeStyle = `rgba(232,121,249,${0.2 + pulse * 0.2})`;
ctx.lineWidth = 2;
ctx.stroke();
// 球体
const grad = ctx.createRadialGradient(-i.radius * 0.3, -i.radius * 0.3, 0, 0, 0, i.radius);
grad.addColorStop(0, C.insightCore);
grad.addColorStop(0.5, C.insight);
grad.addColorStop(1, "#86198f");
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(0, 0, i.radius, 0, Math.PI * 2);
ctx.fill();
// 内部漩涡
ctx.shadowBlur = 0;
ctx.rotate(i.swirlAngle);
ctx.strokeStyle = "rgba(253,244,255,0.7)";
ctx.lineWidth = 1.5;
ctx.beginPath();
for(let t = 0; t < Math.PI * 2; t += 0.3){
const r = t / (Math.PI * 2) * i.radius * 0.8;
const x = Math.cos(t * 2) * r;
const y = Math.sin(t * 2) * r;
if (t === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.stroke();
ctx.restore();
}
function drawBeacon(ctx, b) {
if (b.collected) return;
ctx.save();
ctx.translate(b.x, b.y);
const pulse = 0.5 + 0.5 * Math.sin(b.pulsePhase);
ctx.shadowBlur = 25;
ctx.shadowColor = C.beacon;
// 立柱光束(向上)
const beamGrad = ctx.createLinearGradient(0, -b.radius * 4, 0, b.radius);
beamGrad.addColorStop(0, "rgba(251,191,36,0)");
beamGrad.addColorStop(0.5, `rgba(251,191,36,${0.3 + pulse * 0.2})`);
beamGrad.addColorStop(1, `rgba(251,191,36,${0.5 + pulse * 0.3})`);
ctx.fillStyle = beamGrad;
ctx.beginPath();
ctx.moveTo(-b.radius * 0.5, 0);
ctx.lineTo(-b.radius * 0.2, -b.radius * 4);
ctx.lineTo(b.radius * 0.2, -b.radius * 4);
ctx.lineTo(b.radius * 0.5, 0);
ctx.closePath();
ctx.fill();
// 旋转光环
ctx.rotate(b.rotation);
ctx.beginPath();
ctx.ellipse(0, 0, b.radius * (1.2 + pulse * 0.2), b.radius * 0.4, 0, 0, Math.PI * 2);
ctx.strokeStyle = `rgba(251,191,36,${0.5 + pulse * 0.3})`;
ctx.lineWidth = 2;
ctx.stroke();
// 核心
ctx.shadowBlur = 0;
const coreGrad = ctx.createRadialGradient(0, 0, 0, 0, 0, b.radius * 0.6);
coreGrad.addColorStop(0, C.beaconCore);
coreGrad.addColorStop(0.7, C.beacon);
coreGrad.addColorStop(1, "#92400e");
ctx.fillStyle = coreGrad;
ctx.beginPath();
ctx.arc(0, 0, b.radius * 0.6, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
}
function drawStargate(ctx, g, ship) {
ctx.save();
ctx.translate(g.x, g.y);
const dist = Math.hypot(ship.x - g.x, ship.y - g.y);
const proximity = Math.max(0, 1 - dist / 300);
const pulse = 0.5 + 0.5 * Math.sin(g.pulsePhase);
ctx.shadowBlur = 25 + proximity * 30;
ctx.shadowColor = C.stargate;
// 外旋涡(多层旋转弧)
for(let i = 0; i < 4; i++){
ctx.save();
ctx.rotate(g.rotation * (i % 2 === 0 ? 1 : -1) * (1 + i * 0.3));
ctx.beginPath();
const ringR = g.radius * (1 + i * 0.25);
ctx.arc(0, 0, ringR, 0, Math.PI * 1.5);
ctx.strokeStyle = `rgba(251,113,133,${(0.3 + pulse * 0.2) * (1 - i * 0.15)})`;
ctx.lineWidth = 3 - i * 0.5;
ctx.stroke();
ctx.restore();
}
// 核心旋涡
const coreGrad = ctx.createRadialGradient(0, 0, 0, 0, 0, g.radius);
coreGrad.addColorStop(0, C.stargateCore);
coreGrad.addColorStop(0.4, C.stargate);
coreGrad.addColorStop(0.8, "#9f1239");
coreGrad.addColorStop(1, "rgba(159,18,57,0)");
ctx.fillStyle = coreGrad;
ctx.beginPath();
ctx.arc(0, 0, g.radius * (0.9 + pulse * 0.1), 0, Math.PI * 2);
ctx.fill();
// 吸入粒子(接近时)
ctx.shadowBlur = 0;
if (proximity > 0.1) {
for(let i = 0; i < 8; i++){
const ang = g.rotation * 2 + i / 8 * Math.PI * 2;
const r = g.radius * (0.8 + 0.6 * Math.sin(g.pulsePhase + i));
const px = Math.cos(ang) * r;
const py = Math.sin(ang) * r;
ctx.fillStyle = `rgba(254,205,211,${proximity * 0.8})`;
ctx.beginPath();
ctx.arc(px, py, 2, 0, Math.PI * 2);
ctx.fill();
}
}
// 提示光环(接近时)
if (proximity > 0.3) {
ctx.beginPath();
ctx.arc(0, 0, g.radius * 1.6, 0, Math.PI * 2);
ctx.strokeStyle = `rgba(251,113,133,${proximity * 0.4})`;
ctx.lineWidth = 2;
ctx.setLineDash([
8,
8
]);
ctx.stroke();
ctx.setLineDash([]);
}
ctx.restore();
}
function drawParticle(ctx, p) {
const alpha = Math.max(0, p.life / p.maxLife);
const size = p.shrink ? p.size * alpha : p.size;
if (size < 0.3) return;
ctx.globalAlpha = alpha;
ctx.fillStyle = p.color;
ctx.beginPath();
ctx.arc(p.x, p.y, size, 0, Math.PI * 2);
ctx.fill();
ctx.globalAlpha = 1;
}
// ============================================================
// BOSS 绘制
// ============================================================
function drawBoss(ctx, b) {
ctx.save();
ctx.translate(b.x, b.y);
const breath = 1 + 0.06 * Math.sin(b.breathPhase);
const pulse = 0.5 + 0.5 * Math.sin(b.pulsePhase);
// 阶段颜色(rose 主色 + fuchsia 辉光)
const phaseColor = b.attackPhase === 1 ? "#fb7185" : b.attackPhase === 2 ? "#f43f5e" : "#e879f9";
ctx.shadowBlur = 40;
ctx.shadowColor = C.bossGlow;
// 外层旋转环(多层)
for(let i = 0; i < 3; i++){
ctx.save();
ctx.rotate(b.rotation * (i % 2 === 0 ? 1 : -1) * (1 + i * 0.4));
ctx.beginPath();
const ringR = b.radius * (1.15 + i * 0.18) * breath;
const segs = 24;
for(let s = 0; s < segs; s++){
const a = s / segs * Math.PI * 2;
const r = ringR + Math.sin(b.pulsePhase * 2 + s * 0.6) * 4;
const x = Math.cos(a) * r;
const y = Math.sin(a) * r;
if (s === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.closePath();
ctx.strokeStyle = `${phaseColor}${i === 0 ? "cc" : "66"}`;
ctx.lineWidth = 3 - i * 0.6;
ctx.stroke();
ctx.restore();
}
// 触手 / 光环(旋转的光带)
ctx.save();
ctx.rotate(b.tentaclePhase);
for(let i = 0; i < 6; i++){
ctx.save();
ctx.rotate(i / 6 * Math.PI * 2);
ctx.beginPath();
const tlen = b.radius * 1.4;
ctx.moveTo(b.radius * 0.6, 0);
ctx.quadraticCurveTo(b.radius * 1.1 + Math.sin(b.tentaclePhase * 2 + i) * 10, Math.cos(b.pulsePhase + i) * 8, tlen, 0);
ctx.strokeStyle = `rgba(232,121,249,${0.5 + 0.3 * pulse})`;
ctx.lineWidth = 2.5;
ctx.stroke();
// 触手尖端光点
ctx.fillStyle = "#fda4af";
ctx.beginPath();
ctx.arc(tlen, 0, 3, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
}
ctx.restore();
// 内核(径向渐变)
ctx.shadowBlur = 30;
ctx.shadowColor = phaseColor;
const coreGrad = ctx.createRadialGradient(0, 0, 0, 0, 0, b.radius * 0.85);
coreGrad.addColorStop(0, "#ffffff");
coreGrad.addColorStop(0.2, C.bossCore);
coreGrad.addColorStop(0.6, phaseColor);
coreGrad.addColorStop(1, "#9f1239");
ctx.fillStyle = coreGrad;
ctx.beginPath();
ctx.arc(0, 0, b.radius * 0.85 * breath, 0, Math.PI * 2);
ctx.fill();
// 内部六边形纹理(旋转)
ctx.shadowBlur = 0;
ctx.save();
ctx.rotate(-b.rotation * 2);
ctx.beginPath();
for(let i = 0; i < 6; i++){
const a = i / 6 * Math.PI * 2;
const r = b.radius * 0.55;
const x = Math.cos(a) * r;
const y = Math.sin(a) * r;
if (i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.closePath();
ctx.strokeStyle = `rgba(254,205,211,${0.6 + 0.2 * pulse})`;
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
// 阶段标记(小圆点)
ctx.save();
ctx.rotate(-b.rotation * 1.5);
for(let i = 0; i < 3; i++){
const a = i / 3 * Math.PI * 2 - Math.PI / 2;
const r = b.radius * 0.7;
const x = Math.cos(a) * r;
const y = Math.sin(a) * r;
ctx.fillStyle = i < b.attackPhase ? "#fbbf24" : "rgba(255,255,255,0.2)";
ctx.beginPath();
ctx.arc(x, y, 3, 0, Math.PI * 2);
ctx.fill();
}
ctx.restore();
ctx.restore();
}
// ============================================================
// 子弹绘制
// ============================================================
function drawBullet(ctx, b) {
ctx.save();
ctx.translate(b.x, b.y);
const ang = Math.atan2(b.vy, b.vx);
ctx.rotate(ang);
ctx.shadowBlur = 14;
ctx.shadowColor = b.color;
if (b.owner === "ship") {
// 飞船子弹:emerald 椭圆 + 尾焰
const grad = ctx.createLinearGradient(-b.radius * 3, 0, b.radius, 0);
grad.addColorStop(0, "rgba(52,211,153,0)");
grad.addColorStop(0.5, "rgba(52,211,153,0.6)");
grad.addColorStop(1, "#a7f3d0");
ctx.fillStyle = grad;
ctx.beginPath();
ctx.ellipse(0, 0, b.radius * 1.8, b.radius * 0.8, 0, 0, Math.PI * 2);
ctx.fill();
// 核心亮点
ctx.fillStyle = "#ffffff";
ctx.beginPath();
ctx.arc(b.radius * 0.6, 0, b.radius * 0.4, 0, Math.PI * 2);
ctx.fill();
} else {
// BOSS 子弹:rose / fuchsia 圆球 + 拖尾
const grad = ctx.createRadialGradient(0, 0, 0, 0, 0, b.radius);
if (b.homing) {
grad.addColorStop(0, "#fdf4ff");
grad.addColorStop(0.6, "#e879f9");
grad.addColorStop(1, "#86198f");
} else {
grad.addColorStop(0, "#ffe4e6");
grad.addColorStop(0.6, "#fb7185");
grad.addColorStop(1, "#9f1239");
}
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(0, 0, b.radius, 0, Math.PI * 2);
ctx.fill();
// 拖尾
ctx.shadowBlur = 0;
ctx.fillStyle = `${b.color}55`;
ctx.beginPath();
ctx.ellipse(-b.radius * 2, 0, b.radius * 2, b.radius * 0.5, 0, 0, Math.PI * 2);
ctx.fill();
// 追踪弹旋转标记
if (b.homing) {
ctx.rotate(Date.now() / 100);
ctx.strokeStyle = "#fdf4ff";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.arc(0, 0, b.radius * 1.3, 0, Math.PI * 1.5);
ctx.stroke();
}
}
ctx.restore();
}
// ============================================================
// 道具绘制
// ============================================================
function drawPowerup(ctx, p) {
if (p.collected) return;
ctx.save();
ctx.translate(p.x, p.y);
const pulse = 0.5 + 0.5 * Math.sin(p.pulsePhase);
// 即将消失闪烁
const blink = p.life < 3 && Math.floor(Date.now() / 150) % 2 === 0;
if (blink) ctx.globalAlpha = 0.5;
const color = POWERUP_COLOR[p.powerupType];
ctx.shadowBlur = 22;
ctx.shadowColor = color;
// 外发光环
ctx.beginPath();
ctx.arc(0, 0, p.radius * (1.5 + pulse * 0.3), 0, Math.PI * 2);
ctx.strokeStyle = `${color}40`;
ctx.lineWidth = 2;
ctx.stroke();
// 旋转六边形
ctx.rotate(p.rotation);
ctx.beginPath();
for(let i = 0; i < 6; i++){
const a = i / 6 * Math.PI * 2;
const r = p.radius;
const x = Math.cos(a) * r;
const y = Math.sin(a) * r;
if (i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.closePath();
const grad = ctx.createRadialGradient(0, 0, 0, 0, 0, p.radius);
grad.addColorStop(0, "#ffffff");
grad.addColorStop(0.5, color);
grad.addColorStop(1, `${color}80`);
ctx.fillStyle = grad;
ctx.fill();
ctx.lineWidth = 1.5;
ctx.strokeStyle = "#ffffffaa";
ctx.stroke();
// 内部图标(用文字符号代替 lucide,避免 React-Canvas 桥接)
ctx.shadowBlur = 0;
ctx.rotate(-p.rotation);
ctx.fillStyle = "#ffffff";
ctx.font = "bold 12px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const sym = p.powerupType === "shield" ? "S" : p.powerupType === "energy" ? "E" : p.powerupType === "rapid" ? "R" : p.powerupType === "overdrive" ? "O" : "M";
ctx.fillText(sym, 0, 1);
ctx.globalAlpha = 1;
ctx.restore();
}
function CruiseMode({ onClose }) {
_s();
const canvasRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(null);
const stateRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(null);
const upgradesRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])((0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["defaultUpgrades"])());
const appliedUpgradesRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])([]);
const rafRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(0);
const lastTimeRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(0);
const starsRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])([]);
const keysRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(new Set());
const joystickRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])({
active: false,
baseX: 0,
baseY: 0,
knobX: 0,
knobY: 0,
touchId: null
});
const shootHeldRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(false);
const rewardGrantedRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(false);
const pausedRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(false);
const phaseRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])("ready");
const lastResultRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(null);
const hudRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])({
shield: 100,
shieldMax: 100,
energy: 100,
energyMax: 100,
score: 0,
time: 0,
duration: 60,
crystals: 0,
totalCrystals: 0,
insights: 0,
totalInsights: 0,
beacons: 0,
totalBeacons: 0,
lowShield: false,
isBossLevel: false,
bossHp: 0,
bossMaxHp: 0,
bossPhase: 1,
buffs: [],
appliedUpgrades: [],
pickupFlashColor: null
});
const lastHudUpdateRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])(0);
const sizeRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useRef"])({
w: 0,
h: 0
});
const [phase, setPhase] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useState"])("ready");
const [level, setLevel] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useState"])(1);
const [result, setResult] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useState"])(null);
const [stats, setStats] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useState"])({
"CruiseMode.useState": ()=>("TURBOPACK compile-time truthy", 1) ? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["loadCruiseStats"])() : "TURBOPACK unreachable"
}["CruiseMode.useState"]);
const [paused, setPaused] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useState"])(false);
const [isTouch] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useState"])({
"CruiseMode.useState": ()=>("TURBOPACK compile-time value", "object") !== "undefined" && ("ontouchstart" in window || navigator.maxTouchPoints > 0)
}["CruiseMode.useState"]);
const [joystickVisual, setJoystickVisual] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useState"])({
baseX: 0,
baseY: 0,
knobX: 0,
knobY: 0,
active: false
});
const [pendingChoices, setPendingChoices] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useState"])([]);
const [selectedChoice, setSelectedChoice] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useState"])(null);
// 镜像 appliedUpgradesRef 用于渲染(ref 不能在 render 中读取)
const [appliedUpgradesList, setAppliedUpgradesList] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useState"])([]);
const [hud, setHud] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useState"])({
shield: 100,
shieldMax: 100,
energy: 100,
energyMax: 100,
score: 0,
time: 0,
duration: 60,
crystals: 0,
totalCrystals: 0,
insights: 0,
totalInsights: 0,
beacons: 0,
totalBeacons: 0,
lowShield: false,
isBossLevel: false,
bossHp: 0,
bossMaxHp: 0,
bossPhase: 1,
buffs: [],
appliedUpgrades: [],
pickupFlashColor: null
});
// ---- 启动一局 ----
const startGame = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useCallback"])({
"CruiseMode.useCallback[startGame]": (lvl)=>{
const { w, h } = sizeRef.current;
if (w === 0 || h === 0) return;
const seed = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["cruiseSeed"])(lvl);
const state = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["generateLevel"])(lvl, seed, w, h, upgradesRef.current, appliedUpgradesRef.current);
state.phase = "playing";
stateRef.current = state;
rewardGrantedRef.current = false;
lastResultRef.current = null;
setResult(null);
setLevel(lvl);
setPhase("playing");
phaseRef.current = "playing";
setPaused(false);
pausedRef.current = false;
setSelectedChoice(null);
// 重置 HUD
hudRef.current = {
shield: state.ship.shield,
shieldMax: __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRUISE_CONFIG"].shieldMax + state.upgrades.shieldMaxBonus,
energy: state.ship.energy,
energyMax: __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRUISE_CONFIG"].energyMax + state.upgrades.energyMaxBonus,
score: 0,
time: 0,
duration: state.durationSec,
crystals: 0,
totalCrystals: state.totalCrystals,
insights: 0,
totalInsights: state.totalInsights,
beacons: 0,
totalBeacons: state.totalBeacons,
lowShield: false,
isBossLevel: state.isBossLevel,
bossHp: state.boss?.hp ?? 0,
bossMaxHp: state.boss?.maxHp ?? 0,
bossPhase: state.boss?.attackPhase ?? 1,
buffs: [],
appliedUpgrades: state.appliedUpgrades,
pickupFlashColor: null
};
setHud({
...hudRef.current
});
}
}["CruiseMode.useCallback[startGame]"], []);
// ---- 加载统计(已用 useState initializer 初始化,无需 effect----
// ---- 检测触摸设备(用 useState initializer 避免 effect 内 setState----
// 已在 useState 初始化时检测,此处无需 effect
// ---- Canvas 初始化 + Resize ----
(0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useEffect"])({
"CruiseMode.useEffect": ()=>{
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
const resize = {
"CruiseMode.useEffect.resize": ()=>{
const dpr = Math.min(window.devicePixelRatio || 1, 2);
const w = window.innerWidth;
const h = window.innerHeight;
canvas.width = Math.floor(w * dpr);
canvas.height = Math.floor(h * dpr);
canvas.style.width = w + "px";
canvas.style.height = h + "px";
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
sizeRef.current = {
w,
h
};
starsRef.current = generateStars(w, h);
if (stateRef.current) {
stateRef.current.worldWidth = w;
stateRef.current.worldHeight = h;
}
}
}["CruiseMode.useEffect.resize"];
resize();
window.addEventListener("resize", resize);
return ({
"CruiseMode.useEffect": ()=>window.removeEventListener("resize", resize)
})["CruiseMode.useEffect"];
}
}["CruiseMode.useEffect"], []);
// ---- 键盘控制 ----
(0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useEffect"])({
"CruiseMode.useEffect": ()=>{
const down = {
"CruiseMode.useEffect.down": (e)=>{
const k = e.key.toLowerCase();
if ([
"w",
"a",
"s",
"d",
"arrowup",
"arrowdown",
"arrowleft",
"arrowright"
].includes(k)) {
keysRef.current.add(k);
e.preventDefault();
} else if (k === " " || k === "spacebar") {
// 空格射击
shootHeldRef.current = true;
e.preventDefault();
} else if (k === "p") {
if (phaseRef.current === "playing") {
const np = !pausedRef.current;
pausedRef.current = np;
setPaused(np);
}
} else if (k === "escape") {
onClose();
}
}
}["CruiseMode.useEffect.down"];
const up = {
"CruiseMode.useEffect.up": (e)=>{
const k = e.key.toLowerCase();
if ([
"w",
"a",
"s",
"d",
"arrowup",
"arrowdown",
"arrowleft",
"arrowright"
].includes(k)) {
keysRef.current.delete(k);
} else if (k === " " || k === "spacebar") {
shootHeldRef.current = false;
}
}
}["CruiseMode.useEffect.up"];
window.addEventListener("keydown", down);
window.addEventListener("keyup", up);
return ({
"CruiseMode.useEffect": ()=>{
window.removeEventListener("keydown", down);
window.removeEventListener("keyup", up);
}
})["CruiseMode.useEffect"];
}
}["CruiseMode.useEffect"], [
onClose
]);
// ---- 失焦自动暂停 ----
(0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useEffect"])({
"CruiseMode.useEffect": ()=>{
const onBlur = {
"CruiseMode.useEffect.onBlur": ()=>{
shootHeldRef.current = false;
if (phaseRef.current === "playing") {
pausedRef.current = true;
setPaused(true);
}
}
}["CruiseMode.useEffect.onBlur"];
window.addEventListener("blur", onBlur);
document.addEventListener("visibilitychange", onBlur);
return ({
"CruiseMode.useEffect": ()=>{
window.removeEventListener("blur", onBlur);
document.removeEventListener("visibilitychange", onBlur);
}
})["CruiseMode.useEffect"];
}
}["CruiseMode.useEffect"], []);
// ---- 触摸摇杆 + 射击按钮 ----
(0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useEffect"])({
"CruiseMode.useEffect": ()=>{
const onStart = {
"CruiseMode.useEffect.onStart": (e)=>{
if (phaseRef.current !== "playing" || pausedRef.current) return;
for(let i = 0; i < e.changedTouches.length; i++){
const t = e.changedTouches[i];
// 右下区域:射击按钮
if (t.clientX > window.innerWidth * 0.65 && t.clientY > window.innerHeight * 0.55) {
shootHeldRef.current = true;
e.preventDefault();
continue;
}
// 左下区域激活摇杆
if (t.clientX < window.innerWidth * 0.5 && t.clientY > window.innerHeight * 0.35) {
if (joystickRef.current.active) continue;
joystickRef.current = {
active: true,
baseX: t.clientX,
baseY: t.clientY,
knobX: 0,
knobY: 0,
touchId: t.identifier
};
setJoystickVisual({
baseX: t.clientX,
baseY: t.clientY,
knobX: 0,
knobY: 0,
active: true
});
e.preventDefault();
return;
}
}
}
}["CruiseMode.useEffect.onStart"];
const onMove = {
"CruiseMode.useEffect.onMove": (e)=>{
if (!joystickRef.current.active) return;
for(let i = 0; i < e.changedTouches.length; i++){
const t = e.changedTouches[i];
if (t.identifier !== joystickRef.current.touchId) continue;
const dx = t.clientX - joystickRef.current.baseX;
const dy = t.clientY - joystickRef.current.baseY;
const maxR = 55;
const mag = Math.hypot(dx, dy);
const clampedMag = Math.min(mag, maxR);
const nx = mag > 0 ? dx / mag * clampedMag : 0;
const ny = mag > 0 ? dy / mag * clampedMag : 0;
joystickRef.current.knobX = nx / maxR; // -1 ~ 1
joystickRef.current.knobY = ny / maxR;
setJoystickVisual({
baseX: joystickRef.current.baseX,
baseY: joystickRef.current.baseY,
knobX: nx,
knobY: ny,
active: true
});
e.preventDefault();
return;
}
}
}["CruiseMode.useEffect.onMove"];
const onEnd = {
"CruiseMode.useEffect.onEnd": (e)=>{
for(let i = 0; i < e.changedTouches.length; i++){
const t = e.changedTouches[i];
if (t.identifier === joystickRef.current.touchId) {
joystickRef.current = {
active: false,
baseX: 0,
baseY: 0,
knobX: 0,
knobY: 0,
touchId: null
};
setJoystickVisual({
baseX: 0,
baseY: 0,
knobX: 0,
knobY: 0,
active: false
});
}
// 右下区域松开 → 停止射击
if (t.clientX > window.innerWidth * 0.65 && t.clientY > window.innerHeight * 0.55) {
shootHeldRef.current = false;
}
}
e.preventDefault();
}
}["CruiseMode.useEffect.onEnd"];
window.addEventListener("touchstart", onStart, {
passive: false
});
window.addEventListener("touchmove", onMove, {
passive: false
});
window.addEventListener("touchend", onEnd, {
passive: false
});
window.addEventListener("touchcancel", onEnd, {
passive: false
});
return ({
"CruiseMode.useEffect": ()=>{
window.removeEventListener("touchstart", onStart);
window.removeEventListener("touchmove", onMove);
window.removeEventListener("touchend", onEnd);
window.removeEventListener("touchcancel", onEnd);
}
})["CruiseMode.useEffect"];
}
}["CruiseMode.useEffect"], []);
// ---- 游戏主循环 ----
(0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useEffect"])({
"CruiseMode.useEffect": ()=>{
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
const loop = {
"CruiseMode.useEffect.loop": (time)=>{
rafRef.current = requestAnimationFrame(loop);
const dt = lastTimeRef.current === 0 ? 16 : time - lastTimeRef.current;
lastTimeRef.current = time;
const dtSec = Math.min(dt / 1000, 0.05);
const { w, h } = sizeRef.current;
if (w === 0 || h === 0) return;
const state = stateRef.current;
const playing = state && state.phase === "playing" && !pausedRef.current;
// ---- 更新 ----
if (playing && state) {
// 计算输入
let dx = 0;
let dy = 0;
const keys = keysRef.current;
if (keys.has("w") || keys.has("arrowup")) dy -= 1;
if (keys.has("s") || keys.has("arrowdown")) dy += 1;
if (keys.has("a") || keys.has("arrowleft")) dx -= 1;
if (keys.has("d") || keys.has("arrowright")) dx += 1;
// 摇杆覆盖
if (joystickRef.current.active) {
dx = joystickRef.current.knobX;
dy = joystickRef.current.knobY;
}
const input = {
dx,
dy,
active: Math.abs(dx) > 0.05 || Math.abs(dy) > 0.05,
shoot: shootHeldRef.current
};
const res = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["updateCruise"])(state, dt, input);
if (res) {
// 结算
lastResultRef.current = res;
setResult(res);
setPhase(res.phase);
phaseRef.current = res.phase;
if (!rewardGrantedRef.current) {
rewardGrantedRef.current = true;
__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$store$2f$gameStore$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["useGameStore"].getState().grantCruiseReward(res.rewards);
const newStats = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["recordRun"])(res);
setStats(newStats);
}
}
// 更新 HUD ref
hudRef.current = {
shield: state.ship.shield,
shieldMax: __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRUISE_CONFIG"].shieldMax + state.upgrades.shieldMaxBonus,
energy: state.ship.energy,
energyMax: __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRUISE_CONFIG"].energyMax + state.upgrades.energyMaxBonus,
score: state.score,
time: state.timeSec,
duration: state.durationSec,
crystals: state.collectedCrystals,
totalCrystals: state.totalCrystals,
insights: state.collectedInsights,
totalInsights: state.totalInsights,
beacons: state.collectedBeacons,
totalBeacons: state.totalBeacons,
lowShield: state.flashLowShield,
isBossLevel: state.isBossLevel,
bossHp: state.boss?.hp ?? 0,
bossMaxHp: state.boss?.maxHp ?? 0,
bossPhase: state.boss?.attackPhase ?? 1,
buffs: [
...state.activeBuffs
],
appliedUpgrades: state.appliedUpgrades,
pickupFlashColor: state.pickupFlash?.color ?? null
};
// 节流更新 React HUD~12fps
if (time - lastHudUpdateRef.current > 80) {
lastHudUpdateRef.current = time;
setHud({
...hudRef.current
});
}
}
// ---- 渲染 ----
// 背景
ctx.fillStyle = "#050410";
ctx.fillRect(0, 0, w, h);
// 屏幕震动偏移
let shakeX = 0;
let shakeY = 0;
if (state && state.shakeTimer > 0) {
const intensity = state.shakeAmount * (state.shakeTimer / __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["CRUISE_CONFIG"].shakeMs);
shakeX = (Math.random() - 0.5) * intensity;
shakeY = (Math.random() - 0.5) * intensity;
}
ctx.save();
ctx.translate(shakeX, shakeY);
// 视差星空
const shipVx = state ? state.ship.vx : 0;
const shipVy = state ? state.ship.vy : 0;
drawStars(ctx, starsRef.current, dtSec, w, h, shipVx, shipVy);
// 实体
if (state) {
// 星门优先(在底层)
for (const e of state.entities){
if (e.type === "stargate") drawStargate(ctx, e, state.ship);
}
// 风暴
for (const e of state.entities){
if (e.type === "storm") drawStorm(ctx, e);
}
// 陨石
for (const e of state.entities){
if (e.type === "asteroid") drawAsteroid(ctx, e);
}
// 道具
for (const p of state.powerups)drawPowerup(ctx, p);
// 收集物
for (const e of state.entities){
if (e.type === "crystal") drawCrystal(ctx, e);
else if (e.type === "insight") drawInsight(ctx, e);
else if (e.type === "beacon") drawBeacon(ctx, e);
}
// 粒子
for (const p of state.particles)drawParticle(ctx, p);
// 子弹
for (const b of state.bullets)drawBullet(ctx, b);
// BOSS(在飞船之下绘制)
if (state.boss) drawBoss(ctx, state.boss);
// 飞船(最上层)
if (state.phase === "playing" || state.phase === "won") {
drawShip(ctx, state.ship, state.invulnTimer > 0, state.activeBuffs);
}
}
ctx.restore();
// 低护盾红色边框(不受震动影响)
if (state && state.flashLowShield && state.phase === "playing") {
const pulse = 0.3 + 0.3 * Math.sin(time / 150);
ctx.strokeStyle = `rgba(251,113,133,${pulse})`;
ctx.lineWidth = 6;
ctx.strokeRect(3, 3, w - 6, h - 6);
}
// 道具拾取屏幕闪光(边缘渐变)
if (state && state.pickupFlash && state.phase === "playing") {
const alpha = state.pickupFlash.timer / 400;
const c = state.pickupFlash.color;
const grad = ctx.createRadialGradient(w / 2, h / 2, Math.min(w, h) * 0.3, w / 2, h / 2, Math.max(w, h) * 0.7);
grad.addColorStop(0, "rgba(0,0,0,0)");
grad.addColorStop(1, `${c}${Math.round(alpha * 100).toString(16).padStart(2, "0")}`);
ctx.fillStyle = grad;
ctx.fillRect(0, 0, w, h);
}
}
}["CruiseMode.useEffect.loop"];
rafRef.current = requestAnimationFrame(loop);
return ({
"CruiseMode.useEffect": ()=>cancelAnimationFrame(rafRef.current)
})["CruiseMode.useEffect"];
}
}["CruiseMode.useEffect"], []);
// ---- 暂停切换 ----
const togglePause = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useCallback"])({
"CruiseMode.useCallback[togglePause]": ()=>{
if (phaseRef.current !== "playing") return;
const np = !pausedRef.current;
pausedRef.current = np;
setPaused(np);
}
}["CruiseMode.useCallback[togglePause]"], []);
// ---- 退出 ----
const handleExit = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useCallback"])({
"CruiseMode.useCallback[handleExit]": ()=>{
onClose();
}
}["CruiseMode.useCallback[handleExit]"], [
onClose
]);
// ---- 进入升级选择阶段(won → choosing ----
const goToChoosing = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useCallback"])({
"CruiseMode.useCallback[goToChoosing]": ()=>{
if (!lastResultRef.current) return;
// 失败不进入选择
if (lastResultRef.current.phase !== "won") return;
const choices = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["rollUpgradeChoices"])(3, appliedUpgradesRef.current.map({
"CruiseMode.useCallback[goToChoosing].choices": (c)=>c.id
}["CruiseMode.useCallback[goToChoosing].choices"]));
setPendingChoices(choices);
setSelectedChoice(null);
setPhase("choosing");
phaseRef.current = "choosing";
}
}["CruiseMode.useCallback[goToChoosing]"], []);
// ---- 选择一张升级卡 ----
const handlePickUpgrade = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$index$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["useCallback"])({
"CruiseMode.useCallback[handlePickUpgrade]": (idx)=>{
const card = pendingChoices[idx];
if (!card) return;
setSelectedChoice(idx);
// 应用升级
(0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["applyUpgradeCard"])(upgradesRef.current, card);
appliedUpgradesRef.current = [
...appliedUpgradesRef.current,
card
];
setAppliedUpgradesList(appliedUpgradesRef.current);
// 延迟跳转到下一关(让动画播放)
setTimeout({
"CruiseMode.useCallback[handlePickUpgrade]": ()=>{
if (lastResultRef.current) {
startGame(lastResultRef.current.level + 1);
}
}
}["CruiseMode.useCallback[handlePickUpgrade]"], 700);
}
}["CruiseMode.useCallback[handlePickUpgrade]"], [
pendingChoices,
startGame
]);
// ============================================================
// 渲染
// ============================================================
const shieldPct = hud.shieldMax > 0 ? Math.max(0, Math.min(100, hud.shield / hud.shieldMax * 100)) : 0;
const shieldColor = shieldPct > 60 ? "#34d399" : shieldPct > 30 ? "#fbbf24" : "#fb7185";
const energyPct = hud.energyMax > 0 ? Math.max(0, Math.min(100, hud.energy / hud.energyMax * 100)) : 0;
const timeLeft = Math.max(0, hud.duration - hud.time);
const bossHpPct = hud.bossMaxHp > 0 ? hud.bossHp / hud.bossMaxHp * 100 : 0;
return /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "fixed inset-0 z-50 bg-[#050410] overflow-hidden select-none",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("canvas", {
ref: canvasRef,
className: "absolute inset-0 w-full h-full touch-none"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1409,
columnNumber: 7
}, this),
phase === "playing" && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Fragment"], {
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute top-3 left-3 flex flex-col gap-2 min-w-[180px]",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-xl p-2.5 border-white/10",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-2 mb-1.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$shield$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Shield$3e$__["Shield"], {
className: "h-3.5 w-3.5",
style: {
color: shieldColor
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1421,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-[10px] text-muted-foreground uppercase tracking-wider",
children: "护盾"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1422,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "ml-auto font-mono text-xs font-bold",
style: {
color: shieldColor
},
children: Math.round(hud.shield)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1423,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1420,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "h-2 rounded-full bg-black/50 overflow-hidden border border-white/5",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "h-full rounded-full transition-all duration-150",
style: {
width: `${shieldPct}%`,
background: `linear-gradient(90deg, ${shieldColor}, ${shieldColor}dd)`,
boxShadow: `0 0 8px ${shieldColor}aa`
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1428,
columnNumber: 17
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1427,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-2 mt-2 mb-1.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$zap$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Zap$3e$__["Zap"], {
className: "h-3.5 w-3.5 text-fuchsia-300"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1438,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-[10px] text-muted-foreground uppercase tracking-wider",
children: "能量"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1439,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "ml-auto font-mono text-xs font-bold text-fuchsia-200",
children: Math.round(hud.energy)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1440,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1437,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "h-2 rounded-full bg-black/50 overflow-hidden border border-white/5",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "h-full rounded-full transition-all duration-150",
style: {
width: `${energyPct}%`,
background: "linear-gradient(90deg, #e879f9, #c026d3)",
boxShadow: "0 0 8px rgba(232,121,249,0.6)"
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1445,
columnNumber: 17
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1444,
columnNumber: 15
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1419,
columnNumber: 13
}, this),
hud.buffs.length > 0 && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-xl p-2 border-white/10 flex flex-col gap-1",
children: hud.buffs.map((buff, i)=>{
const color = POWERUP_COLOR[buff.type];
const pct = Math.max(0, buff.remaining / buff.total * 100);
const label = buff.type === "shield" ? "护盾" : buff.type === "energy" ? "能量" : buff.type === "rapid" ? "急速" : buff.type === "overdrive" ? "过载" : "磁吸";
return /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-1.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "h-2 w-2 rounded-full",
style: {
background: color,
boxShadow: `0 0 6px ${color}`
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1469,
columnNumber: 23
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-[10px] text-white/80",
style: {
color
},
children: label
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1470,
columnNumber: 23
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex-1 h-1 rounded-full bg-black/40 overflow-hidden",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "h-full rounded-full",
style: {
width: `${pct}%`,
background: color
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1472,
columnNumber: 25
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1471,
columnNumber: 23
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-[9px] text-muted-foreground w-6 text-right",
children: [
Math.ceil(buff.remaining),
"s"
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1474,
columnNumber: 23
}, this)
]
}, i, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1468,
columnNumber: 21
}, this);
})
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1457,
columnNumber: 15
}, this),
hud.appliedUpgrades.length > 0 && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-xl p-1.5 border-white/10 flex flex-wrap gap-1 max-w-[200px]",
children: hud.appliedUpgrades.map((u, i)=>/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "h-5 w-5 rounded-md flex items-center justify-center border",
style: {
borderColor: `${u.color}80`,
background: `${u.color}20`
},
title: u.title,
children: (()=>{
const Icon = UPGRADE_ICON_MAP[u.icon] ?? __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$sparkles$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Sparkles$3e$__["Sparkles"];
return /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(Icon, {
className: "h-3 w-3",
style: {
color: u.color
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1492,
columnNumber: 30
}, this);
})()
}, i, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1484,
columnNumber: 19
}, this))
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1482,
columnNumber: 15
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1418,
columnNumber: 11
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute top-3 left-1/2 -translate-x-1/2 flex flex-col items-center gap-1.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-xl px-4 py-2 border-white/10 flex items-center gap-4",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-center",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[9px] text-muted-foreground uppercase tracking-wider",
children: "关卡"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1504,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-sm font-bold text-amber-200",
children: [
"L",
level,
hud.isBossLevel && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$skull$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Skull$3e$__["Skull"], {
className: "inline h-3 w-3 ml-0.5 text-rose-300"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1506,
columnNumber: 47
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1505,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1503,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "w-px h-7 bg-white/10"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1509,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-center",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[9px] text-muted-foreground uppercase tracking-wider",
children: "分数"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1511,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-sm font-bold text-emerald-200",
children: (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["formatNum"])(hud.score)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1512,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1510,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "w-px h-7 bg-white/10"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1514,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-center min-w-[52px]",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[9px] text-muted-foreground uppercase tracking-wider flex items-center justify-center gap-0.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$clock$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Clock$3e$__["Clock"], {
className: "h-2.5 w-2.5"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1517,
columnNumber: 19
}, this),
"用时"
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1516,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-sm font-bold text-rose-200",
children: [
Math.floor(timeLeft / 60),
":",
String(Math.floor(timeLeft % 60)).padStart(2, "0")
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1519,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1515,
columnNumber: 15
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1502,
columnNumber: 13
}, this),
hud.isBossLevel && hud.bossMaxHp > 0 && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg px-3 py-1.5 border-rose-400/30 min-w-[260px] sm:min-w-[320px]",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center justify-between mb-0.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-1.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$skull$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Skull$3e$__["Skull"], {
className: "h-3 w-3 text-rose-300"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1529,
columnNumber: 21
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-[10px] text-rose-200 font-bold tracking-wider",
children: "BOSS"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1530,
columnNumber: 21
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1528,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-1",
children: [
1,
2,
3
].map((p)=>/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: `h-1.5 w-1.5 rounded-full ${p <= hud.bossPhase ? "bg-rose-400" : "bg-white/15"}`
}, p, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1534,
columnNumber: 23
}, this))
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1532,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1527,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "h-2.5 rounded-full bg-black/60 overflow-hidden border border-rose-400/20",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "h-full rounded-full transition-all duration-200",
style: {
width: `${bossHpPct}%`,
background: "linear-gradient(90deg, #fb7185, #e879f9)",
boxShadow: "0 0 12px rgba(232,121,249,0.7)"
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1542,
columnNumber: 19
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1541,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1526,
columnNumber: 15
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1501,
columnNumber: 11
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute top-3 right-3 flex items-start gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-xl p-2 border-white/10 flex flex-col gap-1.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-1.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$gem$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Gem$3e$__["Gem"], {
className: "h-3 w-3 text-emerald-300"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1559,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-xs font-bold text-emerald-200",
children: [
hud.crystals,
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-muted-foreground/60",
children: [
"/",
hud.totalCrystals
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1561,
columnNumber: 33
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1560,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1558,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-1.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$brain$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Brain$3e$__["Brain"], {
className: "h-3 w-3 text-fuchsia-300"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1565,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-xs font-bold text-fuchsia-200",
children: [
hud.insights,
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-muted-foreground/60",
children: [
"/",
hud.totalInsights
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1567,
columnNumber: 33
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1566,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1564,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-1.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$radio$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Radio$3e$__["Radio"], {
className: "h-3 w-3 text-amber-300"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1571,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-xs font-bold text-amber-200",
children: [
hud.beacons,
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-muted-foreground/60",
children: [
"/",
hud.totalBeacons
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1573,
columnNumber: 32
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1572,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1570,
columnNumber: 15
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1557,
columnNumber: 13
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
size: "icon",
variant: "ghost",
onClick: togglePause,
className: "h-8 w-8 glass border-white/10 hover:bg-white/10 text-white/80",
"aria-label": "暂停",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$pause$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Pause$3e$__["Pause"], {
className: "h-4 w-4"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1584,
columnNumber: 15
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1577,
columnNumber: 13
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
size: "icon",
variant: "ghost",
onClick: handleExit,
className: "h-8 w-8 glass border-rose-400/30 hover:bg-rose-500/20 text-rose-200",
"aria-label": "退出",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$x$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__X$3e$__["X"], {
className: "h-4 w-4"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1593,
columnNumber: 15
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1586,
columnNumber: 13
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1556,
columnNumber: 11
}, this),
!isTouch && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute bottom-4 left-1/2 -translate-x-1/2 glass rounded-full px-4 py-1.5 border-white/10 text-[11px] text-muted-foreground",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-white/80",
children: "WASD"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1600,
columnNumber: 15
}, this),
" / ",
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-white/80",
children: "方向键"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1600,
columnNumber: 71
}, this),
" 移动 · ",
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-emerald-300",
children: "空格"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1600,
columnNumber: 129
}, this),
" 射击 · ",
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-white/80",
children: "P"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1600,
columnNumber: 189
}, this),
" 暂停 · ",
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-white/80",
children: "Esc"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1600,
columnNumber: 245
}, this),
" 退出"
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1599,
columnNumber: 13
}, this),
isTouch && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute bottom-4 left-1/2 -translate-x-1/2 glass rounded-full px-3 py-1 border-white/10 text-[10px] text-muted-foreground pointer-events-none",
children: "左下摇杆 · 右下射击"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1604,
columnNumber: 13
}, this),
isTouch && joystickVisual.active && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute pointer-events-none",
style: {
left: joystickVisual.baseX,
top: joystickVisual.baseY,
transform: "translate(-50%, -50%)"
},
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "relative h-28 w-28 rounded-full border-2 border-amber-400/40 bg-amber-500/5 backdrop-blur-sm",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute h-12 w-12 rounded-full border-2 border-amber-300 bg-amber-400/30 backdrop-blur",
style: {
left: "50%",
top: "50%",
transform: `translate(calc(-50% + ${joystickVisual.knobX}px), calc(-50% + ${joystickVisual.knobY}px))`,
boxShadow: "0 0 16px rgba(251,191,36,0.6)"
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1613,
columnNumber: 17
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1612,
columnNumber: 15
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1611,
columnNumber: 13
}, this),
isTouch && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("button", {
"aria-label": "射击",
className: "absolute bottom-20 right-6 h-20 w-20 rounded-full border-2 border-emerald-400/50 bg-emerald-500/15 backdrop-blur-md flex items-center justify-center pointer-events-none",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$crosshair$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Crosshair$3e$__["Crosshair"], {
className: "h-9 w-9 text-emerald-300",
style: {
filter: "drop-shadow(0 0 8px rgba(52,211,153,0.8))"
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1632,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute inset-0 rounded-full border-2 border-emerald-400/30 animate-ping",
style: {
animationDuration: "2s"
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1633,
columnNumber: 15
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1628,
columnNumber: 13
}, this),
paused && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-10",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-2xl p-8 border-white/15 text-center max-w-xs",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$pause$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Pause$3e$__["Pause"], {
className: "h-10 w-10 mx-auto mb-3 text-amber-300"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1641,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("h3", {
className: "text-lg font-bold text-white mb-1",
children: "已暂停"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1642,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
className: "text-xs text-muted-foreground mb-5",
children: "深空时间已凝固"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1643,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex flex-col gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
onClick: togglePause,
className: "bg-amber-500/20 border border-amber-400/50 text-amber-100 hover:bg-amber-500/30",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$play$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Play$3e$__["Play"], {
className: "h-4 w-4 mr-1.5"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1649,
columnNumber: 21
}, this),
"继续"
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1645,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
variant: "ghost",
onClick: handleExit,
className: "text-rose-200 hover:bg-rose-500/10",
children: "退出巡航"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1652,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1644,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1640,
columnNumber: 15
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1639,
columnNumber: 13
}, this)
]
}, void 0, true),
phase === "ready" && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute inset-0 flex items-center justify-center p-4 bg-gradient-to-b from-black/40 via-transparent to-black/60",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-2xl p-6 sm:p-8 border-amber-400/30 max-w-md w-full text-center relative overflow-hidden",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "pointer-events-none absolute -top-20 -left-20 h-40 w-40 rounded-full bg-amber-500/20 blur-3xl"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1670,
columnNumber: 13
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "pointer-events-none absolute -bottom-20 -right-20 h-40 w-40 rounded-full bg-rose-500/20 blur-3xl"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1671,
columnNumber: 13
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "relative",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[10px] tracking-[0.3em] text-amber-300/70 mb-1",
children: "DEEP SPACE CRUISE · v0.8"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1673,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("h2", {
className: "text-3xl sm:text-4xl font-bold text-gradient mb-1",
children: "深空巡航"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1674,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
className: "text-xs text-muted-foreground mb-5",
children: "操控飞船穿越陨石带,抵达星门 / 击败 BOSS"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1675,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "grid grid-cols-2 gap-2 mb-5 text-left",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg p-2.5 border-white/10",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[10px] text-muted-foreground",
children: "起始关卡"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1679,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-lg font-bold text-amber-200",
children: [
"L",
level
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1680,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1678,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg p-2.5 border-white/10",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[10px] text-muted-foreground",
children: "历史最高分"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1683,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-lg font-bold text-emerald-200",
children: stats ? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["formatNum"])(stats.highScore) : "—"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1684,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1682,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg p-2.5 border-white/10",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[10px] text-muted-foreground",
children: "通关次数"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1689,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-lg font-bold text-fuchsia-200",
children: stats ? stats.totalWins : 0
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1690,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1688,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg p-2.5 border-white/10",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[10px] text-muted-foreground",
children: "BOSS 击杀"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1695,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-lg font-bold text-rose-200",
children: stats ? stats.bossKills : 0
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1696,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1694,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1677,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg p-3 border-white/10 mb-5 text-left text-[11px] space-y-1",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$gem$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Gem$3e$__["Gem"], {
className: "h-3 w-3 text-emerald-300 shrink-0"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1704,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-muted-foreground",
children: "收集晶体碎片 → 晶体奖励"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1705,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1703,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$brain$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Brain$3e$__["Brain"], {
className: "h-3 w-3 text-fuchsia-300 shrink-0"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1708,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-muted-foreground",
children: "收集洞见光球 → 洞见奖励"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1709,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1707,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$radio$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Radio$3e$__["Radio"], {
className: "h-3 w-3 text-amber-300 shrink-0"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1712,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-muted-foreground",
children: "收集信标 → 接触进度"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1713,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1711,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$trophy$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Trophy$3e$__["Trophy"], {
className: "h-3 w-3 text-rose-300 shrink-0"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1716,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-muted-foreground",
children: "抵达星门通关 → +50% 奖励"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1717,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1715,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$skull$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Skull$3e$__["Skull"], {
className: "h-3 w-3 text-rose-300 shrink-0"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1720,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-muted-foreground",
children: "每 5 关 BOSS 战:击败 ×3 奖励"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1721,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1719,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$crosshair$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Crosshair$3e$__["Crosshair"], {
className: "h-3 w-3 text-emerald-300 shrink-0"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1724,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-muted-foreground",
children: "空格 / 右下角射击按钮 → 发射能量弹"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1725,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1723,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$sparkles$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Sparkles$3e$__["Sparkles"], {
className: "h-3 w-3 text-fuchsia-300 shrink-0"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1728,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-muted-foreground",
children: "通关后 3 选 1 强化卡牌(每局重置)"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1729,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1727,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1702,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
onClick: ()=>startGame(level),
className: "flex-1 bg-amber-500/20 border border-amber-400/50 text-amber-100 hover:bg-amber-500/30 h-11",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$play$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Play$3e$__["Play"], {
className: "h-4 w-4 mr-1.5"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1738,
columnNumber: 19
}, this),
"启动巡航"
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1734,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
variant: "ghost",
onClick: handleExit,
className: "border border-white/10 text-white/70 hover:bg-white/10 h-11",
children: "返回"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1741,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1733,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[10px] text-muted-foreground/60 mt-3",
children: isTouch ? "左下摇杆移动 · 右下射击" : "WASD / 方向键移动 · 空格射击 · P 暂停 · Esc 退出"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1749,
columnNumber: 15
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1672,
columnNumber: 13
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1669,
columnNumber: 11
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1668,
columnNumber: 9
}, this),
(phase === "won" || phase === "lost") && result && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute inset-0 flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: `glass rounded-2xl p-6 sm:p-8 max-w-md w-full relative overflow-hidden ${phase === "won" ? result.isBossLevel ? "border-fuchsia-400/50" : "border-emerald-400/40" : "border-rose-400/40"}`,
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: `pointer-events-none absolute -top-20 -left-20 h-40 w-40 rounded-full blur-3xl ${phase === "won" ? result.isBossLevel ? "bg-fuchsia-500/25" : "bg-emerald-500/20" : "bg-rose-500/20"}`
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1765,
columnNumber: 13
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "relative",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: `text-[10px] tracking-[0.3em] mb-1 ${phase === "won" ? result.isBossLevel ? "text-fuchsia-300/70" : "text-emerald-300/70" : "text-rose-300/70"}`,
children: phase === "won" ? result.isBossLevel ? "BOSS DEFEATED" : "MISSION COMPLETE" : "MISSION FAILED"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1771,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("h2", {
className: `text-3xl font-bold mb-1 ${phase === "won" ? result.isBossLevel ? "text-fuchsia-300" : "text-emerald-300" : "text-rose-300"}`,
style: {
textShadow: `0 0 20px ${phase === "won" ? result.isBossLevel ? "rgba(232,121,249,0.5)" : "rgba(52,211,153,0.5)" : "rgba(251,113,133,0.5)"}`
},
children: phase === "won" ? result.isBossLevel ? "BOSS 击破" : "巡航成功" : "巡航失败"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1778,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
className: "text-xs text-muted-foreground mb-5",
children: [
"关卡 L",
result.level,
" · 用时 ",
Math.floor(result.durationSec / 60),
":",
String(Math.floor(result.durationSec % 60)).padStart(2, "0")
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1786,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "grid grid-cols-3 gap-2 mb-4",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg p-2 border-emerald-400/20 text-center",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$gem$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Gem$3e$__["Gem"], {
className: "h-4 w-4 mx-auto text-emerald-300 mb-0.5"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1794,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-lg font-bold text-emerald-200",
children: result.collectedCrystals
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1795,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[9px] text-muted-foreground",
children: "晶体碎片"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1798,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1793,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg p-2 border-fuchsia-400/20 text-center",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$brain$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Brain$3e$__["Brain"], {
className: "h-4 w-4 mx-auto text-fuchsia-300 mb-0.5"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1801,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-lg font-bold text-fuchsia-200",
children: result.collectedInsights
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1802,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[9px] text-muted-foreground",
children: "洞见光球"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1805,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1800,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg p-2 border-amber-400/20 text-center",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$radio$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Radio$3e$__["Radio"], {
className: "h-4 w-4 mx-auto text-amber-300 mb-0.5"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1808,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-lg font-bold text-amber-200",
children: result.collectedBeacons
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1809,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[9px] text-muted-foreground",
children: "信标"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1812,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1807,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1792,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "grid grid-cols-2 gap-2 mb-4",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg p-2 border-white/10 flex items-center gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$shield$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Shield$3e$__["Shield"], {
className: "h-4 w-4 text-rose-300"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1819,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[9px] text-muted-foreground",
children: "剩余护盾"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1821,
columnNumber: 21
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-sm font-bold text-rose-200",
children: result.remainingShield
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1822,
columnNumber: 21
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1820,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1818,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg p-2 border-white/10 flex items-center gap-2",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$trophy$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Trophy$3e$__["Trophy"], {
className: "h-4 w-4 text-amber-300"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1828,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[9px] text-muted-foreground",
children: "得分"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1830,
columnNumber: 21
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "font-mono text-sm font-bold text-amber-200",
children: (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["formatNum"])(result.score)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1831,
columnNumber: 21
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1829,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1827,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1817,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "glass rounded-lg p-3 border-emerald-400/20 mb-5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[10px] text-muted-foreground uppercase tracking-wider mb-2",
children: phase === "won" ? result.isBossLevel ? "BOSS 击败奖励 (×3)" : "通关奖励 (+50%)" : "残骸回收 (×50%)"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1840,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "space-y-1.5",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center justify-between",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "flex items-center gap-1.5 text-xs text-emerald-200",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$gem$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Gem$3e$__["Gem"], {
className: "h-3 w-3"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1848,
columnNumber: 23
}, this),
" 晶体"
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1847,
columnNumber: 21
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-sm font-bold text-emerald-200",
children: [
"+",
(0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$config$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["formatNum"])(result.rewards.crystals)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1850,
columnNumber: 21
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1846,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center justify-between",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "flex items-center gap-1.5 text-xs text-fuchsia-200",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$brain$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Brain$3e$__["Brain"], {
className: "h-3 w-3"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1856,
columnNumber: 23
}, this),
" 洞见"
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1855,
columnNumber: 21
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-sm font-bold text-fuchsia-200",
children: [
"+",
result.rewards.insights.toFixed(1)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1858,
columnNumber: 21
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1854,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center justify-between",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "flex items-center gap-1.5 text-xs text-amber-200",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$radio$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Radio$3e$__["Radio"], {
className: "h-3 w-3"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1864,
columnNumber: 23
}, this),
" 接触"
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1863,
columnNumber: 21
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "font-mono text-sm font-bold text-amber-200",
children: [
"+",
result.rewards.contact.toFixed(1),
"%"
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1866,
columnNumber: 21
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1862,
columnNumber: 19
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1845,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[9px] text-muted-foreground/70 mt-2 pt-2 border-t border-white/5",
children: "奖励已同步至主游戏"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1871,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1839,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex gap-2",
children: [
phase === "won" && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
onClick: goToChoosing,
className: "flex-1 bg-fuchsia-500/20 border border-fuchsia-400/50 text-fuchsia-100 hover:bg-fuchsia-500/30 h-10",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$sparkles$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Sparkles$3e$__["Sparkles"], {
className: "h-4 w-4 mr-1"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1883,
columnNumber: 21
}, this),
"选择强化"
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1879,
columnNumber: 19
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
onClick: ()=>startGame(result.level),
variant: phase === "won" ? "ghost" : "default",
className: `${phase === "lost" ? "flex-1 bg-rose-500/20 border border-rose-400/50 text-rose-100 hover:bg-rose-500/30" : "border border-white/10 text-white/80 hover:bg-white/10"} h-10`,
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$rotate$2d$ccw$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__RotateCcw$3e$__["RotateCcw"], {
className: "h-4 w-4 mr-1"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1896,
columnNumber: 19
}, this),
"重试"
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1887,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
variant: "ghost",
onClick: handleExit,
className: "border border-white/10 text-white/70 hover:bg-white/10 h-10",
children: "返回"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1899,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1877,
columnNumber: 15
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1770,
columnNumber: 13
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1760,
columnNumber: 11
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1759,
columnNumber: 9
}, this),
phase === "choosing" && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute inset-0 flex items-center justify-center p-4 bg-black/70 backdrop-blur-md",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "w-full max-w-3xl",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-center mb-6",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[10px] tracking-[0.4em] text-fuchsia-300/70 mb-1",
children: "REINFORCEMENT PROTOCOL"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1917,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("h2", {
className: "text-2xl sm:text-3xl font-bold text-gradient mb-1",
children: "选择强化"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1918,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
className: "text-xs text-muted-foreground",
children: "星门共鸣释放能量,3 选 1 永久强化(本局有效)"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1919,
columnNumber: 15
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1916,
columnNumber: 13
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "grid grid-cols-1 sm:grid-cols-3 gap-3",
children: pendingChoices.map((card, idx)=>{
const Icon = UPGRADE_ICON_MAP[card.icon] ?? __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$sparkles$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Sparkles$3e$__["Sparkles"];
const isSelected = selectedChoice === idx;
const isFaded = selectedChoice !== null && !isSelected;
return /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("button", {
onClick: ()=>selectedChoice === null && handlePickUpgrade(idx),
disabled: selectedChoice !== null,
className: `group relative glass rounded-2xl p-5 border-2 transition-all duration-500 text-left overflow-hidden ${isSelected ? "scale-105 border-fuchsia-400 shadow-[0_0_30px_rgba(232,121,249,0.5)]" : isFaded ? "opacity-40 border-white/10" : "border-white/15 hover:border-white/30 hover:scale-[1.02] cursor-pointer"}`,
style: {
minHeight: "220px"
},
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "pointer-events-none absolute -top-10 -left-10 h-32 w-32 rounded-full blur-3xl opacity-40 transition-opacity group-hover:opacity-70",
style: {
background: card.color
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1941,
columnNumber: 21
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "relative flex flex-col h-full",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "h-12 w-12 rounded-xl flex items-center justify-center mb-3 border",
style: {
background: `${card.color}20`,
borderColor: `${card.color}80`,
boxShadow: `0 0 16px ${card.color}40`
},
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(Icon, {
className: "h-6 w-6",
style: {
color: card.color
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1954,
columnNumber: 25
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1946,
columnNumber: 23
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[10px] font-mono uppercase tracking-wider mb-1",
style: {
color: card.color
},
children: [
"强化 ",
String(idx + 1).padStart(2, "0")
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1956,
columnNumber: 23
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("h3", {
className: "text-lg font-bold text-white mb-1.5",
children: card.title
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1959,
columnNumber: 23
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
className: "text-xs text-muted-foreground mb-3",
children: card.desc
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1960,
columnNumber: 23
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "mt-auto pt-2 border-t border-white/5",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center justify-between text-[10px]",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-muted-foreground/70",
children: "点击选择"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1963,
columnNumber: 27
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$chevron$2d$right$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__ChevronRight$3e$__["ChevronRight"], {
className: "h-3 w-3",
style: {
color: card.color
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1964,
columnNumber: 27
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1962,
columnNumber: 25
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1961,
columnNumber: 23
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1945,
columnNumber: 21
}, this),
isSelected && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "absolute inset-0 flex items-center justify-center bg-fuchsia-500/10 backdrop-blur-[1px]",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-center",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$sparkles$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Sparkles$3e$__["Sparkles"], {
className: "h-10 w-10 mx-auto text-fuchsia-300 animate-pulse",
style: {
filter: "drop-shadow(0 0 12px rgba(232,121,249,0.8))"
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1971,
columnNumber: 27
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "mt-2 text-xs font-bold text-fuchsia-200 tracking-wider",
children: "已激活"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1972,
columnNumber: 27
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1970,
columnNumber: 25
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1969,
columnNumber: 23
}, this)
]
}, card.id, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1927,
columnNumber: 19
}, this);
})
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1921,
columnNumber: 13
}, this),
appliedUpgradesList.length > 0 && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "mt-5 glass rounded-xl p-3 border-white/10",
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-[10px] text-muted-foreground uppercase tracking-wider mb-2",
children: "本局已激活强化"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1983,
columnNumber: 17
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex flex-wrap gap-2",
children: appliedUpgradesList.map((u, i)=>{
const Icon = UPGRADE_ICON_MAP[u.icon] ?? __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$sparkles$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Sparkles$3e$__["Sparkles"];
return /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "flex items-center gap-1.5 rounded-md px-2 py-1 border",
style: {
borderColor: `${u.color}50`,
background: `${u.color}15`
},
children: [
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(Icon, {
className: "h-3 w-3",
style: {
color: u.color
}
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1993,
columnNumber: 25
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
className: "text-[11px] text-white/85",
children: u.title
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1994,
columnNumber: 25
}, this)
]
}, i, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1988,
columnNumber: 23
}, this);
})
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1984,
columnNumber: 17
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1982,
columnNumber: 15
}, this),
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
className: "text-center mt-4",
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
variant: "ghost",
onClick: handleExit,
className: "border border-white/10 text-white/60 hover:bg-white/10 h-9",
children: "退出巡航"
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 2002,
columnNumber: 15
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 2001,
columnNumber: 13
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1915,
columnNumber: 11
}, this)
}, void 0, false, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1914,
columnNumber: 9
}, this)
]
}, void 0, true, {
fileName: "[project]/src/components/game/CruiseMode.tsx",
lineNumber: 1408,
columnNumber: 5
}, this);
}
_s(CruiseMode, "dRh+2G1Wc+HWMpPPcXFQlMrG/TA=");
_c = CruiseMode;
;
var _c;
__turbopack_context__.k.register(_c, "CruiseMode");
if (typeof globalThis.$RefreshHelpers$ === 'object' && globalThis.$RefreshHelpers !== null) {
__turbopack_context__.k.registerExports(__turbopack_context__.m, globalThis.$RefreshHelpers$);
}
}),
"[project]/src/components/game/CruiseMode.tsx [app-client] (ecmascript)", ((__turbopack_context__) => {
"use strict";
__turbopack_context__.s([
"CruiseMode",
()=>__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$game$2f$CruiseMode$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__["CruiseMode"],
"UPGRADE_POOL",
()=>__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__["UPGRADE_POOL"]
]);
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$game$2f$CruiseMode$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$locals$3e$__ = __turbopack_context__.i("[project]/src/components/game/CruiseMode.tsx [app-client] (ecmascript) <locals>");
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$game$2f$cruise$2e$ts__$5b$app$2d$client$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/game/cruise.ts [app-client] (ecmascript)");
}),
"[project]/src/components/game/CruiseMode.tsx [app-client] (ecmascript, next/dynamic entry)", ((__turbopack_context__) => {
__turbopack_context__.n(__turbopack_context__.i("[project]/src/components/game/CruiseMode.tsx [app-client] (ecmascript)"));
}),
]);
//# sourceMappingURL=src_fe091346._.js.map