From d7253c45be3b5b0b599f34ddcaaa4d85625fdfc9 Mon Sep 17 00:00:00 2001 From: Cloud Bot Date: Tue, 24 Mar 2026 08:22:21 +0000 Subject: [PATCH] =?UTF-8?q?feat(game):=20PUA=E6=BF=80=E5=8A=B1=E5=8F=B0?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0HC=E6=B6=88=E8=80=97=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=EF=BC=8C=E8=B4=B9=E7=94=A8=3D=E5=BD=93=E5=89=8DHC=C3=9715%?= =?UTF-8?q?=EF=BC=8C=E4=BD=99=E9=A2=9D=E4=B8=8D=E8=B6=B3=E6=97=B6=E7=A6=81?= =?UTF-8?q?=E7=94=A8=EF=BC=8C=E9=98=B2=E6=AD=A2=E6=97=A0=E9=99=90=E6=BF=80?= =?UTF-8?q?=E5=8A=B1=E7=A0=B4=E5=9D=8F=E5=B9=B3=E8=A1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/game/page.tsx | 157 ++++++++++++++++++++++++++++++++++++++-------- game/GameScene.ts | 8 ++- 2 files changed, 137 insertions(+), 28 deletions(-) diff --git a/app/game/page.tsx b/app/game/page.tsx index 941d6e5..808568b 100644 --- a/app/game/page.tsx +++ b/app/game/page.tsx @@ -21,6 +21,7 @@ interface PuaResult { title: string desc: string effect: EffectType + cost?: number // 实际扣除的 HC(前端填写) } const EFFECT_META: Record = { @@ -39,26 +40,57 @@ const PUA_PLACEHOLDERS = [ '大家加油,相信自己!', ] +// ── 费用计算:基于当前HC的15%,最低20,最高200,取整到10的倍数 ──────────── +function calcPuaCost(hc: number): number { + const raw = Math.ceil(hc * 0.15) + const rounded = Math.ceil(raw / 10) * 10 // 向上取到整十 + return Math.max(20, Math.min(200, rounded)) +} + // ── PUA 输入面板 ───────────────────────────────────────────────────────────── -function PuaPanel({ gameReady }: { gameReady: boolean }) { +function PuaPanel({ gameReady, hc }: { gameReady: boolean; hc: number }) { const [text, setText] = useState('') const [loading, setLoading] = useState(false) const [result, setResult] = useState(null) const [history, setHistory] = useState([]) + const [insufficient, setInsufficient] = useState(false) const textareaRef = useRef(null) - const placeholder = PUA_PLACEHOLDERS[Math.floor(Math.random() * PUA_PLACEHOLDERS.length)] + const placeholder = useRef(PUA_PLACEHOLDERS[Math.floor(Math.random() * PUA_PLACEHOLDERS.length)]).current + + const cost = calcPuaCost(hc) + const canAfford = hc >= cost const handleSubmit = useCallback(async () => { if (!text.trim() || loading || !gameReady) return + + // 先从游戏扣除 HC(扣不到则拒绝) + const spendHC: ((n: number) => boolean) | undefined = + typeof window !== 'undefined' ? (window as any).__gameSpendHC : undefined + + const currentHC: number = + typeof window !== 'undefined' + ? ((window as any).__gameGetHC?.() ?? hc) + : hc + + const actualCost = calcPuaCost(currentHC) + + if (!spendHC?.(actualCost)) { + setInsufficient(true) + setTimeout(() => setInsufficient(false), 2000) + return + } + setLoading(true) setResult(null) + setInsufficient(false) try { const res = await fetch('/api/pua-score', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: text.trim() }), }) - const data: PuaResult = await res.json() + const data: PuaResult & { cost?: number } = await res.json() + data.cost = actualCost setResult(data) setHistory(prev => [data, ...prev].slice(0, 5)) // 通知游戏场景应用 buff @@ -70,7 +102,7 @@ function PuaPanel({ gameReady }: { gameReady: boolean }) { } finally { setLoading(false) } - }, [text, loading, gameReady]) + }, [text, loading, gameReady, hc]) const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { @@ -115,6 +147,62 @@ function PuaPanel({ gameReady }: { gameReady: boolean }) { + {/* 费用提示 */} +
+ + 激励费用 + +
+ + -{cost} HC + + {!canAfford && ( + + 余额不足 + + )} +
+
+ + {/* HC 不足闪烁提示 */} + {insufficient && ( +
+ HC 不足!先去打怪赚钱! +
+ )} + {/* 输入框 */}